Skip to main content
Glama

MCP Log Analyzer

by sedwardstx
main.py4.94 kB
#!/usr/bin/env python3 """ Main entry point for the MCP Log Analyzer server with graceful shutdown support. """ import asyncio import atexit import signal import sys import logging from pathlib import Path # Add src to Python path sys.path.insert(0, str(Path(__file__).parent / "src")) from mcp_log_analyzer.mcp_server.server import mcp, log_sources, get_log_sources logger = logging.getLogger(__name__) # Track if cleanup has been performed _cleanup_done = False def cleanup_resources(): """Clean up all resources on shutdown.""" global _cleanup_done # Avoid duplicate cleanup if _cleanup_done: return _cleanup_done = True logger.info("Cleaning up resources on shutdown...") # Clean up ETL caches for all ETL sources etl_sources = [source for source in get_log_sources().values() if source.type == "etl"] if etl_sources: try: from mcp_log_analyzer.parsers.etl_cached_parser import EtlCachedParser logger.info(f"Cleaning up ETL caches for {len(etl_sources)} source(s)") for source in etl_sources: logger.info(f"Cleaning up ETL cache for: {source.name} ({source.path})") EtlCachedParser.cleanup_cache_for_source(source.path) except Exception as e: logger.error(f"Error cleaning up ETL caches: {e}") # Clean up all cached ETL files (including orphaned ones) try: from mcp_log_analyzer.parsers.etl_cached_parser import EtlCachedParser logger.info("Cleaning up any remaining ETL cache files...") EtlCachedParser.cleanup_all_cache() except Exception as e: logger.error(f"Error cleaning up all ETL caches: {e}") # Don't clear log sources - they should persist across restarts # log_sources.clear() logger.info(f"Keeping {len(get_log_sources())} log sources for next startup") def signal_handler(signum, frame): """Handle shutdown signals.""" logger.info(f"Received signal {signum}, initiating graceful shutdown...") cleanup_resources() sys.exit(0) async def async_signal_handler(): """Async signal handler for asyncio.""" cleanup_resources() def setup_signal_handlers(): """Set up signal handlers for graceful shutdown.""" # Handle CTRL+C (SIGINT) and termination signals signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) # For Windows, also handle CTRL+BREAK if sys.platform == "win32": signal.signal(signal.SIGBREAK, signal_handler) # Set up asyncio signal handlers if running in event loop try: loop = asyncio.get_running_loop() for sig in (signal.SIGINT, signal.SIGTERM): loop.add_signal_handler(sig, lambda: asyncio.create_task(async_signal_handler())) except RuntimeError: # No event loop running yet pass def main(): """Run the MCP server with cleanup support.""" # Set up logging with DEBUG level to see more details logging.basicConfig( level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) # Register cleanup function with atexit atexit.register(cleanup_resources) # Set up signal handlers setup_signal_handlers() try: logger.info("Starting MCP Log Analyzer server...") # Add a handler to catch any unhandled exceptions import sys def handle_exception(exc_type, exc_value, exc_traceback): if issubclass(exc_type, KeyboardInterrupt): sys.__excepthook__(exc_type, exc_value, exc_traceback) return logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)) sys.excepthook = handle_exception mcp.run() logger.info("MCP server run() method returned - server shutting down") except KeyboardInterrupt: logger.info("Server interrupted by user") cleanup_resources() except Exception as e: logger.error(f"Server error: {e}") logger.error(f"Error type: {type(e).__name__}") logger.error(f"Error args: {e.args}") import traceback logger.error(f"Traceback: {traceback.format_exc()}") cleanup_resources() raise finally: # Final cleanup if not already done logger.info("In finally block - checking if cleanup needed") try: # Check if any log sources are loaded (use try/except in case lazy loading hasn't happened) sources = get_log_sources() if sources: logger.info(f"Found {len(sources)} log sources, cleaning up") cleanup_resources() except: # If there's any error checking, skip cleanup pass logger.info("MCP server process ending") if __name__ == "__main__": main()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sedwardstx/demomcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server