""" logger.py — Structured logging using structlog. Outputs pretty console logs in development, JSON in production. """ import logging import sys import structlog from src.config import settings def configure_logging() -> None: """Configure structlog based on app environment.""" shared_processors = [ structlog.contextvars.merge_contextvars, structlog.stdlib.add_logger_name, structlog.stdlib.add_log_level, structlog.processors.TimeStamper(fmt="iso"), structlog.processors.StackInfoRenderer(), ] if settings.log_format == "json" or settings.is_production: renderer = structlog.processors.JSONRenderer() else: renderer = structlog.dev.ConsoleRenderer(colors=True) # type: ignore[assignment] structlog.configure( processors=[ *shared_processors, structlog.stdlib.ProcessorFormatter.wrap_for_formatter, ], wrapper_class=structlog.stdlib.BoundLogger, context_class=dict, logger_factory=structlog.stdlib.LoggerFactory(), cache_logger_on_first_use=True, ) formatter = structlog.stdlib.ProcessorFormatter( processor=renderer, foreign_pre_chain=shared_processors, ) handler = logging.StreamHandler(sys.stdout) handler.setFormatter(formatter) root_logger = logging.getLogger() root_logger.handlers = [handler] root_logger.setLevel(settings.log_level) def get_logger(name: str) -> structlog.stdlib.BoundLogger: configure_logging() return structlog.get_logger(name)