Skip to content

FastAPI 接口日志标准化

在 FastAPI 中,可以使用中间件来实现日志格式的标准化。通过自定义日志格式,统一请求和响应的日志格式。以下是实现标准化 FastAPI 接口日志格式的一种方法:

1. 配置日志格式

首先,通过 logging 配置日志格式,统一日志输出。

python
import logging

# 配置日志格式
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger("fastapi")

2. 创建日志中间件

使用 FastAPI 的 Middleware 来捕获每个请求和响应。通过记录请求方法、URL、状态码等信息,实现日志的标准化。

python
from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware
import time

app = FastAPI()

class LoggingMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        # 获取请求信息
        start_time = time.time()
        method = request.method
        url = request.url.path

        # 请求进入日志
        logger.info(f"Request: {method} {url}")

        # 调用路由处理请求
        response = await call_next(request)

        # 响应时间和状态码
        process_time = time.time() - start_time
        status_code = response.status_code

        # 响应日志
        logger.info(f"Response: {method} {url} - {status_code} - {process_time:.2f}s")

        return response

# 添加中间件
app.add_middleware(LoggingMiddleware)

3. 配置详细的日志信息

可以在日志中记录更多细节,比如客户端 IP、请求头、请求体、响应体等。以下代码记录请求和响应的详细信息:

python
class LoggingMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        start_time = time.time()

        # 请求信息
        client_ip = request.client.host
        method = request.method
        url = request.url.path
        headers = dict(request.headers)
        
        # 记录请求详细信息
        logger.info(f"Request from {client_ip} - {method} {url} - Headers: {headers}")

        # 获取请求体
        request_body = await request.body()
        logger.info(f"Request body: {request_body.decode(errors='ignore')}")

        # 调用并获取响应
        response = await call_next(request)
        process_time = time.time() - start_time
        status_code = response.status_code

        # 记录响应详细信息
        response_body = b""
        async for chunk in response.body_iterator:
            response_body += chunk
        logger.info(f"Response {status_code} - Body: {response_body.decode(errors='ignore')} - Process Time: {process_time:.2f}s")

        return response

4. 输出日志样式示例

这样配置后,日志输出将类似于以下标准化格式:

2024-10-29 10:00:00 - fastapi - INFO - Request from 127.0.0.1 - GET /api/example - Headers: {...}
2024-10-29 10:00:00 - fastapi - INFO - Request body: {...}
2024-10-29 10:00:00 - fastapi - INFO - Response 200 - Body: {...} - Process Time: 0.01s

以上方法可以帮助你在 FastAPI 中实现标准化的日志格式。

Released under the MIT License.