"""JSON structured logging on stdout.""" from __future__ import annotations import logging import sys from pythonjsonlogger import jsonlogger def configure_logging(level: str = "INFO") -> None: """Replace the root handler with a single JSON stdout handler. Fields emitted: ts, level, name, msg, plus any extras passed via `logger.X(..., extra={...})`. """ root = logging.getLogger() root.setLevel(level.upper()) # Drop any pre-existing handlers (uvicorn/gunicorn add their own). for h in list(root.handlers): root.removeHandler(h) handler = logging.StreamHandler(sys.stdout) formatter = jsonlogger.JsonFormatter( fmt="%(asctime)s %(levelname)s %(name)s %(message)s", rename_fields={"asctime": "ts", "levelname": "level", "name": "logger"}, json_ensure_ascii=False, ) handler.setFormatter(formatter) root.addHandler(handler) # Tame the noisy third parties unless explicitly debugging. if level.upper() != "DEBUG": logging.getLogger("werkzeug").setLevel(logging.WARNING)