Skip to main content
Glama
logger.py3.54 kB
""" Structured logging utility for MCP Maximo Server Provides correlation ID tracking and JSON formatting """ import logging import sys import uuid from contextvars import ContextVar from typing import Any, Optional import structlog from structlog.types import EventDict, Processor from src.config import settings # Context variable for correlation ID correlation_id_var: ContextVar[Optional[str]] = ContextVar("correlation_id", default=None) def add_correlation_id(logger: Any, method_name: str, event_dict: EventDict) -> EventDict: """Add correlation ID to log entries""" correlation_id = correlation_id_var.get() if correlation_id: event_dict["correlation_id"] = correlation_id return event_dict def add_app_context(logger: Any, method_name: str, event_dict: EventDict) -> EventDict: """Add application context to log entries""" event_dict["app"] = settings.app_name event_dict["version"] = settings.app_version event_dict["environment"] = settings.environment return event_dict def configure_logging() -> None: """Configure structured logging for the application""" # Determine log level log_level = getattr(logging, settings.log_level.upper(), logging.INFO) # Configure stdlib logging logging.basicConfig( format="%(message)s", stream=sys.stdout, level=log_level, ) # Processors for structlog processors: list[Processor] = [ structlog.contextvars.merge_contextvars, add_correlation_id, add_app_context, structlog.stdlib.add_logger_name, structlog.stdlib.add_log_level, structlog.stdlib.PositionalArgumentsFormatter(), structlog.processors.TimeStamper(fmt="iso"), structlog.processors.StackInfoRenderer(), structlog.processors.format_exc_info, ] # Add appropriate renderer based on format if settings.log_format == "json": processors.append(structlog.processors.JSONRenderer()) else: processors.append(structlog.dev.ConsoleRenderer()) # Configure structlog structlog.configure( processors=processors, wrapper_class=structlog.stdlib.BoundLogger, context_class=dict, logger_factory=structlog.stdlib.LoggerFactory(), cache_logger_on_first_use=True, ) def get_logger(name: str) -> structlog.stdlib.BoundLogger: """Get a logger instance with the given name""" return structlog.get_logger(name) def generate_correlation_id() -> str: """Generate a new correlation ID""" return str(uuid.uuid4()) def set_correlation_id(correlation_id: Optional[str] = None) -> str: """Set correlation ID for current context""" if correlation_id is None: correlation_id = generate_correlation_id() correlation_id_var.set(correlation_id) return correlation_id def get_correlation_id() -> Optional[str]: """Get current correlation ID""" return correlation_id_var.get() def clear_correlation_id() -> None: """Clear correlation ID from current context""" correlation_id_var.set(None) # Configure logging on module import configure_logging() # Convenience function for getting module-specific loggers def get_module_logger() -> structlog.stdlib.BoundLogger: """Get logger for the calling module""" import inspect frame = inspect.currentframe() if frame and frame.f_back: module_name = frame.f_back.f_globals.get("__name__", "unknown") return get_logger(module_name) return get_logger("unknown")

Latest Blog Posts

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/nick0918964388/mcp-maximo-server'

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