"""Configuration des logs backend : lisible, structure, sans donnee sensible.""" from __future__ import annotations import logging import sys _LOG_FORMAT = "%(asctime)s | %(levelname)-8s | %(name)s | %(message)s" _DATE_FORMAT = "%Y-%m-%dT%H:%M:%S" # Champs qui ne doivent jamais apparaitre dans les logs. REDACTED_KEYS = frozenset({"management_token", "managementToken", "authorization"}) def configure_logging(level: str = "INFO") -> None: handler = logging.StreamHandler(sys.stdout) handler.setFormatter(logging.Formatter(_LOG_FORMAT, datefmt=_DATE_FORMAT)) root = logging.getLogger() root.handlers.clear() root.addHandler(handler) root.setLevel(level.upper()) # Uvicorn possede ses propres handlers : on les aligne sur les notres. for name in ("uvicorn", "uvicorn.error", "uvicorn.access"): logger = logging.getLogger(name) logger.handlers.clear() logger.propagate = True def safe_extra(data: dict[str, object]) -> dict[str, object]: """Retire les valeurs sensibles avant de les envoyer dans un log.""" return {k: ("***" if k in REDACTED_KEYS else v) for k, v in data.items()}