OpenTelemetry を使用してアプリケーションをインストルメント化し、トレースデータを Managed Service for OpenTelemetry にレポートすると、Managed Service for OpenTelemetry はアプリケーションの監視を開始します。アプリケーショントポロジー、トレース、異常トランザクション、低速トランザクション、SQL 分析などのアプリケーションの監視データを表示できます。このトピックでは、OpenTelemetry を使用して Android アプリケーションをインストルメント化し、Android アプリケーションのトレースデータをレポートする方法について説明します。
始める前に
サンプルコード
この例では、OpenTelemetry を使用して Android アプリケーションのトレースデータをレポートします。この例で使用されている方法は、Java または Kotlin で記述されたアプリケーションにも適用されます。
opentelemetry-android-demo からサンプルコードをダウンロードできます。
手順 1: アプリケーションを作成して設定する
アプリケーションを作成します。
Android Studio でアプリケーションを作成します。基本ビューアクティビティ を選択し、次へ をクリックします。

言語として Java または Kotlin を選択し、最小 SDK として API 24: Android 7.0 (Nougat) を選択して、完了 をクリックします。
依存関係を追加します。
モジュールまたはプロジェクトの build.gradle ファイルに次の依存関係を追加します。
この例では、OpenTelemetry SDK for Java のバージョンは 1.25.0 です。SDK のバージョンの詳細については、opentelemetry-java のリリース を参照してください。完全なサンプルコードについては、build.gradle を参照してください。
implementation platform('io.opentelemetry:opentelemetry-bom:1.25.0') implementation "io.opentelemetry:opentelemetry-api" implementation "io.opentelemetry:opentelemetry-context" implementation 'io.opentelemetry:opentelemetry-exporter-otlp' implementation 'io.opentelemetry:opentelemetry-exporter-logging' implementation 'io.opentelemetry:opentelemetry-extension-kotlin' implementation 'io.opentelemetry:opentelemetry-sdk' implementation 'io.opentelemetry:opentelemetry-semconv'ネットワーク設定を行います。
app/res/xmlディレクトリに network_security_config.xml という名前のファイルを作成し、次の内容をファイルに追加します。<!-- ファイルの完全な内容は、https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/res/xml/network_security_config.xml を参照してください。 --> <?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <!-- ドメイン名を、このトピックの「始める前に」セクションの手順に従って取得したエンドポイントに置き換えます。エンドポイントには、http://、ポート番号、または URL パスを含めることはできません。 --> <domain includeSubdomains="true">tracing-analysis-dc-hz.aliyuncs.com</domain> </domain-config> </network-security-config>アプリケーションがネットワークにアクセスできるように、
app/src/main/AndroidManifest.xmlファイルに次の内容を追加します。<!-- ファイルの完全な内容は、https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/AndroidManifest.xml を参照してください。 --> <?xml version="1.0" encoding="utf-8"?> <manifest ...> <!-- ネットワークアクセス許可を付与するには、次の行を追加します。 --> <uses-permission android:name="android.permission.INTERNET" /> <application ... <!-- データをレポートするドメイン名にネットワークを設定するには、次の行を追加します。 --> android:networkSecurityConfig="@xml/network_security_config" ...> ... </application> </manifest>
手順 2: OpenTelemetry を初期化する
OpenTelemetry ユーティリティクラスを作成します。
MainActivity ファイルがあるディレクトリに OpenTelemetryUtil ファイルを作成し、OpenTelemetryUtil ファイルに次の内容を追加します。
方法 1: gRPC 経由でトレースデータをレポートする
/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/java/com/example/androidjavademo/OpenTelemetryUtil.java */ Resource otelResource = Resource.getDefault().merge( Resource.create( Attributes.of( // <your-service-name> をアプリケーション名に置き換えます。 ResourceAttributes.SERVICE_NAME, "<your-service-name>", // <your-host-name> をホスト名に置き換えます。 ResourceAttributes.HOST_NAME, "<your-host-name>" ) ) ); SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) // オプション。ログまたはコマンドラインにトレースデータを表示します。必要ない場合は、この行をコメントアウトします。 // <gRPC-endpoint> を、このトピックの「始める前に」セクションの手順に従って取得したエンドポイントに置き換え、<gRPC-token> を認証トークンに置き換えます。 .addSpanProcessor(BatchSpanProcessor.builder( OtlpGrpcSpanExporter.builder() .setEndpoint("<gRPC-endpoint>") // 例: http://tracing-analysis-dc-hz.aliyuncs.com:8090 .addHeader("Authentication", "<gRPC-token>") // 例: xxxx@xxxx_xxxx@xxxx .build()).build() ) .setResource(otelResource) .build(); OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() .setTracerProvider(sdkTracerProvider) .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) .buildAndRegisterGlobal(); // スパンの作成に使用するトレーサーを取得します。 tracer = openTelemetry.getTracer("android-tracer", "1.0.0");/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/OpenTelemetryUtil.kt */ val otelResource = Resource.getDefault().merge( Resource.create( Attributes.of( ResourceAttributes.SERVICE_NAME, "<your-service-name>", // <your-service-name> をアプリケーション名に置き換えます。 ResourceAttributes.HOST_NAME, "<your-host-name>" // <your-host-name> をホスト名に置き換えます。 ) ) ) /* gRPC 経由でトレースデータをレポートします。 */ val sdkTracerProvider = SdkTracerProvider.builder() .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) // オプション。ログまたはコマンドラインにトレースデータを表示します。必要ない場合は、この行をコメントアウトします。 // <gRPC-endpoint> を、このトピックの「始める前に」セクションの手順に従って取得したエンドポイントに置き換え、<gRPC-token> を認証トークンに置き換えます。 .addSpanProcessor( BatchSpanProcessor.builder( OtlpGrpcSpanExporter.builder() .setEndpoint("<gRPC-endpoint>") // 例: http://tracing-analysis-dc-hz.aliyuncs.com:8090 .addHeader("Authentication", "<gRPC-token>") // 例: xxxx@xxxx_xxxx@xxxx .build() ).build() ) .setResource(otelResource) .build() val openTelemetry: OpenTelemetry = OpenTelemetrySdk.builder() .setTracerProvider(sdkTracerProvider) .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) .buildAndRegisterGlobal() // スパンの作成に使用するトレーサーを取得します。 tracer = openTelemetry.getTracer("android-tracer", "1.0.0")方法 2: HTTP 経由でトレースデータをレポートする
/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/java/com/example/androidjavademo/OpenTelemetryUtil.java */ Resource otelResource = Resource.getDefault().merge( Resource.create( Attributes.of( // <your-service-name> をアプリケーション名に置き換えます。 ResourceAttributes.SERVICE_NAME, "<your-service-name>", // <your-host-name> をホスト名に置き換えます。 ResourceAttributes.HOST_NAME, "<your-host-name>" ) ) ); SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) // オプション。ログまたはコマンドラインにトレースデータを表示します。必要ない場合は、この行をコメントアウトします。 // <HTTP-endpoint> を、このトピックの「始める前に」セクションの手順に従って取得したエンドポイントに置き換えます。 .addSpanProcessor(BatchSpanProcessor.builder( OtlpHttpSpanExporter.builder() .setEndpoint("<HTTP-endpoint>") // 例: http://tracing-analysis-dc-hz.aliyuncs.com/adapt_xxxx@xxxx_xxxx@xxxx/api/otlp/traces .build()).build() ) .setResource(otelResource) .build(); OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() .setTracerProvider(sdkTracerProvider) .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) .buildAndRegisterGlobal(); // スパンの作成に使用するトレーサーを取得します。 tracer = openTelemetry.getTracer("android-tracer", "1.0.0");/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/OpenTelemetryUtil.kt */ val otelResource = Resource.getDefault().merge( Resource.create( Attributes.of( ResourceAttributes.SERVICE_NAME, "<your-service-name>", // <your-service-name> をアプリケーション名に置き換えます。 ResourceAttributes.HOST_NAME, "<your-host-name>" // <your-host-name> をホスト名に置き換えます。 ) ) ) /* HTTP 経由でトレースデータをレポートします。 */ val sdkTracerProvider = SdkTracerProvider.builder() .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) // オプション。ログまたはコマンドラインにトレースデータを表示します。必要ない場合は、この行をコメントアウトします。 // <HTTP-endpoint> を、このトピックの「始める前に」セクションの手順に従って取得したエンドポイントに置き換えます。 .addSpanProcessor(BatchSpanProcessor.builder( OtlpHttpSpanExporter.builder() .setEndpoint("<HTTP-endpoint>") // 例: http://tracing-analysis-dc-hz.aliyuncs.com/adapt_xxxx@xxxx_xxxx@xxxx/api/otlp/traces .build()).build() ) .setResource(otelResource) .build(); val openTelemetry: OpenTelemetry = OpenTelemetrySdk.builder() .setTracerProvider(sdkTracerProvider) .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) .buildAndRegisterGlobal() // スパンの作成に使用するトレーサーを取得します。 tracer = openTelemetry.getTracer("android-tracer", "1.0.0")
アプリケーションの初期化中に OpenTelemetry を初期化します。
MainActivity クラスの onCreate メソッドで OpenTelemetryUtil.init() メソッドを呼び出します。
/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/java/com/example/androidjavademo/MainActivity.java */ ... public class MainActivity extends AppCompatActivity { ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // OpenTelemetry を初期化するには、次の行を追加します。 OpenTelemetryUtil.init(); ... } ... }/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/MainActivity.kt */ ... class MainActivity : AppCompatActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { WindowCompat.setDecorFitsSystemWindows(window, false) super.onCreate(savedInstanceState) // OpenTelemetry を初期化するには、次の行を追加します。 OpenTelemetryUtil.init() ... } }
手順 3: トレースデータを追跡するためのスパンを作成する
スパンを作成します。
FirstFragment ファイルのボタンタップイベントを監視するメソッドで、First Fragment Button onClick という名前のスパンを作成します。
/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/java/com/example/androidjavademo/FirstFragment.java */ public void onClick(View view) { // トレーサーを取得します。 Tracer tracer = OpenTelemetryUtil.getTracer(); // スパンを作成します。 Span span = tracer.spanBuilder("First Fragment Button onClick").startSpan(); try (Scope scope = span.makeCurrent()) { // トレース ID を取得します。 System.out.println(span.getSpanContext().getTraceId()); ... } finally { span.end(); } }/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/FirstFragment.kt */ binding.buttonFirst.setOnClickListener { // トレーサーを取得します。 val tracer: Tracer = OpenTelemetryUtil.getTracer()!! // スパンを作成します。 val span = tracer.spanBuilder("First Fragment Button onClick").startSpan() try { span.makeCurrent().use { scope -> // トレース ID を取得します。 println(span.spanContext.traceId) // スパン ID を取得します。 println(span.spanContext.spanId) findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment) } } catch (t: Throwable) { span.setStatus(StatusCode.ERROR, "Something wrong in onClick") throw t } finally { span.end() } }スパンの属性とイベントを設定します。
/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/java/com/example/androidjavademo/FirstFragment.java */ // 属性を設定します。 span.setAttribute("key", "value"); Attributes eventAttributes = Attributes.of( AttributeKey.stringKey("key"), "value", AttributeKey.longKey("result"), 0L); // イベントを追加します。 span.addEvent("onClick", eventAttributes);/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/FirstFragment.kt */ // 属性を設定します。 span.setAttribute("key", "value") val eventAttributes = Attributes.of( AttributeKey.stringKey("key"), "value", AttributeKey.longKey("result"), 0L ) // イベントを追加します。 span.addEvent("onClick", eventAttributes)スパンのステータスを設定します。
/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/java/com/example/androidjavademo/FirstFragment.java */ ... try (Scope scope = span.makeCurrent()) { ... } catch (Throwable t) { // スパンのステータスを設定します。 span.setStatus(StatusCode.ERROR, "Something wrong in onClick"); throw t; } finally { span.end(); }/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/FirstFragment.kt */ ... try { ... } catch (t: Throwable) { // スパンのステータスを設定します。 span.setStatus(StatusCode.ERROR, "Something wrong in onClick") throw t } finally { span.end() }ネストされたスパンを作成します。
/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/java/com/example/androidjavademo/FirstFragment.java */ public void parentSpan() { // トレーサーを取得します。 Tracer tracer = OpenTelemetryUtil.getTracer(); // スパンを作成します。 Span span = tracer.spanBuilder("Parent Span").startSpan(); try (Scope scope = span.makeCurrent()) { // トレース ID を取得します。 System.out.println(span.getSpanContext().getTraceId()); // スパン ID を取得します。 System.out.println(span.getSpanContext().getSpanId()); childSpan(); } finally { span.end(); } } public void childSpan() { // トレーサーを取得します。 Tracer tracer = OpenTelemetryUtil.getTracer(); // スパンを作成します。 Span span = tracer.spanBuilder("Child Span").startSpan(); try (Scope scope = span.makeCurrent()) { // トレース ID を取得します。 System.out.println(span.getSpanContext().getTraceId()); // スパン ID を取得します。 System.out.println(span.getSpanContext().getSpanId()); } finally { span.end(); } }/** 完全なコードを表示するには、次のリンクにアクセスしてください。 https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/FirstFragment.kt */ // ネストされたスパンを作成します。 fun parentSpan() { // トレーサーを取得します。 val tracer: Tracer = OpenTelemetryUtil.getTracer()!! // スパンを作成します。 val span = tracer.spanBuilder("Parent Span").startSpan() try { span.makeCurrent().use { scope -> // トレース ID を取得します。 println(span.spanContext.traceId) // スパン ID を取得します。 println(span.spanContext.spanId) childSpan() } } finally { span.end() } } // ネストされたスパンを作成します。 fun childSpan() { // トレーサーを取得します。 val tracer: Tracer = OpenTelemetryUtil.getTracer()!! // スパンを作成します。 val span = tracer.spanBuilder("Child Span").startSpan() try { span.makeCurrent().use { scope -> // トレース ID を取得します。 println(span.spanContext.traceId) // スパン ID を取得します。 println(span.spanContext.spanId) } } finally { span.end() } }
手順 4: プロジェクトを実行して、レポートされたトレースデータを表示する
プロジェクトを実行し、アプリケーションページでボタンのタップをシミュレートします。

LoggingSpanExporter を使用してエクスポートされたスパン情報を含むログを Logcat で表示できます。

ARMSコンソール にログインします。左側のナビゲーションペインで、 を選択します。アプリケーションページで、アプリケーションの名前をクリックします。表示されるページで、トレースデータを表示します。
説明
アイコンが言語列に表示されている場合は、アプリケーションはApplication Monitoringに接続されています。ハイフン (-) が表示されている場合は、アプリケーションはManaged Service for OpenTelemetryに接続されています。
手順 5: クライアントアプリケーションとサーバーアプリケーションを接続する
HTTP リクエストヘッダーでトレースデータを渡すためのフォーマットを変更します。
プロトコルが異なると、トレースコンテキストを渡すために使用される HTTP リクエストヘッダーも異なります。たとえば、OpenTelemetry はデフォルトで W3C Trace Context フォーマットを使用し、他のフォーマットもサポートしています。Zipkin は B3 または B3 Multi フォーマットを使用します。詳細については、トレースデータを渡すフォーマットを指定する を参照してください。
サーバーアプリケーションで使用されているプロトコルに基づいて、クライアントアプリケーションのトレースデータを渡すフォーマットを設定します。これにより、Android クライアントアプリケーションとサーバーアプリケーションを接続できます。
サーバーアプリケーションが OpenTelemetry の W3C Trace Context フォーマットを使用している場合は、クライアントアプリケーションの textPropagators パラメーターを指定する必要はありません。
サーバーアプリケーションが Zipkin の B3 または B3 Multi フォーマットを使用している場合は、クライアントアプリケーションの textPropagators パラメーターを B3Propagator に設定します。
// トレースデータを渡すために B3 フォーマットを指定します。 OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() .setTracerProvider(sdkTracerProvider) .setPropagators(ContextPropagators.create(TextMapPropagator.composite( B3Propagator.injectingMultiHeaders(), B3Propagator.injectingSingleHeader()))) .buildAndRegisterGlobal();サーバーアプリケーションが Jaeger プロトコルを使用している場合は、クライアントアプリケーションの textPropagators パラメーターを JaegerPropagator に設定する必要があります。
// トレースデータを渡すために Jaeger フォーマットを指定します。 OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() .setTracerProvider(sdkTracerProvider) .setPropagators(ContextPropagators.create(TextMapPropagator.composite( JaegerPropagator.getInstance()))) .buildAndRegisterGlobal();複数のフォーマットを指定してトレースデータを渡すこともできます。
// トレースデータを渡すために W3C Trace Context、B3、および Jaeger フォーマットを指定します。 // トレースデータを渡すために Jaeger フォーマットを指定します。 OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() .setTracerProvider(sdkTracerProvider) .setPropagators(ContextPropagators.create(TextMapPropagator.composite( W3CTraceContextPropagator.getInstance(), B3Propagator.injectingMultiHeaders(), B3Propagator.injectingSingleHeader() JaegerPropagator.getInstance()))) .buildAndRegisterGlobal();
OkHttp3 と opentelemetry-okhttp をインポートします。
opentelemetry-okhttp-3.0 は、OpenTelemetry が OkHttp フレームワーク向けに提供する自動インストルメンテーションプラグインです。OkHttp3 フレームワークを使用して送信されるすべてのネットワークリクエストを自動的にインターセプトし、トレースを作成します。
build.gradle ファイルに次の依存関係を追加します。
dependencies { ... implementation 'io.opentelemetry.instrumentation:opentelemetry-okhttp-3.0:2.3.0-alpha' implementation 'com.squareup.okhttp3:okhttp:4.12.0' }OkHttpConfiguration を作成します。
import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.okhttp.v3_0.OkHttpTelemetry; import okhttp3.Call; import okhttp3.OkHttpClient; public class OkHttpConfiguration { //標準の HTTP クライアント呼び出しを行うには、この Call.Factory 実装を使用します。 public Call.Factory createTracedClient(OpenTelemetry openTelemetry) { return OkHttpTelemetry.builder(openTelemetry).build().newCallFactory(createClient()); } //OkHttpClient の設定はここに記述します。 private OkHttpClient createClient() { return new OkHttpClient.Builder().build(); } }
OkHttp3 を使用してネットワークリクエストを送信し、サーバーアプリケーションにアクセスします。
private void callHttpService() throws IOException { Tracer tracer = OpenTelemetryUtil.getTracer(); // スパンを作成します。 Span span = tracer.spanBuilder("AsyncRequestZipkinServer").startSpan(); System.out.println("AsyncRequestZipkinServer TraceID: " + span.getSpanContext().getTraceId()); System.out.println("AsyncRequestZipkinServer SpanID: " + span.getSpanContext().getSpanId()); try (Scope scope = span.makeCurrent()) { // OkHttp を使用してネットワークリクエストを実行します。 OkHttpConfiguration configuration = new OkHttpConfiguration(); Call.Factory tracedClient = configuration.createTracedClient(GlobalOpenTelemetry.get()); Request request = new Request.Builder().url("${Server address}").get().build(); Call call = tracedClient.newCall(request); try (Response response = call.execute()) { // レスポンスを処理します。 String responseBody = response.body().string(); System.out.println(responseBody); } catch (IOException e) { // エラーを処理します。 e.printStackTrace(); } } finally { span.end(); } }トレースエクスプローラーページで、クライアントアプリケーションとサーバーアプリケーション間のトレースを表示します。
次の図は例を示しています。この例では、
AsyncRequestZipkinServerは Android アプリケーションで、zipkin-demo-serverはサーバーアプリケーションです。
