コンテンツにスキップ

OpenTelemetry Python

設定

OTEL を使って Trace を DataKit に送信する前に、まずコレクタが正しく設定されていることを確認してください。

このページでは、OpenTelemetry で Python の自動計装を使う方法を示します。例は OpenTracing のサンプルをベースにしています。ここで使用しているソースファイルは、opentelemetry-python リポジトリからダウンロードするか、このページ上で確認できます。

このサンプルでは 3 つの異なるスクリプトを使います。主な違いは計装の方法です。

  • server_manual.py:手動計装。
  • server_automatic.py:自動計装。
  • server_programmatic.py:プログラムによる計装。

プログラムによる計装は、アプリケーションに少量の計装コードを追加するだけでよい方法です。一部の計装ライブラリは、プログラムから利用することで追加機能を提供し、計装プロセスをより細かく制御できます。

最初のスクリプト(自動計装エージェントを使わない)と 2 番目のスクリプト(エージェントを使う)をそれぞれ実行してください。どちらも同じ結果になるはずです。これは、自動計装エージェントが手動計装と同じ動作をしていることを示します。

自動計装では、計装ライブラリが実行時に monkey patching を使ってメソッドやクラスを書き換えるため、OpenTelemetry をアプリケーションコードに統合する作業が少なくなります。以下では、Flask ルートにおける手動・自動・プログラムによる計装の違いを確認します。

依存ライブラリのインストール

以下の demo を実行する前に、まず依存関係をインストールしてください

pip install opentelemetry-api opentelemetry-instrumentation

自動計装

  • 依存ライブラリをインストール

pip install opentelemetry-instrumentation-flask

  • server_automatic.py
from flask import Flask, request

app = Flask(__name__)


@app.route("/server_request")
def server_request():
    print(request.args.get("param"))
    return "served"


if __name__ == "__main__":
    app.run(port=8082)
  • 起動

opentelemetry-instrument --service_name auto-instrument-service --traces_exporter console,otlp --metrics_exporter none --exporter_otlp_endpoint http://0.0.0.0:4317 python server_automatic.py

  • アクセス

curl http://localhost:8082/server_request?param=automatic

手動計装

  • 依存ライブラリをインストール

pip install opentelemetry-exporter-otlp-proto-grpc

  • server_manual.py
from flask import Flask, request

from opentelemetry.instrumentation.wsgi import collect_request_attributes
from opentelemetry.propagate import extract
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
    BatchSpanProcessor,
    ConsoleSpanExporter,
)
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter

from opentelemetry.trace import (
    SpanKind,
    get_tracer_provider,
    set_tracer_provider,
)

app = Flask(__name__)

set_tracer_provider(TracerProvider())
tracer = get_tracer_provider().get_tracer(__name__)


# ConsoleSpanExporter と OTLPSpanExporter を TracerProvider に追加する
get_tracer_provider().add_span_processor(
    BatchSpanProcessor(ConsoleSpanExporter())
)
get_tracer_provider().add_span_processor(
    BatchSpanProcessor(OTLPSpanExporter())
)


@app.route("/server_request")
def server_request():
    with tracer.start_as_current_span(
        "server_request",
        context=extract(request.headers),
        kind=SpanKind.SERVER,
        attributes=collect_request_attributes(request.environ),
    ):
        print(request.args.get("param"))
        return "served"


if __name__ == "__main__":
    app.run(port=8082)
  • 実行

export OTEL_SERVICE_NAME="manual-instrument-service"

python server_manual.py

  • アクセス

curl http://localhost:8082/server_request?param=manual

プログラムによる計装

計装ライブラリ(たとえば opentelemetry-instrumentation-flask)を個別に使用することもできます。この方法には、カスタムオプションを利用できるという利点があります。ただし、この方法を選ぶと、opentelemetry-instrument でアプリケーションを起動したときの自動計装は使えなくなります。これら 2 つの方法は排他的です。

  • 依存ライブラリをインストール

pip install opentelemetry-exporter-otlp-proto-grpc

  • server_programmatic.py
from flask import Flask, request

from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
    BatchSpanProcessor,
    ConsoleSpanExporter,
)
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.trace import get_tracer_provider, set_tracer_provider

set_tracer_provider(TracerProvider())
get_tracer_provider().add_span_processor(
    BatchSpanProcessor(ConsoleSpanExporter())
)
get_tracer_provider().add_span_processor(
    BatchSpanProcessor(OTLPSpanExporter())
)

instrumentor = FlaskInstrumentor()

app = Flask(__name__)

instrumentor.instrument_app(app)
# instrumentor.instrument_app(app, excluded_urls="/server_request")


@app.route("/server_request")
def server_request():
    print(request.args.get("param"))
    return "served"


if __name__ == "__main__":
    app.run(port=8082)
  • 実行

export OTEL_SERVICE_NAME="programmatic-instrument-service"

python server_programmatic.py

  • アクセス

curl http://localhost:8082/server_request?param=programmatic

フィードバック

このページは役に立ちましたか?