| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- """
- API日志中间件
- """
- import time
- from fastapi import Request
- from starlette.middleware.base import BaseHTTPMiddleware
- from sqlalchemy.orm import Session
- from app.database import SessionLocal
- from app.models.api_log import APILog
- from app.core.logger import logger
- from datetime import datetime
- class APILoggingMiddleware(BaseHTTPMiddleware):
- """API日志中间件"""
-
- async def dispatch(self, request: Request, call_next):
- start_time = time.time()
-
- # 获取请求信息
- method = request.method
- url = str(request.url)
- client_ip = request.client.host if request.client else None
- user_agent = request.headers.get("user-agent", "")
-
- # 获取请求体(如果是POST/PUT),其它方法不修改url
- request_body = ""
- if method in ["POST", "PUT", "PATCH"]:
- try:
- body = await request.body()
- request_body = body.decode('utf-8')[:1000] # 限制长度
- except:
- pass
-
- # 执行请求
- response = await call_next(request)
-
- # 计算执行时间
- execution_time = int((time.time() - start_time) * 1000)
-
- # 获取响应状态码
- status_code = response.status_code
-
- # 异步记录日志(避免阻塞)
- try:
- db = SessionLocal()
- try:
- api_log = APILog(
- endpoint=url,
- method=method,
- request_data=request_body,
- ip_address=client_ip,
- user_agent=user_agent,
- response_code=status_code,
- execution_time=execution_time,
- created_at=datetime.now()
- )
- db.add(api_log)
- db.commit()
- except Exception as e:
- db.rollback()
- logger.error(f"记录API日志失败: {e}")
- finally:
- db.close()
- except:
- pass
-
- return response
|