| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- from __future__ import annotations
- """统一日志配置与trace_id上下文管理:通过contextvars实现一次工作流调用的trace_id贯穿所有日志。"""
- import logging
- import sys
- import uuid
- from contextvars import ContextVar
- _trace_id_context: ContextVar[str] = ContextVar(
- "trace_id",
- default="-",
- )
- class TraceIdFilter(logging.Filter):
- """向每条日志中注入当前请求trace_id。"""
- def filter(
- self,
- record: logging.LogRecord,
- ) -> bool:
- """向日志记录注入当前上下文的trace_id,供日志格式串引用。"""
- record.trace_id = get_trace_id()
- return True
- def configure_logging(
- level: int = logging.INFO,
- ) -> None:
- """配置TravelMind统一日志格式。"""
- handler = logging.StreamHandler(
- sys.stdout
- )
- handler.addFilter(TraceIdFilter())
- formatter = logging.Formatter(
- fmt=(
- "%(asctime)s "
- "| %(levelname)s "
- "| trace_id=%(trace_id)s "
- "| %(name)s "
- "| %(message)s"
- ),
- datefmt="%Y-%m-%d %H:%M:%S",
- )
- handler.setFormatter(formatter)
- root_logger = logging.getLogger()
- root_logger.handlers.clear()
- root_logger.addHandler(handler)
- root_logger.setLevel(level)
- # 降低第三方HTTP库的日志噪声。
- logging.getLogger(
- "httpcore"
- ).setLevel(logging.WARNING)
- logging.getLogger(
- "httpx"
- ).setLevel(logging.WARNING)
- def new_trace_id() -> str:
- """生成并设置一次工作流调用的trace_id。"""
- trace_id = uuid.uuid4().hex[:16]
- _trace_id_context.set(trace_id)
- return trace_id
- def set_trace_id(
- trace_id: str,
- ) -> None:
- """设置外部传入的trace_id。"""
- normalized = trace_id.strip()
- _trace_id_context.set(
- normalized or "-"
- )
- def get_trace_id() -> str:
- """读取当前上下文trace_id。"""
- return _trace_id_context.get()
|