feat: 增加全局异常处理、使用route_class记录请求日志

This commit is contained in:
zy7y
2023-06-14 19:52:28 +08:00
parent e7cc1e5e18
commit 0ef41c6cde
7 changed files with 62 additions and 7 deletions

View File

@@ -2,6 +2,8 @@ from fastapi.exceptions import HTTPException
from starlette.requests import Request
from starlette.responses import JSONResponse
from core.log import logger
class TokenAuthFailure(HTTPException):
pass
@@ -19,4 +21,18 @@ async def http_exception(request: Request, exc: HTTPException):
)
exception_handlers = {HTTPException: http_exception}
async def global_exception(request: Request, exc):
if hasattr(request.state, "request_id"):
request_id = request.state.request_id
else:
request_id = None
logger.info("request_id 获取失败 请确认对应APIRouter使用了route_class=LogRoute ")
logger.exception(f"{request_id} Exception Log: {exc}")
return JSONResponse({
"msg": str(exc),
"code": 500,
"data": None
})
exception_handlers = {Exception: global_exception, HTTPException: http_exception}

View File

@@ -2,7 +2,14 @@ import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
# 创建一个 FileHandler用于写入日志文件
handler = logging.FileHandler('log_file.log')
handler.setLevel(logging.INFO)
# 设置日志格式
formatter = logging.Formatter("[%(asctime)s] %(levelname)s %(message)s")
handler.setFormatter(formatter)
# 添加 FileHandler 到日志处理器中
logger.addHandler(handler)

View File

@@ -1,10 +1,18 @@
import time
import uuid
from typing import Callable
from fastapi.middleware import Middleware
from fastapi.middleware.cors import CORSMiddleware
from fastapi.routing import APIRoute
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import Response
from core.log import logger
# fix 中间件没法获取到request 请求体数据 响应体
class CustomRequestLogMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
logger.info(
@@ -16,8 +24,28 @@ class CustomRequestLogMiddleware(BaseHTTPMiddleware):
return response
class LogRoute(APIRoute):
def get_route_handler(self) -> Callable:
original_route_handler = super().get_route_handler()
async def custom_route_handler(request: Request) -> Response:
request_id = str(uuid.uuid4())
request.state.request_id = request_id
logger.info(f"{request_id} Request Log {request.client} {request.method}"
f" {request.url} {request.headers}\n {await request.body()}")
before = time.time()
response: Response = await original_route_handler(request)
duration = time.time() - before
response.headers["X-Response-Time"] = str(duration)
logger.info(f"{request_id} Response Log {duration}s {response.headers}\n"
f" {response.body.decode('utf-8')}")
return response
return custom_route_handler
middlewares = [
Middleware(CustomRequestLogMiddleware),
# Middleware(CustomRequestLogMiddleware),
Middleware(
CORSMiddleware,
allow_origins=["*"],