"""Journalisation structurée du pipeline. Sortie lisible en console pour les exécutions manuelles, JSON lorsque la sortie n'est pas un terminal (systemd, redirections) afin que `journalctl` reste exploitable. """ from __future__ import annotations import logging import sys import structlog def configurer(niveau: str = "INFO") -> None: """Configure structlog une fois pour toute l'exécution.""" logging.basicConfig(format="%(message)s", stream=sys.stdout, level=niveau) processeurs: list = [ structlog.contextvars.merge_contextvars, structlog.processors.add_log_level, structlog.processors.TimeStamper(fmt="%Y-%m-%d %H:%M:%S", utc=False), ] if sys.stdout.isatty(): processeurs.append(structlog.dev.ConsoleRenderer(colors=True)) else: processeurs.append(structlog.processors.JSONRenderer(ensure_ascii=False)) structlog.configure( processors=processeurs, wrapper_class=structlog.make_filtering_bound_logger(getattr(logging, niveau)), logger_factory=structlog.PrintLoggerFactory(), cache_logger_on_first_use=True, ) def logger(nom: str) -> structlog.stdlib.BoundLogger: return structlog.get_logger(nom)