Skip to main content
Glama
logger.py3.34 kB
""" Structured logging configuration using structlog. Provides JSON-formatted logging with context processors for request tracking, timestamps, and log levels. Story: MVP-005 (FastMCP Server Foundation) """ import logging import os import sys from typing import Any import structlog def setup_logging(level: str = "INFO") -> None: """ Configure structured logging with structlog. Args: level: Log level string (DEBUG, INFO, WARNING, ERROR, CRITICAL) Sets up: - JSON output format for production - Console output with colors for development - Context processors for timestamps and metadata - Integration with standard library logging """ log_level = getattr(logging, level.upper(), logging.INFO) # Configure standard library logging logging.basicConfig( format="%(message)s", stream=sys.stdout, level=log_level, ) # Determine if we're in development mode is_dev = os.getenv("ENVIRONMENT", "production") == "development" # Configure structlog processors processors = [ structlog.contextvars.merge_contextvars, structlog.processors.add_log_level, structlog.processors.StackInfoRenderer(), structlog.dev.set_exc_info, structlog.processors.TimeStamper(fmt="iso", utc=True), ] if is_dev: # Development: Human-readable console output with colors processors.append(structlog.dev.ConsoleRenderer()) else: # Production: JSON output processors.append(structlog.processors.JSONRenderer()) structlog.configure( processors=processors, wrapper_class=structlog.make_filtering_bound_logger(log_level), context_class=dict, logger_factory=structlog.PrintLoggerFactory(), cache_logger_on_first_use=True, ) def get_logger(name: str = __name__) -> structlog.BoundLogger: """ Get a structured logger instance. Args: name: Logger name (typically __name__ of calling module) Returns: Configured structlog logger instance Example: >>> logger = get_logger(__name__) >>> logger.info("tool_request", tool="search_reddit", params={"query": "test"}) """ return structlog.get_logger(name) def log_tool_execution( tool_name: str, duration_ms: float, cached: bool, error: str | None = None, **extra: Any, ) -> None: """ Log tool execution metrics in structured format. Args: tool_name: Name of the MCP tool executed duration_ms: Execution time in milliseconds cached: Whether result was served from cache error: Error message if execution failed **extra: Additional context to log Example: >>> log_tool_execution( ... tool_name="search_reddit", ... duration_ms=1234.5, ... cached=False, ... result_count=25 ... ) """ logger = get_logger("tool_execution") log_data = { "event": "tool_execution", "tool": tool_name, "duration_ms": round(duration_ms, 2), "cached": cached, "error": error, **extra, } if error: logger.error("tool_execution_failed", **log_data) else: logger.info("tool_execution_success", **log_data)

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/padak/apify-actor-reddit-mcp'

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