為了做日誌跟蹤,我們可以用下面的辦法來搞一個 request_id
或者說 correlation_id
的東西。
main.py
import sys
import uvicorn
import logging
from uuid import uuid4
from loguru import logger
from fastapi import FastAPI
from fastapi import Request
from typing import Optional
from contextvars import ContextVar
correlation_id: ContextVar[Optional[str]] = ContextVar(
'correlation_id', default=None)
app = FastAPI()
@app.middleware("http")
async def add_request_id_header(request: Request, call_next):
correlation_id.set(uuid4().hex)
response = await call_next(request)
response.headers["x-request-id"] = correlation_id.get()
return response
logger.remove()
def correlation_id_filter(record):
record['correlation_id'] = correlation_id.get()
return record['correlation_id']
fmt = "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <red> {correlation_id} </red> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>"
logger.add(sys.stderr, format=fmt, level=logging.DEBUG,
filter=correlation_id_filter)
@app.get('/')
def index():
logger.info(f"Request with id ")
return 'OK'
if __name__ == "__main__":
uvicorn.run(app="main:app", host="0.0.0.0", port=8000)
使用下面的命令執行程式:
python main.py
用下面的命令發起 http
請求來做測試
http http://localhost:8000/ -v
可以使用apt install httpie
或者brew install httpie
來安裝 http 命令
輸出如下:
GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: localhost:8000
User-Agent: HTTPie/2.6.0
HTTP/1.1 200 OK
content-length: 4
content-type: application/json
date: Mon, 21 Feb 2022 13:36:50 GMT
server: uvicorn
x-request-id: a27b3b26382545e9ae15358a321a9568
"OK"
事實上,已經有相應的開源實現了:snok/asgi-correlation-id
參考文章:
FastAPI 入門系列 之 中介軟體!