"""Request ID 中间件:为每个请求生成并传播唯一标识符。""" import uuid import logging from starlette.middleware.base import BaseHTTPMiddleware from starlette.requests import Request from starlette.responses import Response logger = logging.getLogger("geo.request_id") REQUEST_ID_HEADER = "X-Request-ID" class RequestIdMiddleware(BaseHTTPMiddleware): """从请求头读取或自动生成 X-Request-ID,注入 request.state 并写回响应头。 使用场景: - 链路追踪:日志中携带 request_id 方便跨服务排查 - 客户端可主动传入 X-Request-ID,实现端到端追踪 """ async def dispatch(self, request: Request, call_next) -> Response: request_id = request.headers.get(REQUEST_ID_HEADER) or str(uuid.uuid4()) # 注入到 request.state,业务代码可通过 request.state.request_id 读取 request.state.request_id = request_id response = await call_next(request) response.headers[REQUEST_ID_HEADER] = request_id return response