Python アプリに計装ゼロで分散トレースを追加できる OpenTelemetry Python Contrib の使い方

タグ OpenTelemetryPython分散トレーシング自動計装可観測性FastAPIDjangoCNCFcolumnコラムlinuxLinuxwindowsWindowsGitHubオープンソースopen-telemetryopentelemetry-python-contrib
🚀 今すぐ試せます! デモスクリプトをダウンロードして、解凍後にターミナルで bash ファイル名.sh を実行してください(中身を一度確認してから実行すると安心です)。 (macOS / Linux 環境が必要)

Python アプリに計装ゼロで分散トレースを追加できる OpenTelemetry Python Contrib の使い方

ひとことでいうと

OpenTelemetry Python Contrib は、Python アプリケーションにほぼコードを書かずに分散トレーシング・メトリクス・ログを追加できるライブラリ群です。Django・Flask・FastAPI・SQLAlchemy・Redis など 100 以上の人気ライブラリに対応したプラグインが揃っており、本番環境の可観測性(アプリの動作状況を外から見える化すること)を短時間で実現できます。3 つの機能が柱になっており、コマンド 1 行でアプリを変えずに HTTP リクエストや DB クエリのトレースを収集する「ゼロコード自動計装」、独自のビジネスロジックを計装する「手動計装 API」、Jaeger・Zipkin・Prometheus など主要な監視ツールへデータを送る「エクスポーター群」から構成されています。CNCF(Cloud Native Computing Foundation)という国際的な団体が推進するベンダー中立の標準規格 OpenTelemetry を、Python エコシステムから支えるコミュニティ主導のパッケージ集です。初心者から本番運用チームまで、段階的に導入しやすい設計になっています。

こんな人におすすめ

1. マイクロサービスを複数運用している開発者 複数のサービスが互いに呼び合う構成では、どのサービスが遅いのかを特定するのが難しくなりがちです。OpenTelemetry Python Contrib を使うと、サービス間の依存関係やレイテンシ(応答の遅れ)を一本の「トレース」として可視化でき、ボトルネックをすばやく見つけられます。

2. SRE やインフラエンジニア 本番障害の根本原因分析(RCA)に分散トレーシングを活用したい方に向いています。すでに導入している Datadog・New Relic・Grafana Tempo などの監視ツールへ OpenTelemetry の標準フォーマットでデータを送れるため、既存の監視基盤を活かしたまま導入できるのが魅力です。

3. Python Web アプリ開発者 Django や FastAPI などのフレームワークを使っているアプリに、最小限の変更でメトリクスやトレースを追加したい方の入り口となるライブラリです。APM(Application Performance Monitoring=アプリのパフォーマンスを常時計測する仕組み)を素早く導入したいときにも役立ちます。

インストール・使い方

このリポジトリはモノリポ(複数の独立したパッケージを 1 つの Git リポジトリで管理する構成)になっており、必要なパッケージだけを個別にインストールして使います。ターミナル(文字を入力してコンピューターに命令を送る画面)でコマンドをコピー&ペーストするだけで始められます。

Step 1: OpenTelemetry のコアパッケージをインストールする

まず、OpenTelemetry の基礎となる 2 つのパッケージをインストールします。opentelemetry-api はトレースを記録するための共通インターフェース、opentelemetry-sdk はその実際の動作を担うパッケージです。

pip install opentelemetry-api opentelemetry-sdk

Step 2: 使いたいライブラリ向けのプラグインをインストールする

自分のアプリで使っているライブラリに合わせてプラグインを選びます。以下はよく使われる例です。必要な行だけコピー&ペーストして実行してください。

# Flask(Python の軽量 Web フレームワーク)の場合
pip install opentelemetry-instrumentation-flask

# Django(フル機能の Web フレームワーク)の場合
pip install opentelemetry-instrumentation-django

# SQLAlchemy(データベース操作ライブラリ)の場合
pip install opentelemetry-instrumentation-sqlalchemy

# requests ライブラリ(HTTP 通信ライブラリ)の場合
pip install opentelemetry-instrumentation-requests

全部を一度に入れる必要はありません。自分のアプリで使っているライブラリに対応するものだけで十分です。

Step 3: OTLP エクスポーターをインストールして自動計装を起動する

OTLP(OpenTelemetry Protocol)は、収集したトレースデータを外部の監視ツールへ送るための標準プロトコルです。以下のコマンドでエクスポーターをインストールしたあと、opentelemetry-instrument コマンドでアプリを起動すると、アプリのコードを一切変えずに自動でトレースが収集されます。

pip install opentelemetry-exporter-otlp

opentelemetry-instrument \
  --exporter otlp \
  --endpoint http://localhost:4317 \
  python app.py

--endpoint には Jaeger(トレース可視化ツール)など、受信側のアドレスを指定します。アプリ起動コマンドを opentelemetry-instrument ... python app.py に置き換えるだけで計装が適用されます。

Step 4: 手動計装でビジネスロジックを詳しく記録する

自動計装ではカバーしきれない独自の処理には、コードに直接スパン(処理の記録単位)を書き込む「手動計装」が使えます。以下の例では注文処理の開始・終了と注文 ID・ステータスを属性として記録しています。

from opentelemetry import trace

tracer = trace.get_tracer("my-service")

def process_order(order_id: str):
    with tracer.start_as_current_span("process_order") as span:
        span.set_attribute("order.id", order_id)
        result = fetch_and_process(order_id)
        span.set_attribute("order.status", result.status)
        return result

with ブロックの中がひとつの「スパン」として記録され、処理の開始・終了時刻や指定した属性が自動で保存されます。自動計装と組み合わせて使うことで、フレームワーク全体の動作と業務ロジックの詳細を同一トレース上で確認できます。

ブラウザで試す(デモ)

上記の手動計装コードをインタラクティブに体験できるデモも用意されています。スパン名(Operation Name)と属性(key=value 形式)を入力すると OTel スパンが生成され、Trace ID・Span ID・属性の一覧がリアルタイムで表示されます。ローカル環境のセットアップなしに OpenTelemetry のデータモデルを直感的に理解できる入り口として活用できます。

動かしてみた

試す前に知っておくと役立つ動作環境の目安をまとめます。

このリポジトリはモノリポ構成のため、個々のパッケージは instrumentation/exporter/propagator/ などのサブディレクトリにそれぞれ独立した pyproject.toml を持っています。ルートを直接インストールするのではなく、各サブディレクトリを対象に操作する方式が推奨されています。

  • Python 3.9 以上(3.12 まで CI で動作確認済み)
  • pip 21.3 以上(editable install を使う場合)
  • 依存解決には uv または tox-uv も利用可能(uv.locktox-uv.toml がリポジトリに同梱)

PyPI から個別パッケージとして公開されているため、ほとんどの場合は pip install するだけで始められます。外部の監視バックエンドを用意しなくても、コンソールエクスポーターを使えばターミナルにトレースデータが出力されるので、まず動作確認するのに便利です。

pip install opentelemetry-api opentelemetry-sdk
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor

provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
trace.set_tracer_provider(provider)

tracer = trace.get_tracer("hello-otel")

with tracer.start_as_current_span("hello-span") as span:
    span.set_attribute("greeting", "Hello, OpenTelemetry!")
    print("スパンを作成しました")

実行するとコンソールに Trace ID・Span ID・属性・開始/終了時刻が含まれるデータが出力されます。OTel のデータモデルを直接確認できるので、仕組みを体感するのに最速の方法です。opentelemetry-sdk だけで動作し、外部サービスへの接続は不要です。

はじめの一歩:実践のコツ

すぐに試せる行動をまとめます。順番に進めると、スムーズに動作確認できます。

  • まずコンソールエクスポーターで動かす: Jaeger など外部ツールを先に用意しなくても、コンソールにトレースが出力されれば OTel が動いている証拠です。最小構成で成功体験を得てから次のステップへ進みましょう。
  • 使いたいフレームワークのプラグインだけ入れる: 全プラグインを一度に入れる必要はありません。Flask なら opentelemetry-instrumentation-flask だけで十分です。
  • opentelemetry-instrument コマンドを最初に試す: アプリコードをまったく変えずに計装できます。まず自動計装を試してから、必要な箇所だけ手動計装を追加するのが効率的です。
  • スパンに属性を付けて絞り込みやすくする: span.set_attribute("user.id", user_id) のように業務上の情報を属性として記録すると、後から Jaeger UI などで検索・フィルタリングしやすくなります。
  • Python バージョンを事前に確認する: Python 3.9 未満の環境では動作しない場合があります。python --version で確認しておきましょう。
  • モノリポの構造を把握してから開発する: コントリビュート(機能追加や修正)する場合は、instrumentation/ などサブディレクトリの構成を先に確認すると迷いにくくなります。

活用例

  • E コマースの注文フロー可視化: 注文受付 → 在庫確認 → 決済処理 → 出荷指示の各ステップをスパンとして記録します。opentelemetry-instrumentation-requestsopentelemetry-instrumentation-sqlalchemy を組み合わせると、外部 API 呼び出しと DB クエリを同一トレース上で確認できます。
  • 機械学習パイプラインの監視: データ前処理・モデル推論・後処理の実行時間を自動計装で収集し、パイプライン全体のボトルネックを特定します。手動計装 API を使えば特徴量生成の所要時間を属性として記録する運用も可能です。
  • マイクロサービス間のトレース伝播: W3C TraceContext プロパゲーター(例: opentelemetry-propagator-b3)を使い、HTTP ヘッダーで Trace ID を引き継ぐことで複数サービスをまたいだエンドツーエンドのトレースを実現します。Kubernetes 上のサービスメッシュ環境でも標準ヘッダーを通じてシームレスに動作します。
  • 既存の監視ツールへのデータ送信: Datadog・New Relic・Grafana Tempo など、すでに導入している監視ツールへ OTLP 形式でデータを送れます。監視基盤を切り替えるときも、アプリ側のコードを変えずにエクスポーターの設定を変えるだけで対応できます。
  • 社内 API ゲートウェイのレイテンシ分析: 社内サービス間の API 呼び出しに opentelemetry-instrumentation-requests を適用し、どのエンドポイントで遅延が起きているかを定量的に把握します。SLO(サービスレベル目標)の達成状況を可視化するのにも役立ちます。
  • 開発・学習用のローカルトレース確認: Jaeger をローカルで Docker 起動し、手元のアプリのトレースを可視化する学習環境を手軽に作れます。コンソールエクスポーターからはじめて、慣れたら OTLP エクスポーターに切り替えると段階的に理解が深まります。

用語とポイント解説

Span(スパン) 分散トレースの基本単位です。かんたんに言うと「ある処理の開始から終了まで」を記録したひとかたまりのデータです。処理名・開始/終了時刻・属性・ステータスが含まれます。複数のスパンが親子関係でつながってひとつのトレースを構成します。

Trace(トレース) 複数のスパンを親子関係でつなげたもので、リクエスト全体の処理フローを表します。かんたんに言うと「ユーザーがボタンを押してから結果が返るまでの全工程の記録」です。Trace ID という一意の識別子で複数サービスをまたいでも追跡できます。

Exporter(エクスポーター) 収集したスパン情報を外部の監視ツールへ送り出すコンポーネントです。かんたんに言うと「集めたデータを外に届ける宅配便の役割」です。Jaeger・Zipkin・OTLP・Prometheus など、送り先に合わせた種類が用意されています。

Propagator(プロパゲーター) サービス間で Trace ID を HTTP ヘッダーなどに乗せて伝播させる仕組みです。かんたんに言うと「バトンリレーのバトン」で、サービスをまたいでも同じトレースとして記録するために必要です。現在は W3C TraceContext 形式が標準として広く使われています。

Auto-Instrumentation(自動計装) アプリのコードを一切変えずに計装を適用できる仕組みです。かんたんに言うと「アプリを包んでデータ収集を代わりにやってくれる透明なフィルター」です。opentelemetry-instrument コマンドでアプリを起動するだけで動作し、既存コードへの手入れが不要です。

OTLP(OpenTelemetry Protocol) テレメトリデータ(トレース・メトリクス・ログ)を送るための標準転送プロトコルです。かんたんに言うと「OTel データを送るための共通言語」で、バックエンドを問わず同じ形式でデータを送れます。gRPC と HTTP の 2 種類の通信方式に対応しています。

モノリポ(Monorepo) 複数の独立したパッケージを 1 つの Git リポジトリ(ソースコードの置き場)で管理する構成です。かんたんに言うと「たくさんの商品が一つの倉庫にまとまっている状態」です。このリポジトリもその構成で、200 以上のパッケージがサブディレクトリに収められています。

TracerProvider(トレーサープロバイダー) トレーサー(スパンを生成する道具)を管理・配布する中心的なオブジェクトです。かんたんに言うと「トレーサーを貸し出す窓口」で、エクスポーターやプロセッサーの設定もここで行います。アプリ起動時に 1 度だけ初期化してグローバルに登録する使い方が一般的です。

Span Attribute(スパン属性) スパンに付加できるキーと値のペアで、処理の詳細情報を記録します。かんたんに言うと「スパンに貼るラベル」で、user.idorder.status のように業務上の情報を自由に追加できます。後から Jaeger などのツールで属性を使ってフィルタリング・検索を行えるため、障害調査の精度が上がります。

ぜひマイクロサービスの障害調査や、Django・FastAPI などを使った Web アプリのパフォーマンス改善などに活用してみてはいかがでしょうか。