"""Structured logging configuration with safe JSON output.""" from __future__ import annotations import json import logging from datetime import UTC, datetime from typing import Any class JsonFormatter(logging.Formatter): """Serialize standard records and selected structured attributes as JSON.""" _fields = ("request_id", "method", "path", "status", "duration_ms") def format(self, record: logging.LogRecord) -> str: payload: dict[str, Any] = { "timestamp": datetime.now(UTC).isoformat(), "level": record.levelname, "logger": record.name, "message": record.getMessage(), } for field in self._fields: value = getattr(record, field, None) if value is not None: payload[field] = value if record.exc_info is not None: payload["exception"] = self.formatException(record.exc_info) return json.dumps(payload, ensure_ascii=False, separators=(",", ":")) def configure_logging(level: str) -> None: """Configure the root logger once for the process.""" handler = logging.StreamHandler() handler.setFormatter(JsonFormatter()) root = logging.getLogger() root.handlers.clear() root.addHandler(handler) root.setLevel(level.upper())