|
|
@@ -8,6 +8,7 @@
|
|
|
纯 ASGI 中间件通过包装 receive/send 通道缓存请求体与响应状态,既记录日志又不破坏下游请求。
|
|
|
"""
|
|
|
import time
|
|
|
+import uuid
|
|
|
from collections import deque
|
|
|
import logging
|
|
|
|
|
|
@@ -63,6 +64,17 @@ class RequestLogMiddleware:
|
|
|
client = scope.get("client")
|
|
|
client_ip = client[0] if client else "-"
|
|
|
|
|
|
+ # 读取或生成 X-Request-ID(Java AiGateway 在每次调用时都会注入 UUID)
|
|
|
+ request_id = None
|
|
|
+ for name, value in scope.get("headers", []):
|
|
|
+ if name == b"x-request-id":
|
|
|
+ request_id = value.decode()
|
|
|
+ break
|
|
|
+ request_id = request_id or str(uuid.uuid4())
|
|
|
+
|
|
|
+ # 带 trace_id 的 adapter:JsonFormatter 会把它写为顶层字段
|
|
|
+ req_logger = logging.LoggerAdapter(logger, {"trace_id": request_id})
|
|
|
+
|
|
|
# 缓存请求体(仅对带 body 的方法),不影响下游 receive
|
|
|
body_bytes = b""
|
|
|
body_cached = False
|
|
|
@@ -98,8 +110,8 @@ class RequestLogMiddleware:
|
|
|
try:
|
|
|
await self.app(scope, receive_wrapper, send_wrapper)
|
|
|
except Exception as exc:
|
|
|
- logger.error("REQUEST EXCEPTION: %s %s %.2fs error=%r",
|
|
|
- method, path, time.perf_counter() - start_time, exc)
|
|
|
+ req_logger.error("REQUEST EXCEPTION: %s %s %.2fs error=%r",
|
|
|
+ method, path, time.perf_counter() - start_time, exc)
|
|
|
if not sent_response_start:
|
|
|
from starlette.responses import JSONResponse
|
|
|
resp = JSONResponse(status_code=500, content={"detail": str(exc)})
|
|
|
@@ -116,12 +128,13 @@ class RequestLogMiddleware:
|
|
|
"status": final_status,
|
|
|
"duration_ms": round(elapsed * 1000),
|
|
|
"client_ip": client_ip,
|
|
|
+ "trace_id": request_id,
|
|
|
"body": _decode_body(body_bytes) if body_cached else None,
|
|
|
"response": _decode_body(b"".join(response_chunks)[:1000]) if response_chunks else "",
|
|
|
}
|
|
|
_request_log.appendleft(entry)
|
|
|
|
|
|
if elapsed > 5:
|
|
|
- logger.warning("SLOW_REQUEST: %s %s %.2fs", method, path, elapsed)
|
|
|
+ req_logger.warning("SLOW_REQUEST: %s %s %.2fs", method, path, elapsed)
|
|
|
else:
|
|
|
- logger.debug("REQUEST: %s %s %.2fs", method, path, elapsed)
|
|
|
+ req_logger.debug("REQUEST: %s %s %.2fs", method, path, elapsed)
|