Tous les produits
Search
Centre de documentation

Application Real-Time Monitoring Service:Instrumenter une application Android avec OpenTelemetry

Dernière mise à jour :Sep 08, 2026

Une fois l'application instrumentée avec OpenTelemetry et les données de trace envoyées à Managed Service for OpenTelemetry, Managed Service for OpenTelemetry commence à la surveiller. Vous pouvez consulter diverses données de surveillance, telles que la topologie des applications, les traces, les transactions anormales, les transactions lentes et l'analyse SQL. Cette rubrique décrit comment instrumenter une application Android avec OpenTelemetry et envoyer les données.

Prérequis

Obtenir un endpoint

  1. Connectez-vous à la console Application Real-Time Monitoring Service (ARMS). Dans le volet de navigation de gauche, cliquez sur Integration Center.

  2. Sur la page Integration Center, cliquez sur la carte OpenTelemetry dans la section Server-side Applications.

  3. Dans le panneau OpenTelemetry, cliquez sur l'onglet Start Integration, puis sélectionnez la région dans laquelle vous souhaitez envoyer les données.

    Remarque

    Lorsque vous accédez à une région pour la première fois, les ressources y sont automatiquement initialisées.

  4. Configurez les paramètres Connection Type et Export Protocol, puis copiez un endpoint.

    • Connection Type : si votre service est déployé sur Alibaba Cloud et se trouve dans la région sélectionnée, nous vous recommandons de définir ce paramètre sur Alibaba Cloud VPC Network. Sinon, définissez-le sur Public Network.

    • Export Protocol : définissez ce paramètre sur HTTP (recommandé) ou gRPC selon le protocole pris en charge par le client.

    75.jpg

Exemple d'application

Cette rubrique utilise une application exemple pour montrer comment envoyer les données de trace depuis une application Android avec OpenTelemetry. La procédure s'applique aux applications écrites en Java et en Kotlin.

Référentiel de code exemple : opentelemetry-android-demo

Étape 1 : Créer et configurer l'application

  1. Créez une application.

    1. Dans Android Studio, créez une nouvelle application. Sélectionnez le modèle Basic Views Activity et cliquez sur Next.

    2. Sélectionnez Java ou Kotlin comme langage, choisissez API 24: Android 7.0 (Nougat) comme version minimale du SDK, puis cliquez sur Finish.

  2. Ajoutez les dépendances.

    Dans le fichier build.gradle au niveau du module ou du projet, ajoutez les dépendances suivantes.

    Cet exemple utilise la version 1.25.0 du SDK OpenTelemetry pour Java. Pour les autres versions, consultez Opentelemetry Java Releases. Pour le fichier build.gradle complet, voir 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. Ajoutez la configuration réseau.

    1. Dans le répertoire app/res/xml, créez un fichier nommé network_security_config.xml et ajoutez le contenu suivant.

      <!-- For the complete file content, see 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">
          <!-- Replace the following domain name with the endpoint you obtained in the Prerequisites section. Do not include "http://", the port number, or the URL path. -->
          <domain includeSubdomains="true">tracing-analysis-dc-hz.aliyuncs.com</domain>
        </domain-config>
      </network-security-config>
    2. Modifiez le fichier app/src/main/AndroidManifest.xml. Ajoutez les deux lignes suivantes pour accorder à l'application l'autorisation d'accès au réseau.

      <!-- For the complete file content, see https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/AndroidManifest.xml -->
      <?xml version="1.0" encoding="utf-8"?>
      <manifest ...>
        <!-- Add the following line to grant network permission. -->
        <uses-permission android:name="android.permission.INTERNET" />
        <application
          ...
          <!-- Add the following line to configure network settings for the domain to which you want to report data. -->
          android:networkSecurityConfig="@xml/network_security_config"
          ...>
          ...
        </application>
      </manifest>

Étape 2 : Initialiser OpenTelemetry

  1. Créez une classe utilitaire OpenTelemetry.

    Dans le même répertoire que MainActivity, créez un fichier nommé OpenTelemetryUtil et ajoutez le contenu suivant.

    • Option 1 : Envoyer les données de trace via gRPC

      /**
       For the complete code, visit the following link:
       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(
                  // Replace <your-service-name> with your application name.
              	ResourceAttributes.SERVICE_NAME, "<your-service-name>",
                  // Replace <your-host-name> with your host name.
              	ResourceAttributes.HOST_NAME, "<your-host-name>"
              )
          )
      );
      SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
          .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) // Optional: Prints trace data to the console. Comment out this line to disable this feature.
          // Replace <gRPC-endpoint> with the endpoint you obtained in the Prerequisites section and replace <gRPC-token> with your authentication token.
          .addSpanProcessor(BatchSpanProcessor.builder(
              OtlpGrpcSpanExporter.builder()
                   .setEndpoint("<gRPC-endpoint>") // Example: http://tracing-analysis-dc-hz.aliyuncs.com:8090
                   .addHeader("Authentication", "<gRPC-token>") // Example: xxxx@xxxx_xxxx@xxxx
                   .build()).build()
          )
          .setResource(otelResource)
          .build();
      OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
          .setTracerProvider(sdkTracerProvider)
          .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
          .buildAndRegisterGlobal();
      // Obtain a tracer to create spans.
      tracer = openTelemetry.getTracer("android-tracer", "1.0.0");
      /**
       For the complete code, visit the following link:
       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>", // Replace <your-service-name> with your application name.
                  ResourceAttributes.HOST_NAME, "<your-host-name>"    // Replace <your-host-name> with your host name.
              )
          )
      )
      /* Report trace data over gRPC. */
      val sdkTracerProvider = SdkTracerProvider.builder()
          .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) // Optional: Prints trace data to the console. Comment out this line to disable this feature.
      	// Replace <gRPC-endpoint> with the endpoint you obtained in the Prerequisites section and replace <gRPC-token> with your authentication token.
          .addSpanProcessor(
              BatchSpanProcessor.builder(
                  OtlpGrpcSpanExporter.builder()
                      .setEndpoint("<gRPC-endpoint>") // Example: http://tracing-analysis-dc-hz.aliyuncs.com:8090
                      .addHeader("Authentication", "<gRPC-token>") // Example: xxxx@xxxx_xxxx@xxxx
                      .build()
              ).build()
          )
          .setResource(otelResource)
          .build()
      val openTelemetry: OpenTelemetry = OpenTelemetrySdk.builder()
          .setTracerProvider(sdkTracerProvider)
          .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
          .buildAndRegisterGlobal()
      // Obtain a tracer to create spans.
      tracer = openTelemetry.getTracer("android-tracer", "1.0.0")
    • Option 2 : Envoyer les données de trace via HTTP

      /**
       For the complete code, visit the following link:
       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(
                  // Replace <your-service-name> with your application name.
                  ResourceAttributes.SERVICE_NAME, "<your-service-name>",
                  // Replace <your-host-name> with your host name.
                  ResourceAttributes.HOST_NAME, "<your-host-name>"
              )
          )
      );
      SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
          .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) // Optional: Prints trace data to the console. Comment out this line to disable this feature.
          // Replace <HTTP-endpoint> with the endpoint you obtained in the Prerequisites section.
          .addSpanProcessor(BatchSpanProcessor.builder(
              OtlpHttpSpanExporter.builder()
                   .setEndpoint("<HTTP-endpoint>") // Example: 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();
      // Obtain a tracer to create spans.
      tracer = openTelemetry.getTracer("android-tracer", "1.0.0");
      /**
       For the complete code, visit the following link:
       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>", // Replace <your-service-name> with your application name.
                  ResourceAttributes.HOST_NAME, "<your-host-name>"    // Replace <your-host-name> with your host name.
              )
          )
      )
      /* Report trace data over HTTP. */
      val sdkTracerProvider = SdkTracerProvider.builder()
          .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) // Optional: Prints trace data to the console. Comment out this line to disable this feature.
      	// Replace <HTTP-endpoint> with the endpoint you obtained in the Prerequisites section.
          .addSpanProcessor(BatchSpanProcessor.builder(
              OtlpHttpSpanExporter.builder()
                  .setEndpoint("<HTTP-endpoint>") // Example: 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()
      // Obtain a tracer to create spans.
      tracer = openTelemetry.getTracer("android-tracer", "1.0.0")
  2. Initialisez OpenTelemetry au démarrage de l'application.

    Dans la méthode onCreate de MainActivity, appelez la méthode OpenTelemetryUtil.init().

    /**
     For the complete code, visit the following link:
     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);
            // Add this line to initialize OpenTelemetry.
            OpenTelemetryUtil.init();
            ...
        }
        ...
    }
    /**
     For the complete code, visit the following link:
     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)
            // Add this line to initialize OpenTelemetry.
            OpenTelemetryUtil.init()
                ...
        }
    }

Étape 3 : Créer des spans pour tracer les données

  1. Créez un span.

    Dans le fichier FirstFragment, créez un span nommé First Fragment Button onClick dans le gestionnaire de clics sur le bouton.

    /**
     For the complete code, visit the following link:
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/java/com/example/androidjavademo/FirstFragment.java
    */
    public void onClick(View view) {
        // Get the tracer.
        Tracer tracer = OpenTelemetryUtil.getTracer();
    	// Create a span.
        Span span = tracer.spanBuilder("First Fragment Button onClick").startSpan();
    	try (Scope scope = span.makeCurrent()) {
            // Get the trace ID.
            System.out.println(span.getSpanContext().getTraceId());
            ...
        } finally {
            span.end();
        }
    }
    /**
     For the complete code, visit the following link:
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/FirstFragment.kt
    */
    binding.buttonFirst.setOnClickListener {
        // Get the tracer.
        val tracer: Tracer = OpenTelemetryUtil.getTracer()!!
        // Create a span.
        val span = tracer.spanBuilder("First Fragment Button onClick").startSpan()
        try {
            span.makeCurrent().use { scope ->
                // Get the trace ID.
                println(span.spanContext.traceId)
                // Get the span 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()
        }
    }
  2. Définissez les attributs et les événements pour le span.

    /**
     For the complete code, visit the following link:
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/java/com/example/androidjavademo/FirstFragment.java
    */
    // Set an attribute.
    span.setAttribute("key", "value");
    Attributes eventAttributes = Attributes.of(
        AttributeKey.stringKey("key"), "value",
        AttributeKey.longKey("result"), 0L);
    // Add an event.
    span.addEvent("onClick", eventAttributes);
    /**
     For the complete code, visit the following link:
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/FirstFragment.kt
    */
    // Set an attribute.
    span.setAttribute("key", "value")
    val eventAttributes =
        Attributes.of(
            AttributeKey.stringKey("key"), "value",
            AttributeKey.longKey("result"), 0L
        )
    // Add an event.
    span.addEvent("onClick", eventAttributes)
  3. Définissez le statut du span.

    /**
     For the complete code, visit the following link:
     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) {
        // Set the span status.
        span.setStatus(StatusCode.ERROR, "Something wrong in onClick");
        throw t;
    } finally {
        span.end(); 
    }
    /**
     For the complete code, visit the following link:
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/FirstFragment.kt
    */
    ...
    try {
        ...
    } catch (t: Throwable) {
        // Set the span status.
        span.setStatus(StatusCode.ERROR, "Something wrong in onClick")
        throw t
    } finally {
        span.end()
    }
  4. Créez un span imbriqué.

    /**
     For the complete code, visit the following link:
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/java/com/example/androidjavademo/FirstFragment.java
    */
    public void parentSpan() {
        // Get the tracer.
        Tracer tracer = OpenTelemetryUtil.getTracer();
        // Create a span.
        Span span = tracer.spanBuilder("Parent Span").startSpan();
        try (Scope scope = span.makeCurrent()) {
            // Get the trace ID.
            System.out.println(span.getSpanContext().getTraceId());
            // Get the span ID.
            System.out.println(span.getSpanContext().getSpanId());
            childSpan();
        } finally {
            span.end();
        }
    }
    public void childSpan() {
        // Get the tracer.
        Tracer tracer = OpenTelemetryUtil.getTracer();
        // Create a span.
        Span span = tracer.spanBuilder("Child Span").startSpan();
        try (Scope scope = span.makeCurrent()) {
            // Get the trace ID.
            System.out.println(span.getSpanContext().getTraceId());
            // Get the span ID.
            System.out.println(span.getSpanContext().getSpanId());
        } finally {
            span.end();
        }
    }
    /**
     For the complete code, visit the following link:
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/FirstFragment.kt
    */
    // Nested span
    fun parentSpan() {
        // Get the tracer.
        val tracer: Tracer = OpenTelemetryUtil.getTracer()!!
        // Create a span.
        val span = tracer.spanBuilder("Parent Span").startSpan()
        try {
            span.makeCurrent().use { scope ->
                // Get the trace ID.
                println(span.spanContext.traceId)
                // Get the span ID.
                println(span.spanContext.spanId)
                childSpan()
            }
        } finally {
            span.end()
        }
    }
    // Nested span
    fun childSpan() {
        // Get the tracer.
        val tracer: Tracer = OpenTelemetryUtil.getTracer()!!
        // Create a span.
        val span = tracer.spanBuilder("Child Span").startSpan()
        try {
            span.makeCurrent().use { scope ->
                // Get the trace ID.
                println(span.spanContext.traceId)
                // Get the span ID.
                println(span.spanContext.spanId)
            }
        } finally {
            span.end()
        }
    }

Étape 4 : Exécuter le projet et afficher les données de trace

  1. Exécutez le projet et appuyez sur le bouton de la page de l'application de démonstration. Dans le panneau Running Devices d'Android Studio, l'émulateur (par exemple, Pixel 3a API 33) exécute correctement l'application AndroidJavaDemo et affiche la page par défaut First Fragment.

    Consultez Logcat pour afficher les informations de span exportées par LoggingSpanExporter.

    System.out  I  0c8b92db3d8b038ea3eedd0ec25a4abb
    System.out  I  9ecd666297f5d8f6
    System.out  I  0c8b92db3d8b038ea3eedd0ec25a4abb
    System.out  I  7e7eaffe7bd23cb8
    System.out  I  0c8b92db3d8b038ea3eedd0ec25a4abb
    System.out  I  98ef17d962ecf4d1
    LoggingSpanExporter  I  'Child Span' : 0c8b92db3d8b038ea3eedd0ec25a4abb 98ef17d962ecf4d1 INTERNAL [tracer: android-tracer:1.0.0]
    LoggingSpanExporter  I  'Parent Span' : 0c8b92db3d8b038ea3eedd0ec25a4abb 7e7eaffe7bd23cb8 INTERNAL [tracer: android-tracer:1.0.0]
    LoggingSpanExporter  I  'First Fragment Button onClick' : 0c8b92db3d8b038ea3eedd0ec25a4abb 9ecd666297f5d8f6 INTERNAL [tracer: android-tracer:1.0.0]
    EGL_emulation  D  app_time_stats: avg=460.19ms min=2.23ms max=3653.05ms count=8
  2. La page des détails de la trace affiche les métriques récapitulatives (telles que la durée, le nombre d'applications, la profondeur de la trace et le nombre total de spans) ainsi qu'une liste de spans. L'exemple inclut une hiérarchie de spans à trois niveaux : le span racine First Fragment Button onClick (durée : 6 835 ms), le span enfant Parent Span (durée : 2 998 ms) et le span petit-enfant Child Span (durée : 0,14 ms). Le nom de l'application pour tous les spans est otel-android-demo. Cela montre la répartition temporelle et les relations parent-enfant.

    Connectez-vous à la console ARMS. Dans le volet de navigation de gauche, choisissez Application Monitoring > Applications. Sur la page Applications, cliquez sur le nom de l'application. Sur la page qui s'affiche, consultez les données de trace.

    Remarque

    Si l'icône image s'affiche dans la colonne Language, l'application est connectée à Application Monitoring. Si un tiret (-) s'affiche, l'application est connectée à Managed Service for OpenTelemetry.

Étape 5 : Connecter les traces client et serveur

  1. Modifiez le format de propagation du contexte de trace dans les en-têtes.

    • Différents protocoles utilisent différents en-têtes HTTP pour transmettre le contexte de trace aux services en aval. Par exemple, OpenTelemetry utilise par défaut le format W3C Trace Context, mais prend également en charge d'autres formats. Zipkin utilise le format B3 ou B3 Multi. Pour plus d'informations sur les formats de propagation du contexte, consultez Spécifier le format de propagation du contexte pour OpenTelemetry.

    • Pour connecter les traces client et serveur, configurez les textPropagators sur le client afin qu'ils correspondent au protocole utilisé par le serveur :

      • Si le serveur utilise le format W3C Trace Context par défaut d'OpenTelemetry, vous n'avez pas besoin de configurer les textPropagators sur le client.

      • Si le serveur utilise le format B3 ou B3 Multi de Zipkin, vous devez définir les textPropagators sur le client sur B3Propagator.

        // Set the B3 context propagation format.
        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
                .setTracerProvider(sdkTracerProvider)
                .setPropagators(ContextPropagators.create(TextMapPropagator.composite(
                        B3Propagator.injectingMultiHeaders(),
                        B3Propagator.injectingSingleHeader())))
                .buildAndRegisterGlobal();
      • Si le serveur utilise le protocole Jaeger, vous devez définir les textPropagators sur le client sur JaegerPropagator.

        // Set the Jaeger context propagation format.
        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
                .setTracerProvider(sdkTracerProvider)
                .setPropagators(ContextPropagators.create(TextMapPropagator.composite(
                        JaegerPropagator.getInstance())))
                .buildAndRegisterGlobal();
      • Vous pouvez également définir plusieurs formats de propagation du contexte de trace.

        // Use W3C Trace Context, B3, and Jaeger as the trace context propagation formats.
        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
                .setTracerProvider(sdkTracerProvider)
                .setPropagators(ContextPropagators.create(TextMapPropagator.composite(
                        W3CTraceContextPropagator.getInstance(),
                        B3Propagator.injectingMultiHeaders(),
                        B3Propagator.injectingSingleHeader(),
                        JaegerPropagator.getInstance())))
                .buildAndRegisterGlobal();
  2. Importez okhttp3 et opentelemetry-okhttp.

    Le plugin opentelemetry-okhttp-3.0 pour OkHttp instrumente automatiquement votre application en interceptant toutes les requêtes réseau envoyées via OkHttp3 et en créant des traces.

    • Ajoutez les deux dépendances suivantes au fichier build.gradle.

      dependencies {
          ...
          implementation 'io.opentelemetry.instrumentation:opentelemetry-okhttp-3.0:2.3.0-alpha'
          implementation 'com.squareup.okhttp3:okhttp:4.12.0'
      }
    • Créez OkHttpConfiguration.

      import io.opentelemetry.api.OpenTelemetry;
      import io.opentelemetry.instrumentation.okhttp.v3_0.OkHttpTelemetry;
      import okhttp3.Call;
      import okhttp3.OkHttpClient;
      public class OkHttpConfiguration {
          //Use this Call.Factory implementation for making standard http client calls.
          public Call.Factory createTracedClient(OpenTelemetry openTelemetry) {
              return OkHttpTelemetry.builder(openTelemetry).build().newCallFactory(createClient());
          }
          //your configuration of the OkHttpClient goes here:
          private OkHttpClient createClient() {
              return new OkHttpClient.Builder().build();
          }
      }
  3. Utilisez OkHttp3 pour envoyer une requête réseau au serveur.

    private void callHttpService() throws IOException {
        Tracer tracer = OpenTelemetryUtil.getTracer();
        // Create a span.
        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()) {
            // Send a network request, for example, by using OkHttp.
            OkHttpConfiguration configuration = new OkHttpConfiguration();
            Call.Factory tracedClient = configuration.createTracedClient(GlobalOpenTelemetry.get());
            Request request = new Request.Builder().url("${ServerAddress}").get().build();
            Call call = tracedClient.newCall(request);
            try (Response response = call.execute()) {
                // Process the response.
                String responseBody = response.body().string();
                System.out.println(responseBody);
            } catch (IOException e) {
                // Handle the error.
                e.printStackTrace();
            }
        }  finally {
            span.end();
        }
    }

    Cliquez pour afficher le code complet de l'appel asynchrone de la méthode callHttpService.

    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) {
                    // Get the tracer.
                    Tracer tracer = OpenTelemetryUtil.getTracer();
                    // Create a span.
                    Span span = tracer.spanBuilder("First Fragment Button onClick").startSpan();
                    try (Scope scope = span.makeCurrent()) {
                        // Get the trace ID.
                        System.out.println(span.getSpanContext().getTraceId());
                        // Get the span ID.
                        System.out.println(span.getSpanContext().getSpanId());
                        // Set an attribute.
                        span.setAttribute("key", "value");
                        Attributes eventAttributes = Attributes.of(
                                AttributeKey.stringKey("key"), "value",
                                AttributeKey.longKey("result"), 0L);
                        // Add an event.
                        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());
            // Get the tracer.
            Tracer tracer = OpenTelemetryUtil.getTracer();
            // Create a span.
            Span span = tracer.spanBuilder("Parent Span").startSpan();
            try (Scope scope = span.makeCurrent()) {
                // Get the trace ID.
                System.out.println(span.getSpanContext().getTraceId());
                // Get the span ID.
                System.out.println(span.getSpanContext().getSpanId());
                executorService.execute(new Runnable() {
                    @Override
                    public void run() {
                        // Send a network request.
                        try {
                            callHttpService();
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                        // After the execution is complete, switch to the main thread by using the handler to process the result.
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                // Update the UI or perform other tasks.
                                childSpan();
                            }
                        });
                    }
                });
                executorService.shutdown();
            } finally {
                span.end();
            }
        }
        public void childSpan() {
            // Get the tracer.
            Tracer tracer = OpenTelemetryUtil.getTracer();
            // Create a span.
            Span span = tracer.spanBuilder("Child Span").startSpan();
            try (Scope scope = span.makeCurrent()) {
                // Get the trace ID.
                System.out.println(span.getSpanContext().getTraceId());
                // Get the span ID.
                System.out.println(span.getSpanContext().getSpanId());
            } finally {
                span.end();
            }
        }
        private void callHttpService() throws IOException {
            Tracer tracer = OpenTelemetryUtil.getTracer();
            // Create a span.
            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()) {
                // Send a network request, for example, by using OkHttp.
                OkHttpConfiguration configuration = new OkHttpConfiguration();
                Call.Factory tracedClient = configuration.createTracedClient(GlobalOpenTelemetry.get());
                Request request = new Request.Builder().url("${ServerAddress}").get().build();
                Call call = tracedClient.newCall(request);
                try (Response response = call.execute()) {
                    // Process the response.
                    String responseBody = response.body().string();
                    System.out.println(responseBody);
                } catch (IOException e) {
                    // Handle the error.
                    e.printStackTrace();
                }
            }  finally {
                span.end();
            }
        }
    }
  4. Sur la page Trace Explorer, affichez la trace de bout en bout entre le client et le serveur.

    AsyncRequestZipkinServer est l'application Android et zipkin-demo-server est l'application côté serveur.