Files
wecom-ai-assistant/backend/app/logging_config.py
2026-02-05 16:36:32 +08:00

50 lines
1.5 KiB
Python

"""结构化 JSON 日志 + trace_id。"""
import logging
import sys
import uuid
from contextvars import ContextVar
from pythonjsonlogger import jsonlogger
trace_id_var: ContextVar[str] = ContextVar("trace_id", default="")
def get_trace_id() -> str:
t = trace_id_var.get()
if not t:
t = str(uuid.uuid4())
trace_id_var.set(t)
return t
def set_trace_id(tid: str) -> None:
trace_id_var.set(tid)
class TraceIdFilter(logging.Filter):
def filter(self, record: logging.LogRecord) -> bool:
record.trace_id = get_trace_id()
return True
class JsonFormatter(jsonlogger.JsonFormatter):
def add_fields(self, log_record: dict, record: logging.LogRecord, message_dict: dict) -> None:
super().add_fields(log_record, record, message_dict)
log_record["trace_id"] = getattr(record, "trace_id", "")
log_record["level"] = record.levelname
if record.exc_info:
log_record["exception"] = self.formatException(record.exc_info)
def setup_logging(log_level: str = "INFO", log_json: bool = True) -> None:
root = logging.getLogger()
root.handlers.clear()
handler = logging.StreamHandler(sys.stdout)
if log_json:
handler.setFormatter(JsonFormatter("%(timestamp)s %(level)s %(message)s %(trace_id)s"))
else:
handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s [%(trace_id)s] %(message)s"))
handler.addFilter(TraceIdFilter())
root.addHandler(handler)
root.setLevel(getattr(logging, log_level.upper(), logging.INFO))