此 Project 為 PyCon TW 2024 「全方位強化 Python 服務可觀測性:以 FastAPI 和 Grafana Stack 為例」 分享所使用的範例程式碼。
Slide:全方位強化 Python 服務可觀測性:以 FastAPI 和 Grafana Stack 為例
演講錄影:https://youtu.be/y3sumuoDq4w
Demo 影片:https://youtu.be/3Vvtqb3w5m0
想了解更多可觀測性的資訊,可以參考:
- 可觀測性介紹書籍:可觀測性入門指南:Logs、Metrics、Traces 三大實戰應用
- iThome 鐵人賽可觀測性系列文章:時光之鏡:透視過去、現在與未來的 Observability
- Observability 實作範例:FastAPI with Observability
- App:FastAPI Application
- basic.py:基本的 FastAPI Application,示範如何使用 Prometheus Client Library 以及 Zero-code Instrumentation
- main.py:進階的 FastAPI Application,示範如何使用 Code-based Instrumentation,並連接 PostgreSQL 和 redis
- PostgreSQL:資料庫
- redis:快取資料庫
- Tempo:接收 OpenTelemetry SKD 發送的 Trace Data
- Prometheus:爬取 Application 揭露在
/metrics
的 Metrics - Loki Docker Driver:爬取 Container 的 Log 傳送至 Loki
- Loki:接收 Loki Docker Driver 傳送的 Log
- Grafana:查詢 Tempo、Prometheus、Loki 的資料
- Install Loki Docker Driver
docker plugin install grafana/loki-docker-driver:3.1.1 --alias loki --grant-all-permissions
- Start all services
docker-compose up -d
-
Send Request to applications
-
With Swagger UI
- basic: http://localhost:8080/docs
- app-a: http://localhost:8000/docs
- app-b: http://localhost:8001/docs
- app-c: http://localhost:8002/docs
-
with k6, installation guide
k6 run --vus 3 --duration 300s k6-script.js k6 run --vus 3 --duration 30s k6-script-todo.js
-
-
Open Grafana on http://localhost:3000 with admin/admin
- Visit provisioning dashboard FastAPI Observability
- Explore Metrics, Logs, and Traces with Grafana Explore
執行查詢 histogram_quantile(.99,sum(rate(fastapi_requests_duration_seconds_bucket{app_name="app-a", path!="/metrics"}[1m])) by(path, le))
並啟用 Exemplar
選項。
本範例的 Data Source 設定皆透過 Provisioning 的方式進行,以下僅用於說明各 Data Source 的設定內容,無需手動操作。
在 Prometheus Data Source 中設定 Exemplar 要連結的目標 Trace Data Source,以及 Trace ID 的 Label 名稱。
查詢 Metrics 時可以看到該 Exemplar 的詳細資訊,其中的 TraceID
就會作為 Trace Data Source 的 Trace ID 來查詢。
在 Loki Data Source 中設定如何解析出 Trace ID,這裡使用正則表達式 (?:trace_id)=(\w+)
取出 Log 中 trace_id=
後面的值,取得的值會作為 Tempo Data Source 的查詢參數,下方的 Debug log message
可以看到有成功取得 Trace ID。
在 Tempo Data Source 中設定要連結的目標 Loki Data Source,因為 Loki 需要至少一個 Label
才能進行查詢,所以需要透過 Tags 指定 Trace 中的哪個資訊作為 Loki 的 Label,這裡使用 Trace 中的 service.name
作為 Loki 的 compose_service
Label,並且同時用 Trace ID 作為文字篩選條件。
在這筆 Trace 的 Span 中,可以看到有 service.name
這個資訊,值為 app-a
,點擊 Logs for this span
後右側展開的 Loki 查詢條件就會自動帶入 compose_service="app-a"
以及 Trace ID 篩選,這樣就可以查詢到該 Trace 在 app-a
的所有 Log 訊息。