S-Dreamer/CodeCraftLab
0
1"""2Structured logging setup via structlog.3 4Production: JSON output, machine-parseable.5Development: colourised console output.6 7Call configure_logging() once at application startup before any loggers are created.8"""9 10from __future__ import annotations11 12import logging13import sys14 15import structlog16 17 18def configure_logging(log_level: str = "INFO", env: str = "development") -> None:19 """Configure structlog with environment-appropriate rendering."""20 21 shared_processors: list[structlog.types.Processor] = [22 structlog.contextvars.merge_contextvars,23 structlog.stdlib.add_log_level,24 structlog.stdlib.add_logger_name,25 structlog.processors.TimeStamper(fmt="iso"),26 structlog.processors.StackInfoRenderer(),27 ]28 29 if env == "production":30 processors: list[structlog.types.Processor] = [31 *shared_processors,32 structlog.processors.dict_tracebacks,33 structlog.processors.JSONRenderer(),34 ]35 renderer = structlog.processors.JSONRenderer()36 else:37 processors = [38 *shared_processors,39 structlog.dev.ConsoleRenderer(colors=True),40 ]41 renderer = structlog.dev.ConsoleRenderer(colors=True)42 43 structlog.configure(44 processors=processors,45 wrapper_class=structlog.make_filtering_bound_logger(46 getattr(logging, log_level.upper(), logging.INFO)47 ),48 context_class=dict,49 logger_factory=structlog.PrintLoggerFactory(sys.stdout),50 cache_logger_on_first_use=True,51 )52 53 # Silence noisy third-party loggers54 for noisy in ("uvicorn.access", "httpx", "transformers", "datasets"):55 logging.getLogger(noisy).setLevel(logging.WARNING)56 