WechatOnCloud/bridge/woc_bridge/ui/trace.py

54 lines
1.3 KiB
Python
Raw Normal View History

"""TraceID 贯穿ContextVar + 12-hex 生成 + logging.Filter。
每个 HTTP 请求生成唯一 trace_id注入 ContextVar日志通过 TraceFilter
自动带上 trace_id 字段便于全链路追踪
"""
from __future__ import annotations
import logging
import random
import contextvars
# 单请求内贯穿的 trace_id
trace_id_var: contextvars.ContextVar[str] = contextvars.ContextVar(
"trace_id", default=""
)
def new_trace_id() -> str:
"""生成 12 字符 hex trace_id。
Returns:
12 字符 hex 字符串 "a3b5c7d9e1f2"
"""
return f"{random.getrandbits(48):012x}"
def get_trace_id() -> str:
"""获取当前 ContextVar 中的 trace_id。"""
return trace_id_var.get()
def set_trace_id(trace_id: str) -> contextvars.Token:
"""设置 trace_id返回 Token 供 reset 使用。"""
return trace_id_var.set(trace_id)
def reset_trace_id(token: contextvars.Token) -> None:
"""重置 trace_id 到之前的状态。"""
trace_id_var.reset(token)
class TraceFilter(logging.Filter):
"""日志 Filter在每条日志的 extra 中注入 trace_id。
用法
logger.addFilter(TraceFilter())
日志格式中可用 %(trace_id)s 引用
"""
def filter(self, record: logging.LogRecord) -> bool:
record.trace_id = trace_id_var.get()
return True