nikkie-ftnextの日記

イベントレポートや読書メモを発信

OpenTelemetryはWebアプリにもクライアントにも計装して全体をトレースできるのか! 〜FastAPIとHTTPXを例に〜

はじめに

七尾百合子さん、お誕生日 133日目 おめでとうございます! nikkieです。

ここ最近 OpenTelemetry を触っています。
サーバサイドのロギングの発展系みたいにとらえていましたが、もっと広くシステム全体を観測できるようにするものと理解を更新しました。

目次

疑問「クライアントにもOpenTelemetryって必要なの?」

OpenTelemetryをサーバサイドのロギングの発展系ととらえたために、疑問が出てきました。

FlaskやFastAPIなどWebアプリケーション側に入れるのは、アプリケーションの可観測性を上げるためと理解できるのですが、requestsやhttpxといったクライアント側にもOpenTelemetryのパッケージが用意されているのはなぜなんでしょう?

Webアプリケーション側の具体的なパッケージ

素振りしていく中でクライアント側にもパッケージがあることに気づきます。

なぜクライアント側にもOpenTelemetryのパッケージがあるのでしょう?
疑問をo3-proに聞いてみました。

https://opentelemetry.io/ja/docs/zero-code/python/example/ を読み、FlaskやFastAPIなどWebアプリケーション側に入れるのは、アプリケーションの可観測性を上げるためと理解しました。
一方でrequestsやhttpxといったクライアント側にもOpenTelemetryのinstrumentのパッケージが用意されているのですが、これはなぜなのでしょう?

そこでクライアントからWebアプリケーションまでトレースするために必要ということを知ります。

「自動計装の例」で見落としていたクライアントのトレースID

o3-proの回答でハッとなり、ドキュメントの「自動計装の例」を再度動かしました。

cloneしてきて環境構築1
https://opentelemetry.io/ja/docs/zero-code/python/example/#install
opentelemetry-bootstrapflaskrequestsの計装ライブラリをインストールしています2

.venv/bin/python server_programmatic.pyでサーバを起動し、別のコンソールで.venv/bin/python client.py testing
このとき、クライアントのcontextのtrace_idと、サーバのcontextのtrace_idが一致します!

これって結構すごいと思います。
サーバのロギングだけだと、そのログがどのリクエストによるものかって、リクエストもロギングされていないと特定しづらいと思うのですが、OpenTelemetryではトレースのIDが一致することで簡単に特定できます!
クライアントもサーバもトレース(追跡)できるんですね。

FastAPIとHTTPXを例にお試し

FastAPIのアプリは過去の記事で作成したものです。
https://gist.github.com/ftnext/a1b354b2dc7e9a8ac8059afa4792591d

HTTPXを使ったクライアントはPEP 723を使って書きました。

サーバのスクリプトuv runし、別のコンソールでクライアントのスクリプトuv runします。
出力を見ると、サーバとクライアントでトレースIDが一致しています!!
https://gist.github.com/ftnext/f0275fa336d42c8cd6ad70d56476b740

終わりに

OpenTelemetryの認識が改まりました。
クライアント向けの計装ライブラリもあるのは、クライアントからWebアプリケーションまで共通のIDでトレースするためなんですね。

この考え方は初めて出会いましたが、私にとって革新的です!
自作のAPIに多数のリクエストを送るバッチ処理、共通IDでトレースできたら実行中のエラー対応がめちゃめちゃ捗っていたな〜
OpenTelemetry、すっげ〜!


  1. 仮想環境のディレクトリは.venv派です
  2. opentelemetry-bootstrap -a install コマンドは、アクティブな site-packages フォルダにインストールされているパッケージのリストを読み込んで、該当するパッケージがあれば、対応する計装ライブラリをインストールします。」 ref: https://opentelemetry.io/ja/docs/zero-code/python/#setup