Python環境でのOpenTelemetry計装 - 実装ガイド ​

Pythonはマイクロサービスやバックエンドアプリケーション開発に広く使われています。分散システムの可視化には、これらのPythonアプリケーションから適切にトレーシングデータを収集することが必須です。このガイドでは、PythonアプリケーションにOpenTelemetryの計装を実装し、トレーシングデータを取得するための具体的な手順を紹介していきます。

Python環境での計装が必要な理由 ​

Pythonアプリケーションに計装を施すことで、API呼び出し、データベースアクセス、外部サービスへのリクエストといった個々の処理が、分散トレースの中でどのような経路をたどっているのかを把握できます。このデータなしには、マイクロサービス間の遅延問題やエラーの原因特定は困難になります。

OpenTelemetryのPython実装により、計装のコストを最小化しながら、本番環境での可視化を実現できます。

環境セットアップ ​

前提条件 ​

OpenTelemetry PythonはPython 3.9以上をサポートしています。まず、実行環境がこれを満たしているか確認しましょう。

bash
python --version

仮想環境の構築 ​

Pythonプロジェクトを隔離された環境で実行するため、仮想環境の作成をお勧めします。

bash
python -m venv otel_env
source otel_env/bin/activate  # Linux/macOS
# または
otel_env\Scripts\activate  # Windows

必要なパッケージのインストール ​

OpenTelemetryの基本パッケージをインストールします。

bash
pip install opentelemetry-api opentelemetry-sdk

Collectorへのデータ送信やWebフレームワーク対応など、具体的な用途に応じて追加パッケージをインストールする必要があります。

自動計装の実装 ​

自動計装とは ​

自動計装は、アプリケーションコードに最小限の変更を加えるだけで、多くのライブラリ(HTTPクライアント、データベースドライバなど)からテレメトリデータを自動的に収集する仕組みです。OpenTelemetryコミュニティが提供する計装ライブラリを使用することで、実装の手間を大幅に削減できます。

計装パッケージのインストール ​

OpenTelemetryは、よく使用されるライブラリの計装パッケージをあらかじめ用意しており、pip install opentelemetry-instrumentation-<library-name>のパターンで個別にインストールできます。

例えば、Flask、requests(HTTPクライアント)、SQLAlchemy(ORM)など、よく使用されるライブラリに対応した計装パッケージが存在します。

必要な計装パッケージをインストール後、アプリケーション起動時にそれらを有効化するだけで、自動的にスパンが記録され始めます。この方式により、既存のアプリケーションコードにほぼ変更を加えることなく、テレメトリデータを取得できます。

自動インストール方法(opentelemetry-bootstrap) ​

複数の計装パッケージを一括でインストール・有効化するには、opentelemetry-bootstrapコマンドが便利です。

bash
opentelemetry-bootstrap -a install

このコマンドにより、一般的なライブラリ(requests、Flask、Django、FastAPI等)に対応した計装パッケージが自動的にインストールされます。大規模なプロジェクトや、多数のライブラリを使用する場合は、この方法が効率的です。

手動計装の基本 ​

自動計装では対応していない独自の処理やビジネスロジックの詳細な追跡には、手動計装が必要です。

TracerProviderの初期化 ​

トレーシング機能を使用するには、まずTracerProviderを初期化し、トレーサーを取得します。

python
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider

provider = TracerProvider()
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("my.application")

Spanの作成方法 ​

Spanを作成する最も推奨される方法は、コンテキストマネージャーを使用することです。このパターンにより、Span内で発生した例外の処理や、自動的なSpanのクローズが行われます。

python
with tracer.start_as_current_span("process_order") as span:
    # ビジネスロジックをここに記述
    order_id = process_order()
    span.set_attribute("order.id", order_id)

Spanに属性(attributes)を追加することで、トレース後の分析時に有用な情報を付与できます。

デコレーターによるSpan作成 ​

関数全体の実行時間を記録したい場合、デコレーターを使用すると簡潔に記述できます。

python
DISCOUNT_RATE = 0.1

@tracer.start_as_current_span("calculate_discount")
def calculate_discount(amount):
    return amount * (1 - DISCOUNT_RATE)

このパターンでは、関数の実行全体が自動的にSpanで囲まれ、実行時間が記録されます。

Webフレームワーク対応 ​

計装フロー図 ​

Webフレームワーク計装パッケージ ​

主要なPythonフレームワークの計装パッケージをインストールし、アプリケーション起動時に有効化します。

Flask、Django、FastAPI のいずれかを使用する場合は、対応する計装パッケージをインストール後、起動時に有効化します。

bash
pip install opentelemetry-instrumentation-flask  # Flask の場合
pip install opentelemetry-instrumentation-django  # Django の場合
pip install opentelemetry-instrumentation-fastapi  # FastAPI の場合
python
# Flask の場合の有効化例
from opentelemetry.instrumentation.flask import FlaskInstrumentor
FlaskInstrumentor().instrument_app(app)

Django の場合はsettings.pyのINSTALLED_APPSとMIDDLEWAREに設定を追加します。

python
INSTALLED_APPS = ['opentelemetry.instrumentation.django']
MIDDLEWARE = ['opentelemetry.instrumentation.django.middleware.OpenTelemetryMiddleware']

FastAPI の場合は、次のように有効化します。

python
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
FastAPIInstrumentor().instrument_app(app)

これらの設定により、すべてのHTTPリクエストが自動的にスパンで記録されます。

データ送信の設定 ​

自動計装と手動計装により収集したトレーシングデータを、OpenTelemetry Collectorに送信するには、エクスポーターを設定する必要があります。OTLPエクスポーター(OpenTelemetry Protocol)を使用する場合、以下のようにTracerProviderを拡張します。

bash
pip install opentelemetry-exporter-otlp

エクスポーターをTracerProviderに追加します。

python
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))

デフォルトではlocalhost:4317に対してトレースデータが送信されます。