You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.7 KiB
84 lines
2.7 KiB
"""
|
|
请求中间件
|
|
"""
|
|
import time
|
|
import uuid
|
|
from typing import Callable
|
|
from fastapi import Request, Response
|
|
from starlette.middleware.base import BaseHTTPMiddleware
|
|
from starlette.types import ASGIApp
|
|
|
|
from app.utils.log import get_enhanced_logger, LogLevel
|
|
|
|
logger = get_enhanced_logger(__name__, LogLevel.DEBUG)
|
|
|
|
|
|
class RequestMiddleware(BaseHTTPMiddleware):
|
|
"""请求中间件 - 生成请求ID和记录请求日志"""
|
|
|
|
def __init__(self, app: ASGIApp):
|
|
super().__init__(app)
|
|
|
|
async def dispatch(self, request: Request, call_next: Callable) -> Response:
|
|
# 生成请求ID
|
|
request_id = str(uuid.uuid4())
|
|
request.state.request_id = request_id
|
|
|
|
# 记录请求开始
|
|
start_time = time.time()
|
|
|
|
logger.info("请求开始",
|
|
request_id=request_id,
|
|
method=request.method,
|
|
url=str(request.url),
|
|
client_ip=request.client.host if request.client else "unknown",
|
|
user_agent=request.headers.get("user-agent", "unknown"))
|
|
|
|
try:
|
|
# 处理请求
|
|
response = await call_next(request)
|
|
|
|
# 计算处理时间
|
|
process_time = time.time() - start_time
|
|
|
|
# 记录请求完成
|
|
logger.info("请求完成",
|
|
request_id=request_id,
|
|
method=request.method,
|
|
url=str(request.url),
|
|
status_code=response.status_code,
|
|
process_time_ms=round(process_time * 1000, 2))
|
|
|
|
# 添加请求ID到响应头
|
|
response.headers["X-Request-ID"] = request_id
|
|
response.headers["X-Process-Time"] = str(round(process_time * 1000, 2))
|
|
|
|
return response
|
|
|
|
except Exception as e:
|
|
# 计算处理时间
|
|
process_time = time.time() - start_time
|
|
|
|
# 记录请求异常
|
|
logger.error("请求异常",
|
|
request_id=request_id,
|
|
method=request.method,
|
|
url=str(request.url),
|
|
exception=str(e),
|
|
process_time_ms=round(process_time * 1000, 2))
|
|
|
|
# 重新抛出异常,让异常处理器处理
|
|
raise
|
|
|
|
|
|
def add_middleware(app: ASGIApp) -> None:
|
|
"""添加中间件到应用"""
|
|
try:
|
|
# 添加请求中间件
|
|
app.add_middleware(RequestMiddleware)
|
|
|
|
logger.info("中间件添加成功")
|
|
|
|
except Exception as e:
|
|
logger.error("添加中间件失败", error=str(e))
|
|
raise
|