OpenTelemetry¶
當你的 API 運作時,你可能會想知道它收到多少流量、哪些請求較慢,以及何時發生錯誤。
遙測(Telemetry)是關於應用程式行為的資料,能協助你回答這些問題。常見類型包括:
- 指標(Metrics):可隨時間彙整的測量值,例如回應時間和正在處理的請求數量。
- 追蹤(Traces):個別請求及其處理過程中所執行操作的記錄。每個計時的操作稱為一個 span。
- 日誌(Logs):附有時間戳記的事件記錄,例如應用程式啟動或操作失敗。
OpenTelemetry 是一套標準與工具,用於收集遙測資料並將其傳送到監控服務,讓你能在儀表板中查看這些資料。
FastAPI 預設提供 OpenTelemetry 支援,涵蓋 HTTP 請求的追蹤、指標和日誌。WebSocket 連線也提供追蹤和日誌。若要查看這些資料,請設定監控服務來接收它們。
安裝 FastAPI¶
安裝 FastAPI 時加上 standard 額外選項,其中包含傳送遙測資料所需的套件:
$ uv add "fastapi[standard]"
---> 100%
建立應用程式¶
建立一個 main.py 檔案:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
你不需要撰寫任何自訂程式碼來收集遙測資料。
FastAPI Cloud¶
當你使用 fastapi[standard] 部署到 FastAPI Cloud 時,指標功能會自動運作。你不需要做任何額外設定。
使用 Pro 方案時,你可以在指標儀表板中查看請求數量、錯誤率和回應時間。

其他監控服務¶
若要將遙測資料傳送到其他監控服務,請設定一個接受 OTLP 的端點。OTLP 是 OpenTelemetry 用於傳送遙測資料的協定。請使用該服務的 HTTP/protobuf 基礎端點。
設定以下環境變數,並將範例 URL 替換為你的端點:
export FASTAPI_OTEL_AUTO_CONFIGURE=true
export OTEL_SERVICE_NAME=my-api
export OTEL_EXPORTER_OTLP_ENDPOINT=https://collector.example.com
FASTAPI_OTEL_AUTO_CONFIGURE=true 會啟用 FastAPI 的匯出器自動設定功能。OTEL_SERVICE_NAME 用於在監控服務中識別你的應用程式。端點是接收資料的基礎 URL。追蹤會傳送到該 URL 下的 /v1/traces,指標傳送到 /v1/metrics,日誌則傳送到 /v1/logs。
如果你的服務需要驗證身分,請將 OTEL_EXPORTER_OTLP_HEADERS 設定為該服務指定的標頭,例如 api-key=YOUR_API_KEY。
執行應用程式¶
在同一個終端機中啟動應用程式:
$ uv run fastapi run
在另一個終端機中傳送請求:
$ curl http://127.0.0.1:8000/items/1
{"item_id":1}
開啟你的監控服務並找到 my-api。下一次匯出後,你就能看到包含 GET /items/{item_id} span 的追蹤,以及請求數量、回應時間和處理中請求的指標。
自訂遙測¶
設定提供者和匯出器¶
提供者(provider)提供用於記錄追蹤、指標或日誌的物件。其設定控制這些資料的處理與匯出方式。
遙測函式庫可以設定 OpenTelemetry 的全域提供者。在應用程式啟動前設定好函式庫,FastAPI 就會自動使用這些提供者。
預設情況下,FastAPI 會使用已設定的提供者,不會新增匯出器。當自動設定功能已啟用,且環境中設定了 OTLP 端點時,FastAPI 會為每個已啟用的提供者新增一個指向該目的地的匯出器。現有的匯出器會繼續將資料傳送到各自的目的地。
如果另一個函式庫已經設定好匯出到相同目的地,請不要設定 FASTAPI_OTEL_AUTO_CONFIGURE,或將其設為 false,以避免重複的遙測資料。
你也可以直接在 telemetry 字典中傳入提供者。例如,這個提供者使用 OpenTelemetry 的主控台匯出器,在終端機中印出請求的 span:
from fastapi import FastAPI
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter
tracer_provider = TracerProvider()
tracer_provider.add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))
app = FastAPI(telemetry={"tracer_provider": tracer_provider})
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
匯出器(exporter)會將 span 傳送到目的地。BatchSpanProcessor 會將 span 分組,並在背景傳送。將主控台匯出器替換成監控函式庫提供的匯出器,即可使用該函式庫的目的地。更多設定選項請參閱 OpenTelemetry 的 Python instrumentation 指南。
在同一個字典中使用 meter_provider 或 logger_provider,即可提供指標或日誌的提供者。建立提供者的應用程式或函式庫負責管理其關閉流程。FastAPI 則管理它所新增的匯出元件。
警告
OpenTelemetry 預設使用全域提供者。不保證掛載的子應用程式能使用獨立的遙測設定。
追蹤請求操作¶
預設情況下,請求追蹤會包含解析相依性、執行路徑操作函式、序列化回應,以及執行 FastAPI BackgroundTasks 中各個任務的 span。這些 span 使用相同的提供者和匯出器。
背景任務的 span 仍屬於該請求的追蹤。它們在 HTTP 回應 span 結束後才執行,因此不會增加測得的回應時間。
若只想記錄 HTTP 請求 span,請將 operation_spans 設為 False:
from fastapi import FastAPI
app = FastAPI(telemetry={"operation_spans": False})
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
追蹤 WebSocket 連線¶
每個 WebSocket 連線都有一個 span,例如 WS /ws/{room},涵蓋處理函式及相依性清理。它使用相同的提供者和設定,包括用於相依性解析和端點執行的 operation_spans。
HTTP 請求指標僅涵蓋 HTTP 請求。使用代碼 1000 或 1001 正常中斷的 WebSocket 連線不會產生錯誤日誌。
檢查錯誤¶
FastAPI 會將未處理的例外記錄為 OpenTelemetry 日誌,並連結到該請求或連線的追蹤。即使追蹤未被取樣,仍會記錄錯誤日誌。
例外日誌包含例外的類型、訊息和堆疊追蹤。訊息與堆疊追蹤可能包含敏感資訊。請使用提供者的日誌處理器來篩選或遮蔽這些資訊,或將 logs 設為 False 以停用這些日誌。
FastAPI 也會將請求驗證失敗記錄為警告日誌,其中包含路由和錯誤數量。這些日誌不會包含無效的輸入。
選擇要記錄的內容¶
telemetry 字典也接受以下設定:
| 設定 | 用途 | 預設值 |
|---|---|---|
tracing |
記錄 HTTP 請求和 WebSocket 連線的 span | True |
metrics |
記錄 HTTP 請求指標 | True |
logs |
記錄驗證失敗和未處理的例外 | True |
operation_spans |
為請求操作新增 span | True |
exclude |
當接收 ASGI scope 的函式回傳 True 時,略過該請求 |
None |
auto_configure |
為環境變數中設定的端點新增匯出器 | 若 FASTAPI_OTEL_AUTO_CONFIGURE=true 則為 True,否則為 False |
例如,若要收集指標,但排除健康檢查:
from fastapi import FastAPI
app = FastAPI(
telemetry={
"tracing": False,
"exclude": lambda scope: scope["path"] == "/health",
}
)
在 telemetry 字典中明確指定的 auto_configure 值會覆寫 FASTAPI_OTEL_AUTO_CONFIGURE。使用 telemetry={"auto_configure": True} 可在程式碼中啟用自動設定功能;使用 telemetry={"auto_configure": False} 則可為應用程式停用此功能,即使環境變數已啟用它。