OpenTelemetry¶
🌐 AI と人間による翻訳
この翻訳は、人間のガイドに基づいて AI によって作成されました。🤝
原文の意図を取り違えていたり、不自然な表現になっている可能性があります。🤖
AI LLM をより適切に誘導するのを手伝う ことで、この翻訳を改善できます。
APIを実行しているとき、受信するトラフィックの量、遅いリクエスト、エラーが発生するタイミングを把握したくなることがあります。
テレメトリーは、こうした疑問に答えるためのアプリケーションの動作に関するデータです。一般的には、次の種類があります:
- メトリクス: レスポンス時間や処理中のリクエスト数など、時間の経過に沿って集計できる測定値です。
- トレース: 個々のリクエストと、それを処理するために実行された操作の記録です。時間を計測する各操作をスパンと呼びます。
- ログ: アプリケーションの起動や操作の失敗など、イベントのタイムスタンプ付きの記録です。
OpenTelemetryは、テレメトリーを収集して監視サービスに送信するための標準とツールのセットです。監視サービスのダッシュボードで、そのデータを確認できます。
FastAPIはデフォルトでOpenTelemetryをサポートしており、HTTPリクエストのトレース、メトリクス、ログを提供します。WebSocket接続でもトレースとログを提供します。このデータを確認するには、受信する監視サービスを設定してください。
FastAPIのインストール¶
テレメトリーを送信するためのパッケージを含むstandardオプションを指定してFastAPIをインストールします:
$ 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プランでは、メトリクスダッシュボードでリクエスト数、エラー率、レスポンス時間を確認できます。

その他の監視サービス¶
別の監視サービスにテレメトリーを送信するには、テレメトリー送信用のOpenTelemetryプロトコルであるOTLPを受け付けるエンドポイントを設定します。サービスの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}スパンを含むトレースと、リクエスト数、レスポンス時間、処理中のリクエスト数のメトリクスを確認できます。
テレメトリーのカスタマイズ¶
プロバイダーとエクスポーターの設定¶
プロバイダーは、トレース、メトリクス、ログを記録するオブジェクトを提供します。その設定によって、データの処理方法とエクスポート方法を制御します。
テレメトリーライブラリは、OpenTelemetryのグローバルプロバイダーを設定できます。アプリの起動前にライブラリを設定すると、FastAPIはそれらのプロバイダーを自動的に使用します。
デフォルトでは、FastAPIはエクスポーターを追加せずに、設定済みのプロバイダーを使用します。自動設定が有効で、環境変数にOTLPエンドポイントが設定されている場合、FastAPIは有効な各プロバイダーに、その送信先のエクスポーターを追加します。既存のエクスポーターは、それぞれの送信先にデータを送信し続けます。
別のライブラリがすでに同じ送信先へのエクスポートを設定している場合は、テレメトリーの重複を避けるため、FASTAPI_OTEL_AUTO_CONFIGUREを未設定のままにするか、falseに設定してください。
telemetry辞書にプロバイダーを直接渡すこともできます。例えば、次のプロバイダーはOpenTelemetryのコンソールエクスポーターを使用して、リクエストのスパンをターミナルに出力します:
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}
エクスポーターは、スパンを送信先に送ります。BatchSpanProcessorはスパンをまとめ、バックグラウンドで送信します。監視ライブラリの送信先を使用するには、コンソールエクスポーターをそのライブラリが提供するエクスポーターに置き換えてください。その他の設定オプションについては、OpenTelemetryのPython計装ガイドを参照してください。
メトリクスやログのプロバイダーを指定するには、同じ辞書内でmeter_providerまたはlogger_providerを使用します。プロバイダーを作成したアプリケーションまたはライブラリが、そのシャットダウンを管理します。FastAPIは、自身が追加したエクスポートコンポーネントを管理します。
注意
OpenTelemetryはデフォルトでグローバルプロバイダーを使用します。マウントされたサブアプリケーションごとに独立したテレメトリー設定は保証されません。
リクエスト操作のトレース¶
デフォルトでは、リクエストのトレースには、依存関係の解決、path operation関数の実行、レスポンスのシリアライズ、FastAPIのBackgroundTasks内の各タスクの実行に対応するスパンが含まれます。これらのスパンは同じプロバイダーとエクスポーターを使用します。
バックグラウンドタスクのスパンも、リクエストのトレースの一部として扱われます。これらはHTTPレスポンスのスパンが終了した後に実行されるため、測定されるレスポンス時間は増加しません。
HTTPリクエストのスパンのみを記録するには、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接続には、WS /ws/{room}のようなスパンがあり、ハンドラーと依存関係のクリーンアップを対象とします。同じプロバイダーと設定を使用し、依存関係の解決とエンドポイントの実行にはoperation_spansの設定も適用されます。
HTTPリクエストのメトリクスは、HTTPリクエストのみを対象とします。コード1000または1001による正常なWebSocket切断では、エラーログは生成されません。
エラーの確認¶
FastAPIは、未処理の例外をOpenTelemetryのログとして記録し、リクエストまたは接続のトレースに関連付けます。トレースがサンプリングされていない場合でも、エラーログは記録されます。
例外ログには、例外の型、メッセージ、スタックトレースが含まれます。メッセージやスタックトレースには機密情報が含まれる可能性があります。プロバイダーのログプロセッサーを使用してフィルタリングやマスキングを行うか、logsをFalseに設定してこれらのログを無効にしてください。
FastAPIは、リクエストのバリデーション失敗も、ルートとエラー数を含む警告ログとして記録します。これらのログに無効な入力値は含まれません。
記録対象の選択¶
telemetry辞書では、次の設定も指定できます:
| 設定 | 目的 | デフォルト |
|---|---|---|
tracing |
HTTPリクエストとWebSocket接続のスパンを記録します | True |
metrics |
HTTPリクエストのメトリクスを記録します | True |
logs |
バリデーション失敗と未処理の例外を記録します | True |
operation_spans |
リクエスト操作のスパンを追加します | True |
exclude |
ASGIスコープを受け取る関数が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}を使用してください。