CodeCraftLab / app_logging.py
S-Dreamer's picture
Rename structured_logging.py to app_logging.py
6628921 verified
"""
Structured logging setup via structlog.
Production: JSON output, machine-parseable.
Development: colourised console output.
Call configure_logging() once at application startup before any loggers are created.
"""
from __future__ import annotations
import logging
import sys
import structlog
def configure_logging(log_level: str = "INFO", env: str = "development") -> None:
"""Configure structlog with environment-appropriate rendering."""
shared_processors: list[structlog.types.Processor] = [
structlog.contextvars.merge_contextvars,
structlog.stdlib.add_log_level,
structlog.stdlib.add_logger_name,
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.StackInfoRenderer(),
]
if env == "production":
processors: list[structlog.types.Processor] = [
*shared_processors,
structlog.processors.dict_tracebacks,
structlog.processors.JSONRenderer(),
]
renderer = structlog.processors.JSONRenderer()
else:
processors = [
*shared_processors,
structlog.dev.ConsoleRenderer(colors=True),
]
renderer = structlog.dev.ConsoleRenderer(colors=True)
structlog.configure(
processors=processors,
wrapper_class=structlog.make_filtering_bound_logger(
getattr(logging, log_level.upper(), logging.INFO)
),
context_class=dict,
logger_factory=structlog.PrintLoggerFactory(sys.stdout),
cache_logger_on_first_use=True,
)
# Silence noisy third-party loggers
for noisy in ("uvicorn.access", "httpx", "transformers", "datasets"):
logging.getLogger(noisy).setLevel(logging.WARNING)