FastAPI 中如何使用 Middleware 實(shí)現(xiàn)請(qǐng)求日志和耗時(shí)統(tǒng)計(jì)?
在日常開(kāi)發(fā)中,我們經(jīng)常需要統(tǒng)計(jì)每個(gè)請(qǐng)求的耗時(shí)、記錄訪問(wèn)日志,便于監(jiān)控接口性能和排查問(wèn)題。在 FastAPI 中,這種需求的最佳實(shí)踐方式就是 —— 使用中間件(Middleware)!
本文將帶你一步步實(shí)現(xiàn)一個(gè)通用的請(qǐng)求耗時(shí)統(tǒng)計(jì)中間件,并自動(dòng)記錄日志(方法、路徑、耗時(shí)等信息)。

什么是 Middleware?
Middleware(中間件)是介于請(qǐng)求進(jìn)入與響應(yīng)返回之間的一段可插拔邏輯,可以用來(lái)處理:
- 日志記錄
- 請(qǐng)求耗時(shí)
- 權(quán)限校驗(yàn)
- 跨域處理(CORS)
- 請(qǐng)求頻率限制(Rate Limit)等
FastAPI 提供了便捷的方式來(lái)自定義中間件,核心是通過(guò)裝飾器或注冊(cè)機(jī)制封裝函數(shù)。
實(shí)現(xiàn)一個(gè)耗時(shí)統(tǒng)計(jì)中間件
我們下面寫(xiě)一個(gè)中間件,來(lái)統(tǒng)計(jì)每個(gè)請(qǐng)求從進(jìn)入到響應(yīng)返回所花費(fèi)的時(shí)間,并將日志打印出來(lái):
middlewares/request_timer.py
import time
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
import logging
# 設(shè)置日志輸出
logger = logging.getLogger("request_logger")
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
formatter = logging.Formatter('[%(asctime)s] %(levelname)s: %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
class RequestTimerMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
start_time = time.time()
response = await call_next(request) # 執(zhí)行請(qǐng)求處理鏈
process_time = time.time() - start_time
formatted_time = f"{process_time * 1000:.2f}ms"
logger.info(f"{request.method} {request.url.path} - 耗時(shí): {formatted_time}")
# 可以添加到響應(yīng)頭中返回
response.headers["X-Process-Time"] = formatted_time
return response如何在項(xiàng)目中啟用中間件?
只需在創(chuàng)建 FastAPI 應(yīng)用實(shí)例時(shí)添加:
main.py
from fastapi import FastAPI
from middlewares.request_timer import RequestTimerMiddleware
app = FastAPI()
# 添加中間件
app.add_middleware(RequestTimerMiddleware)
# 示例路由
@app.get("/ping")
async def ping():
return {"message": "pong"}訪問(wèn)接口 /ping 后你將看到如下日志輸出:
[2025-04-29 10:30:00] INFO: GET /ping - 耗時(shí): 2.33ms可擴(kuò)展的點(diǎn)
你還可以在中間件中擴(kuò)展更多功能,比如:
- 記錄響應(yīng)狀態(tài)碼
- 日志落盤(pán)或輸出到日志平臺(tái)(如 ELK)
- 日志中包含 IP、User-Agent、用戶(hù)信息等
- 將日志結(jié)構(gòu)化為 JSON 格式(便于日志平臺(tái)解析)
總結(jié)
通過(guò)中間件的方式,我們實(shí)現(xiàn)了:
- 請(qǐng)求耗時(shí)統(tǒng)計(jì)
- 請(qǐng)求路徑和方法記錄
- 響應(yīng)頭中加入處理時(shí)間
這是構(gòu)建高質(zhì)量 Web API 服務(wù)的必備實(shí)踐,尤其對(duì) 運(yùn)維監(jiān)控和性能分析 非常有幫助。































