feature:基本框架
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
"""每请求 trace_id:contextvar 存链路号,中间件生成 / 透传并回写响应头。"""
|
||||
import contextvars
|
||||
import uuid
|
||||
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
from starlette.requests import Request
|
||||
from starlette.responses import Response
|
||||
|
||||
_request_id: contextvars.ContextVar[str | None] = contextvars.ContextVar("request_id", default=None)
|
||||
|
||||
|
||||
def get_request_id() -> str | None:
|
||||
"""获取当前请求的 trace_id(请求上下文外返回 None)。"""
|
||||
return _request_id.get()
|
||||
|
||||
|
||||
def new_request_id() -> str:
|
||||
return uuid.uuid4().hex[:16]
|
||||
|
||||
|
||||
class RequestIdMiddleware(BaseHTTPMiddleware):
|
||||
"""透传客户端 X-Trace-Id(无则生成),供日志/响应头/审计链路关联。"""
|
||||
|
||||
async def dispatch(self, request: Request, call_next):
|
||||
rid = request.headers.get("X-Trace-Id") or new_request_id()
|
||||
token = _request_id.set(rid)
|
||||
try:
|
||||
response: Response = await call_next(request)
|
||||
response.headers["X-Trace-Id"] = rid
|
||||
return response
|
||||
finally:
|
||||
_request_id.reset(token)
|
||||
Reference in New Issue
Block a user