🐕

PythonにOpenTelemetryを手動計装して直接バックエンドに送る

2024/06/19に公開

自動計装 & OpenTelemetry Collector経由がお勧めではありますが、色々な事情(自動計装が対応していないサーバーレスとか)でどうしても手動計装して直接送りたいんだ!という場合。

requirements.txt
opentelemetry-api
opentelemetry-sdk
opentelemetry-exporter-otlp

簡単なサンプル
注:各種変数は環境変数でもセットできる
https://opentelemetry-python.readthedocs.io/en/latest/exporter/otlp/otlp.html

app.py
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.semconv.resource import ResourceAttributes
from opentelemetry.sdk.trace.sampling import ALWAYS_ON

# Setup OTLP Parameter
resource = Resource.create({
    ResourceAttributes.SERVICE_NAME: "<サービス名>",
    ResourceAttributes.SERVICE_VERSION: "<バージョン>",
    ResourceAttributes.DEPLOYMENT_ENVIRONMENT: "<Env名>",
})
provider = TracerProvider(resource=resource, sampler=ALWAYS_ON)
processor = BatchSpanProcessor(OTLPSpanExporter(
    endpoint="<Observability Backend OTLP Endpoint>",
    headers={"<トークンとか>": "<値>"}
))

# Initiate Tracer
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("trace_test")

# サンプルトレースの作成
with tracer.start_as_current_span("parent_span") as parentspan:
    print("Hello, OpenTelemetry!")

    # 子スパンの作成
    with tracer.start_as_current_span("child_span") as childspan:
        childspan.set_attribute("name", "test")
        # あえて例外を発生させてみる
        try:
            print("Child span")
            unknown_span.set_attribute("name", "test") #存在しないspanを呼び出してみる
        except Exception as e:
            childspan.record_exception(e)
            childspan.set_status(trace.Status(trace.StatusCode.ERROR, str(e)))
            print(f"Exception caught: {e}")

Splunk Observability Cloudに送ってみました。
送信設定はこうです。

processor = BatchSpanProcessor(OTLPSpanExporter(
    endpoint="https://ingest.<REALM名>.signalfx.com/v2/trace/otlp",
    headers={"X-SF-Token": "<Ingest Token>"}
))

OK。

Python手動計装の詳細はこちら
https://opentelemetry.io/docs/languages/python/instrumentation/

Discussion