Todos os produtos
Search
Central de documentação

Managed Service for OpenTelemetry:Instrumentar um aplicativo Android com OpenTelemetry

Última atualização: Sep 08, 2026

Após instrumentar um aplicativo com OpenTelemetry e relatar dados de rastreamento para o Managed Service for OpenTelemetry, o Managed Service for OpenTelemetry passa a monitorar o aplicativo. É possível visualizar diversos dados de monitoramento, como topologia do aplicativo, traces, transações anômalas, transações lentas e análise de SQL. Este tópico descreve como instrumentar um aplicativo Android com OpenTelemetry e relatar dados.

Pré-requisitos

Obter um endpoint

New console

  1. Faça login no console do Managed Service for OpenTelemetry. No painel de navegação à esquerda, clique em Integration Center.

  2. Na página Integration Center, clique no cartão OpenTelemetry na seção Open Source Frameworks.

  3. No painel OpenTelemetry, clique na aba Start Integration e selecione a região onde deseja relatar os dados.

    Nota

    Ao acessar uma região pela primeira vez, os recursos são inicializados automaticamente nela.

  4. Configure os parâmetros Connection Type e Export Protocol e copie um endpoint.

    • Connection Type: Se o service estiver implantado no Alibaba Cloud e residir na região selecionada, recomendamos definir este parâmetro como Alibaba Cloud VPC Network. Caso contrário, defina como Public Network.

    • Export Protocol: Defina este parâmetro como HTTP (recomendado) ou gRPC, conforme o protocolo suportado pelo cliente.

    75.jpg

Old console

  1. Faça login no console do Managed Service for OpenTelemetry.

  2. No painel de navegação à esquerda, clique em Cluster Configurations. Na página exibida, clique na aba Access point information.

  3. Na barra de navegação superior, selecione a região onde deseja relatar os dados. Na seção Cluster Information, ative a opção Show Token.

  4. Defina o parâmetro Client como OpenTelemetry.

    Na coluna Related Information da tabela, copie um endpoint.ot旧版中.jpg

    Nota

    Se o aplicativo estiver implantado em um ambiente de produção do Alibaba Cloud, utilize um endpoint de virtual private cloud (VPC). Caso contrário, use um endpoint público.

Aplicativo de exemplo

Este tópico utiliza um aplicativo de exemplo para demonstrar como relatar dados de rastreamento de um aplicativo Android com OpenTelemetry. O procedimento se aplica a aplicativos escritos tanto em Java quanto em Kotlin.

Repositório de código de exemplo: opentelemetry-android-demo

Etapa 1: Criar e configurar o aplicativo

  1. Crie um aplicativo.

    1. No Android Studio, crie um novo aplicativo. Selecione o modelo Basic Views Activity e clique em Next.

    2. Escolha Java ou Kotlin como linguagem, selecione API 24: Android 7.0 (Nougat) como versão mínima do SDK e clique em Finish.

  2. Adicione as dependências.

    No arquivo build.gradle no nível do módulo ou do projeto, adicione as seguintes dependências.

    Este exemplo usa a versão 1.25.0 do OpenTelemetry SDK para Java. Para outras versões, consulte Opentelemetry Java Releases. Para o arquivo build.gradle completo, veja 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. Adicione a configuração de rede.

    1. No diretório app/res/xml, crie um arquivo chamado network_security_config.xml e adicione o seguinte conteúdo.

      <!-- 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. Modifique o arquivo app/src/main/AndroidManifest.xml. Adicione as duas linhas a seguir para conceder permissão de rede ao aplicativo.

      <!-- 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>

Etapa 2: Inicializar o OpenTelemetry

  1. Crie uma classe utilitária do OpenTelemetry.

    No mesmo diretório da MainActivity, crie um arquivo chamado OpenTelemetryUtil e adicione o seguinte conteúdo.

    • Opção 1: Relatar dados de rastreamento usando 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")
    • Opção 2: Relatar dados de rastreamento usando 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. Inicialize o OpenTelemetry quando o aplicativo for iniciado.

    No método onCreate da MainActivity, chame o método 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()
                ...
        }
    }

Etapa 3: Criar spans para rastrear dados

  1. Crie um span.

    No arquivo FirstFragment, crie um span chamado First Fragment Button onClick no manipulador de clique do botão.

    /**
     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. Defina atributos e eventos para o 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. Defina o status do 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. Crie um span aninhado.

    /**
     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()
        }
    }

Etapa 4: Executar o projeto e visualizar dados de rastreamento

  1. Execute o projeto e toque no botão na página do aplicativo de demonstração. No painel Running Devices do Android Studio, o emulador (por exemplo, Pixel 3a API 33) executa com sucesso o aplicativo AndroidJavaDemo e exibe a página padrão First Fragment.

    Verifique o Logcat para visualizar as informações de span exportadas pelo 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. A página de detalhes do trace exibe métricas resumidas (como duração, número de aplicativos, profundidade do trace e número total de spans) e uma lista de spans. O exemplo inclui uma hierarquia de spans de três níveis: o span raiz First Fragment Button onClick (duração: 6.835 ms), o span filho Parent Span (duração: 2.998 ms) e o span neto Child Span (duração: 0,14 ms). O nome do aplicativo para todos os spans é otel-android-demo. Isso mostra a distribuição de tempo e as relações pai-filho.

    Na página Applications do console do Managed Service for OpenTelemetry, clique em nome do aplicativo. Na página exibida, visualize os dados de rastreamento.

Etapa 5: Conectar traces de cliente e servidor

  1. Modifique o formato de propagação de contexto de trace nos cabeçalhos.

    • Protocolos diferentes usam cabeçalhos HTTP distintos para passar o contexto de trace aos services downstream. Por exemplo, o OpenTelemetry usa o formato W3C Trace Context por padrão, mas também suporta outros formatos. O Zipkin usa o formato B3 ou B3 Multi. Para mais informações sobre formatos de propagação de contexto, consulte Specify the context propagation format for OpenTelemetry.

    • Para conectar traces de cliente e servidor, configure o textPropagators no cliente para corresponder ao protocolo usado pelo servidor:

      • Se o servidor usar o formato W3C Trace Context padrão do OpenTelemetry, não é necessário configurar o textPropagators no cliente.

      • Caso o servidor utilize o formato B3 ou B3 Multi do Zipkin, defina o textPropagators no cliente como B3Propagator.

        // Set the B3 context propagation format.
        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
                .setTracerProvider(sdkTracerProvider)
                .setPropagators(ContextPropagators.create(TextMapPropagator.composite(
                        B3Propagator.injectingMultiHeaders(),
                        B3Propagator.injectingSingleHeader())))
                .buildAndRegisterGlobal();
      • Quando o servidor utilizar o protocolo Jaeger, defina o textPropagators no cliente como JaegerPropagator.

        // Set the Jaeger context propagation format.
        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
                .setTracerProvider(sdkTracerProvider)
                .setPropagators(ContextPropagators.create(TextMapPropagator.composite(
                        JaegerPropagator.getInstance())))
                .buildAndRegisterGlobal();
      • Também é possível definir múltiplos formatos de propagação de contexto 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. Importe okhttp3 e opentelemetry-okhttp.

    O plugin opentelemetry-okhttp-3.0 para OkHttp instrumenta automaticamente o aplicativo interceptando todas as requisições de rede enviadas via OkHttp3 e criando traces.

    • Adicione as duas dependências a seguir ao arquivo build.gradle.

      dependencies {
          ...
          implementation 'io.opentelemetry.instrumentation:opentelemetry-okhttp-3.0:2.3.0-alpha'
          implementation 'com.squareup.okhttp3:okhttp:4.12.0'
      }
    • Crie a classe 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. Use OkHttp3 para enviar uma requisição de rede ao servidor.

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

    Clique para visualizar o código completo da chamada assíncrona ao método 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. Na página Trace Explorer, visualize o trace ponta a ponta entre o cliente e o servidor.

    AsyncRequestZipkinServer representa o aplicativo Android e zipkin-demo-server é o aplicativo do lado do servidor.