すべてのプロダクト
Search
ドキュメントセンター

Application Real-Time Monitoring Service:OpenTelemetry を使用した Android アプリケーションデータのレポート

最終更新日:Jun 26, 2026

アプリケーションを計装し、トレースデータを Managed Service for OpenTelemetryにレポートすると、Managed Service for OpenTelemetryがアプリケーションのモニタリングを開始します。その後、アプリケーションのトポロジー、トレース、エラー分析、低速トランザクション、SQL などのモニタリングデータを表示できます。このトピックでは、OpenTelemetry を使用して Android アプリケーションを計装し、そのデータをレポートする方法について説明します。

前提条件

エンドポイントの取得

  1. Application Real-Time Monitoring Service (ARMS) コンソールにログインします。左側のナビゲーションウィンドウで、[インテグレーションセンター] をクリックします。

  2. [インテグレーションセンター] ページで、[サーバーサイドアプリケーション] セクションの [OpenTelemetry] カードをクリックします。

  3. [OpenTelemetry] パネルで、[インテグレーションの開始] タブをクリックし、データをレポートするリージョンを選択します。

    説明

    初めてリージョンにアクセスすると、リソースが自動的に初期化されます。

  4. [接続タイプ][エクスポートプロトコル] パラメーターを設定し、エンドポイントをコピーします。

    • 接続タイプ:サービスが Alibaba Cloud にデプロイされており、選択したリージョンに存在する場合、このパラメーターを [Alibaba Cloud VPC ネットワーク] に設定することを推奨します。それ以外の場合は、このパラメーターを [パブリックネットワーク] に設定します。

    • エクスポートプロトコル:クライアントがサポートするプロトコルに基づいて、このパラメーターを [HTTP (推奨)] または [gRPC] に設定します。

    75.jpg

デモ

このトピックでは、OpenTelemetry を使用して Android アプリケーションからトレースデータをレポートする方法をデモします。この方法は、Java と Kotlin の両方のアプリケーションに適用されます。

サンプルコードリポジトリ:opentelemetry-android-demo

ステップ 1:アプリケーションの作成と設定

  1. アプリケーションの作成

    1. Android Studio で新しいアプリケーションを作成し、[Basic Views Activity] テンプレートを選択して、[Next] をクリックします。

    2. 言語として [Java] または [Kotlin] を選択します。最小 SDK バージョンを [API 24: Android 7.0 (Nougat)] に設定し、[Finish] をクリックします。

  2. 依存関係の追加

    モジュールレベルまたはプロジェクトレベルの build.gradle ファイルに、次の依存関係を追加します。

    この例では、OpenTelemetry Java SDK バージョン 1.25.0 を使用します。他のバージョンについては、「Opentelemetry Java Releases」をご参照ください。完全な build.gradle のサンプルコードについては、「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'
  3. ネットワーク設定の構成

    1. 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>
    2. app/src/main/AndroidManifest.xml ファイルを変更し、次の 2 行を追加してアプリケーションのネットワーク権限を有効にします。

      <!-- 完全なファイルの内容については、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 の初期化

  1. OpenTelemetry ユーティリティクラスの作成

    MainActivity と同じディレクトリに、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")
  2. アプリケーション起動時の OpenTelemetry の初期化

    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:スパンを作成してトレースを追跡

  1. スパンの作成

    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()) {
            // traceId を取得します。
            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 ->
                // traceId を取得します。
                println(span.spanContext.traceId)
                // spanId を取得します。
                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()
        }
    }
  2. スパンの属性とイベントの設定

    /**
     完全なコードについては、次のリンクをご参照ください:
     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)
  3. スパンのステータスの設定

    /**
     完全なコードについては、次のリンクをご参照ください:
     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()
    }
  4. ネストされたスパンの作成

    /**
     完全なコードについては、次のリンクをご参照ください:
     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()) {
            // traceId を取得します。
            System.out.println(span.getSpanContext().getTraceId());
            // spanId を取得します。
            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()) {
            // traceId を取得します。
            System.out.println(span.getSpanContext().getTraceId());
            // spanId を取得します。
            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 ->
                // traceId を取得します。
                println(span.spanContext.traceId)
                // spanId を取得します。
                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 ->
                // traceId を取得します。
                println(span.spanContext.traceId)
                // spanId を取得します。
                println(span.spanContext.spanId)
            }
        } finally {
            span.end()
        }
    }

ステップ 4:トレースデータの実行と表示

  1. プロジェクトを実行し、デモアプリケーションページのボタンをクリックします。Android Studio でプロジェクトを実行すると、エミュレーターで AndroidJavaDemo アプリケーションが起動し、デフォルトの First Fragment ページが表示され、プロジェクトが正しく設定され、期待どおりに実行されていることが確認されます。

    Logcat のログを確認します。LoggingSpanExporter によってエクスポートされたスパン情報を確認できます。

    2023-xx-xx 15547-15547 System.out                com.example.androidjavademo    I  0c8b92db3d8b038ea3eedd0ec25a4abb
    2023-xx-xx 15547-15547 System.out                com.example.androidjavademo    I  9ecd666297f5d8f6
    2023-xx-xx 15547-15547 System.out                com.example.androidjavademo    I  0c8b92db3d8b038ea3eedd0ec25a4abb
    2023-xx-xx 15547-15547 System.out                com.example.androidjavademo    I  7e7eaffe7bd23cb8
    2023-xx-xx 15547-15547 System.out                com.example.androidjavademo    I  0c8b92db3d8b038ea3eedd0ec25a4abb
    2023-xx-xx 15547-15547 System.out                com.example.androidjavademo    I  98ef17d962ecf4d1
    2023-xx-xx 15547-15547 LoggingSpanExporter       com.example.androidjavademo    I  'Child Span' : 0c8b92db3d8b038ea3eedd0ec25a4abb 98ef17d962ecf4d1 INTERNAL [tracer: android-tracer:1.0.0]
    2023-xx-xx 15547-15547 LoggingSpanExporter       com.example.androidjavademo    I  'Parent Span' : 0c8b92db3d8b038ea3eedd0ec25a4abb 7e7eaffe7bd23cb8 INTERNAL [tracer: android-tracer:1.0.0]
    2023-xx-xx 15547-15547 LoggingSpanExporter       com.example.androidjavademo    I  'First Fragment Button onClick' : 0c8b92db3d8b038ea3eedd0ec25a4abb 9ecd666297f5d8f6 INTERNAL [tracer: android-tracer:1.0.0]
    2023-xx-xx 15547-15585 EGL_emulation             com.example.androidjavademo    D  app_time_stats: avg=460.19ms min=2.23ms max=3653.05ms count=8
  2. ARMS コンソールにログインします。左側のナビゲーションウィンドウで、[アプリケーションモニタリング] > [アプリケーション] を選択します。[アプリケーション] ページで、アプリケーションの名前をクリックします。表示されたページで、トレースデータを表示します。

    説明

    [言語] 列に image アイコンが表示されている場合、アプリケーションはアプリケーションモニタリングに接続されています。 ハイフン ([-]) が表示されている場合、アプリケーションは OpenTelemetry 向けマネージドサービスに接続されています。

    トレース詳細ページでは、サマリーに持続時間、アプリケーション数、トレースの深さ、スパンの総数が表示されます。スパンリストには、ルートスパン First Fragment Button onClick (6.835 ms)、子スパン Parent Span (2.998 ms)、孫スパン Child Span (0.14 ms) の 3 階層が表示されます。これらのスパンのアプリケーション名はすべて otel-android-demo で、ステータスは正常です。

ステップ 5:クライアントとサーバーのトレースの関連付け

  1. ヘッダー内のトレース伝播フォーマットの変更

    • プロトコルによって、トレースコンテキストを伝播するために使用される HTTP ヘッダーが異なります。たとえば、OpenTelemetry はデフォルトで W3C Trace Context フォーマットを使用し、Zipkin は B3 または B3 Multi フォーマットを使用します。デフォルトのフォーマットを変更することもできます。伝播フォーマットの詳細については、「トレースデータを渡すフォーマットの指定」をご参照ください。

    • バックエンドアプリケーションのプロトコルに基づいて、クライアントで一致する伝播フォーマット (textPropagators) を設定し、Android クライアントとバックエンドアプリケーション間のトレースを関連付けます。

      • バックエンドアプリケーションがデフォルトの OpenTelemetry W3C Trace Context フォーマットを使用している場合、クライアントで textPropagators を設定する必要はありません。

      • バックエンドアプリケーションが Zipkin の B3 または B3 Multi フォーマットを使用している場合、クライアントの textPropagatorsB3Propagator に設定する必要があります。

        // B3 伝播フォーマットを設定します。
        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
                .setTracerProvider(sdkTracerProvider)
                .setPropagators(ContextPropagators.create(TextMapPropagator.composite(
                        B3Propagator.injectingMultiHeaders(),
                        B3Propagator.injectingSingleHeader())))
                .buildAndRegisterGlobal();
      • バックエンドアプリケーションが Jaeger プロトコルを使用している場合、クライアントの textPropagatorsJaegerPropagator に設定する必要があります。

        // Jaeger 伝播フォーマットを設定します。
        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
                .setTracerProvider(sdkTracerProvider)
                .setPropagators(ContextPropagators.create(TextMapPropagator.composite(
                        JaegerPropagator.getInstance())))
                .buildAndRegisterGlobal();
      • 複数のトレース伝播フォーマットを同時に設定することもできます。

        // W3C Trace Context、B3、Jaeger のトレース伝播フォーマットを同時に使用します。
        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
                .setTracerProvider(sdkTracerProvider)
                .setPropagators(ContextPropagators.create(TextMapPropagator.composite(
                        W3CTraceContextPropagator.getInstance(),
                        B3Propagator.injectingMultiHeaders(),
                        B3Propagator.injectingSingleHeader()
                        JaegerPropagator.getInstance())))
                .buildAndRegisterGlobal();
  2. okhttp3 と opentelemetry-okhttp のインポート

    opentelemetry-okhttp-3.0 は、OkHttp 用の OpenTelemetry 自動計装プラグインで、OkHttp3 を介して送信されるすべてのネットワークリクエストを自動的にインターセプトし、トレースを作成します。

    • build.gradle に次の 2 つの依存関係を追加します。

      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();
          }
      }
  3. 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();
        }
    }

    完全なコード

    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Looper;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import androidx.annotation.NonNull;
    import androidx.fragment.app.Fragment;
    import androidx.navigation.fragment.NavHostFragment;
    import com.example.androidjavademo.databinding.FragmentFirstBinding;
    import java.io.IOException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import io.opentelemetry.api.GlobalOpenTelemetry;
    import io.opentelemetry.api.common.AttributeKey;
    import io.opentelemetry.api.common.Attributes;
    import io.opentelemetry.api.trace.Span;
    import io.opentelemetry.api.trace.StatusCode;
    import io.opentelemetry.api.trace.Tracer;
    import io.opentelemetry.context.Scope;
    import okhttp3.Call;
    import okhttp3.Request;
    import okhttp3.Response;
    public class FirstFragment extends Fragment {
        private FragmentFirstBinding binding;
        @Override
        public View onCreateView(
                LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState
        ) {
            binding = FragmentFirstBinding.inflate(inflater, container, false);
            return binding.getRoot();
        }
        public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            binding.buttonFirst.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // トレーサーを取得します。
                    Tracer tracer = OpenTelemetryUtil.getTracer();
                    // スパンを作成します。
                    Span span = tracer.spanBuilder("First Fragment Button onClick").startSpan();
                    try (Scope scope = span.makeCurrent()) {
                        // traceId を取得します。
                        System.out.println(span.getSpanContext().getTraceId());
                        // spanId を取得します。
                        System.out.println(span.getSpanContext().getSpanId());
                        // 属性を設定します。
                        span.setAttribute("key", "value");
                        Attributes eventAttributes = Attributes.of(
                                AttributeKey.stringKey("key"), "value",
                                AttributeKey.longKey("result"), 0L);
                        // イベントを追加します。
                        span.addEvent("onClick", eventAttributes);
                        parentSpan();
                        NavHostFragment.findNavController(FirstFragment.this)
                                .navigate(R.id.action_FirstFragment_to_SecondFragment);
                    } catch (Throwable t) {
                        span.setStatus(StatusCode.ERROR, "Something wrong in onClick");
                        throw t;
                    } finally {
                        span.end();
                    }
                }
            });
        }
        @Override
        public void onDestroyView() {
            super.onDestroyView();
            binding = null;
        }
        public void parentSpan() {
            ExecutorService executorService = Executors.newSingleThreadExecutor();
            Handler handler = new Handler(Looper.getMainLooper());
            // トレーサーを取得します。
            Tracer tracer = OpenTelemetryUtil.getTracer();
            // スパンを作成します。
            Span span = tracer.spanBuilder("Parent Span").startSpan();
            try (Scope scope = span.makeCurrent()) {
                // traceId を取得します。
                System.out.println(span.getSpanContext().getTraceId());
                // spanId を取得します。
                System.out.println(span.getSpanContext().getSpanId());
                executorService.execute(new Runnable() {
                    @Override
                    public void run() {
                        // ネットワークリクエストを送信します。
                        try {
                            callHttpService();
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                        // 実行後、ハンドラを介してメインスレッドに切り替えて結果を処理します。
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                // UI の更新やその他のタスクを処理します。
                                childSpan();
                            }
                        });
                    }
                });
                executorService.shutdown();
            } finally {
                span.end();
            }
        }
        public void childSpan() {
            // トレーサーを取得します。
            Tracer tracer = OpenTelemetryUtil.getTracer();
            // スパンを作成します。
            Span span = tracer.spanBuilder("Child Span").startSpan();
            try (Scope scope = span.makeCurrent()) {
                // traceId を取得します。
                System.out.println(span.getSpanContext().getTraceId());
                // spanId を取得します。
                System.out.println(span.getSpanContext().getSpanId());
            } finally {
                span.end();
            }
        }
        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();
            }
        }
    }
  4. [トレースエクスプローラー] ページで、クライアントとバックエンドアプリケーションを接続する相関エンドツーエンドトレースを表示します。

    この例では、AsyncRequestZipkinServer が Android アプリケーションで、zipkin-demo-server がバックエンドアプリケーションです。