import logging import json import sys from contextvars import ContextVar from datetime import datetime, timezone request_id_var: ContextVar[str] = ContextVar("request_id", default="-") class JSONFormatter(logging.Formatter): def format(self, record: logging.LogRecord) -> str: log_data = { "timestamp": datetime.now(timezone.utc).isoformat(), "level": record.levelname, "module": record.module, "function": record.funcName, "line": record.lineno, "message": record.getMessage(), "request_id": request_id_var.get("-"), } if record.exc_info and record.exc_info[0] is not None: log_data["exception"] = self.formatException(record.exc_info) if hasattr(record, "extra_data"): log_data["extra"] = record.extra_data return json.dumps(log_data, ensure_ascii=False) def get_logger(name: str) -> logging.Logger: from core.config import settings logger = logging.getLogger(name) if not logger.handlers: handler = logging.StreamHandler(sys.stdout) handler.setFormatter(JSONFormatter()) logger.addHandler(handler) logger.setLevel(getattr(logging, settings.log_level, logging.INFO)) logger.propagate = False return logger