為 fastapi 新增全域性唯一請求id,用於日誌跟蹤

ponponon發表於2022-02-26

為了做日誌跟蹤,我們可以用下面的辦法來搞一個 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"

圖片.png

事實上,已經有相應的開源實現了:snok/asgi-correlation-id

參考文章:
FastAPI 入門系列 之 中介軟體!

相關文章