このトピックでは、OpenTelemetry SDK for Pythonを使用してPythonアプリケーションからSimple Log Serviceにトレースデータをインポートする方法について説明します。
前提条件
トレースインスタンスが作成されます。 詳細については、「トレースインスタンスの作成」をご参照ください。
Python開発環境がセットアップされました。 Pythonのバージョンは3.7以降です。
Python開発環境には、OpenTelemetry SDK for Pythonがインストールされています。
OpenTelemetry SDK for Pythonがインストールされていない場合は、次のコマンドを実行してSDKをインストールできます。
pip install opentelemetry-api==1.12.0 pip install opentelemetry-sdk==1.12.0 pip install opentelemetry-exporter-otlp==1.12.0
手順
OpenTelemetryプロバイダーを初期化します。
半自動モードでデータをインポートする条件が満たされているかどうかを確認します。
条件が満たされている場合、トレースデータを半自動モードでインポートできます。
トレースデータを半自動モードでインポートできないシナリオでは、手動モードでデータをインポートする必要があります。
条件が満たされていない場合は、手動モードでトレースデータをインポートできます。
手順1: OpenTelemetryプロバイダーの初期化
次のコードを使用して、OpenTelemetryプロバイダーを初期化できます。 コード内の変数を実際の値に置き換える必要があります。 変数の詳細については、「変数」をご参照ください。
# For Opentelemetry
import socket
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.trace.export import ConsoleSpanExporter
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
class OpenTelemetrySLSProvider(object):
def __init__(self, namespace="", service="", version="", endpoint='stdout',
project=None, instance=None, access_key_id=None, access_key_secret=None):
'''
:param namespace: Your service namespace
:param service: Your Application Service Name
:param version: Your Application Version
:param endpoint: console or https://sls_endpoint:10010
:param project: SLS project
:param instance: SLS OTEL InstanceId
:param access_key_id: Aliyun AccesskeyId
:param access_key_secret: Aliyun AccesskeySecret
'''
self.sls_otel_endpoint = endpoint
self.sls_otel_project = project
self.sls_otel_akid = access_key_id
self.sls_otel_aksecret = access_key_secret
self.sls_otel_instanceid = instance
self.local_mode = False
if endpoint == "stdout":
self.local_mode = True
self.resource = Resource(attributes={
"host.name": socket.gethostname(),
"service.name": service,
"service.namespace": namespace,
"service.version": version})
else:
self.resource = Resource(attributes={
"host.name": socket.gethostname(),
"service.namespace": namespace,
"service.name": service,
"service.version": version,
"sls.otel.project": self.sls_otel_project,
"sls.otel.akid": self.sls_otel_akid,
"sls.otel.aksecret": self.sls_otel_aksecret,
"sls.otel.instanceid": self.sls_otel_instanceid
})
def initTracer(self):
trace.set_tracer_provider(TracerProvider(resource=self.resource))
if self.local_mode:
trace.get_tracer_provider().add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
else:
otlp_exporter = OTLPSpanExporter(endpoint=self.sls_otel_endpoint)
trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(otlp_exporter))
# debug mode
#sls_ot_provider = OpenTelemetrySLSProvider(service="example", version="v0.1.0")
# write to sls
sls_ot_provider = OpenTelemetrySLSProvider(namespace="${service.namespace}", service="${service}", version="${version}",
endpoint='${endpoint}',
project="${project}",
instance="${instance}",
access_key_id="${access-key-id}",
access_key_secret="${access-key-secret}"
)
表 1. 変数
変数 | 説明 | 例 |
${service.nameスペース} | サービスが属する名前空間。 | order |
${service} | サービスの名前です。 ビジネス要件に基づいて値を指定します。 | payment |
${version} | サービスのバージョンです。 va.b.c形式でバージョンを指定することを推奨します。 | v0.1.2 |
${endpoint} | Simple Log Serviceプロジェクトのエンドポイント。 形式: https://${project}.${region-endpoint}:Port
説明
| https://test-project.cn-hangzhou.log.aliyuncs.com:10010 |
${project} | Simple Log Serviceプロジェクトの名前。 | test-project |
${instance} | トレースインスタンスのID。 詳細については、「トレースインスタンスの作成」をご参照ください。 | テストトレース |
${access-key-id} | Alibaba CloudアカウントのAccessKey ID。 Simple Log Serviceプロジェクトに対する書き込み権限のみを持つRAMユーザーのAccessKeyペアを使用することを推奨します。 AccessKey ペアは、AccessKey ID と AccessKey Secret で構成されます。 指定したプロジェクトの書き込み権限をRAMユーザーに付与する方法の詳細については、「カスタムポリシーを使用してRAMユーザーに権限を付与する」をご参照ください。 AccessKeyペアを取得する方法の詳細については、「AccessKeyペア」をご参照ください。 | なし |
${access-key-secret} | Alibaba CloudアカウントのAccessKeyシークレット。 Simple Log Serviceプロジェクトに対する書き込み権限のみを持つRAMユーザーのAccessKeyペアを使用することを推奨します。 | なし |
ステップ2: データのインポート
トレースデータは、半自動または手動モードでSimple Log Serviceにインポートできます。 OpenTelemetry SDK for Pythonは、さまざまなタイプのインストルメンテーションパッケージを提供し、共通フレームワークの半自動インストルメンテーションをサポートします。 いずれかのインストルメンテーションパッケージを使用する場合は、半自動モードでデータをインポートする必要があります。 詳細については、Instrumentationパッケージをご参照ください。
半自動計測
この例では、フラスコおよび要求計装パッケージが使用される。
インストルメンテーションパッケージをインストールします。
pip install requests pip install flask pip install opentelemetry-instrumentation-flask pip install opentelemetry-instrumentation-requests
コードを実行します。
次のコードの変数を実際の値に置き換えます。 詳細については、「変数」をご参照ください。
フラスコのための
# for flask import flask import requests # for Opentelemetry instrumentation import socket from opentelemetry.instrumentation.flask import FlaskInstrumentor from opentelemetry.instrumentation.requests import RequestsInstrumentor # For Opentelemetry pip install opentelemetry-instrumentation-requests from opentelemetry import trace from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( OTLPSpanExporter, ) from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.sdk.trace.export import ConsoleSpanExporter from opentelemetry.sdk.trace.export import SimpleSpanProcessor class OpenTelemetrySLSProvider(object): def __init__(self, namespace="", service="", version="", endpoint='stdout', project=None, instance=None, access_key_id=None, access_key_secret=None): ''' :param namespace: Your service namespace :param service: Your Application Service Name :param version: Your Application Version :param endpoint: console or https://sls_endpoint:10010 :param project: SLS project :param instance: SLS OTEL InstanceId :param access_key_id: Aliyun AccesskeyId :param access_key_secret: Aliyun AccesskeySecret ''' self.sls_otel_endpoint = endpoint self.sls_otel_project = project self.sls_otel_akid = access_key_id self.sls_otel_aksecret = access_key_secret self.sls_otel_instanceid = instance self.local_mode = False if endpoint == "stdout": self.local_mode = True self.resource = Resource(attributes={ "host.name": socket.gethostname(), "service.name": service, "service.namespace": namespace, "service.version": version}) else: self.resource = Resource(attributes={ "host.name": socket.gethostname(), "service.name": service, "service.version": version, "service.namespace": namespace, "sls.otel.project": self.sls_otel_project, "sls.otel.akid": self.sls_otel_akid, "sls.otel.aksecret": self.sls_otel_aksecret, "sls.otel.instanceid": self.sls_otel_instanceid }) def initTracer(self): trace.set_tracer_provider(TracerProvider(resource=self.resource)) if self.local_mode: trace.get_tracer_provider().add_span_processor( SimpleSpanProcessor(ConsoleSpanExporter())) else: otlp_exporter = OTLPSpanExporter(endpoint=self.sls_otel_endpoint) trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(otlp_exporter)) # write to sls sls_ot_provider = OpenTelemetrySLSProvider(namespace="${service.namespace}", service="${service}", version="${version}", endpoint='${endpoint}', project="${project}", instance="${instance}", access_key_id="${access-key-id}", access_key_secret="${access-key-secret}" ) # for console debug #sls_ot_provider = OpenTelemetrySLSProvider(service="example", version="v0.1.0") sls_ot_provider.initTracer() # flask init app = flask.Flask(__name__) # instrumentation init FlaskInstrumentor().instrument_app(app) RequestsInstrumentor().instrument() @app.route("/") def hello(): tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("request_server"): requests.get("http://www.taobao.com") return "hello" app.run(debug=True, port=5000)
サービスにアクセスしてトレースデータの生成をトリガーし、トレースデータをSimple Log serviceに送信します。
127.0.0.1:5000/hello
マニュアル
次のコードを実行します。 コード内の変数を実際の値に置き換えます。 コードの詳細については、「変数」をご参照ください。
# ot-manual-example.py import time # For Opentelemetry import socket from opentelemetry import trace from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.sdk.trace.export import ConsoleSpanExporter from opentelemetry.sdk.trace.export import SimpleSpanProcessor class OpenTelemetrySLSProvider(object): def __init__(self, namespace="", service="", version="", endpoint='stdout', project=None, instance=None, access_key_id=None, access_key_secret=None): ''' :param service: Your service namespace :param service: Your Application Service Name :param version: Your Application Version :param endpoint: console or https://sls_endpoint:10010 :param project: SLS project :param instance: SLS OTEL InstanceId :param access_key_id: Aliyun AccesskeyId :param access_key_secret: Aliyun AccesskeySecret ''' self.sls_otel_endpoint = endpoint self.sls_otel_project = project self.sls_otel_akid = access_key_id self.sls_otel_aksecret = access_key_secret self.sls_otel_instanceid = instance self.local_mode = False if endpoint == "stdout": self.local_mode = True self.resource = Resource(attributes={ "host.name": socket.gethostname(), "service.name": service, "service.namespace": namespace, "service.version": version}) else: self.resource = Resource(attributes={ "host.name": socket.gethostname(), "service.name": service, "service.version": version, "service.namespace": namespace, "sls.otel.project": self.sls_otel_project, "sls.otel.akid": self.sls_otel_akid, "sls.otel.aksecret": self.sls_otel_aksecret, "sls.otel.instanceid": self.sls_otel_instanceid }) def initTracer(self): trace.set_tracer_provider(TracerProvider(resource=self.resource)) if self.local_mode: trace.get_tracer_provider().add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter())) else: otlp_exporter = OTLPSpanExporter(endpoint=self.sls_otel_endpoint) trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(otlp_exporter)) # write to sls sls_ot_provider = OpenTelemetrySLSProvider(namespace="${service.namespace}", service="${service}", version="${version}", endpoint='${endpoint}', project="${project}", instance="${instance}", access_key_id="${access-key-id}", access_key_secret="${access-key-secret}" ) # for console debug #sls_ot_provider = OpenTelemetrySLSProvider(service="example", version="v0.1.0") # Trace Example sls_ot_provider.initTracer() tracer = trace.get_tracer(__name__) with tracer.start_as_current_span("foo"): print("Hello world!") labels = {"environment": "staging"} time.sleep(60)
よくある質問
OpenTelemetry SDK for Pythonが期待どおりにインストールされているかどうかを確認するにはどうすればよいですか?
次のサンプルコードを使用して、SDKが期待どおりにインストールされているかどうかを確認できます。 コードをtracing.pyファイルとして保存します。 次に、tracing.pyコマンドを実行します。 コマンド出力が期待どおりに返されると、OpenTelemetry SDK for Pythonの関連する依存関係がインストールされます。
# tracing-example-1.py
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
ConsoleSpanExporter,
SimpleSpanProcessor,
)
trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(
SimpleSpanProcessor(ConsoleSpanExporter())
)
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("foo"):
print("Hello world!")