Todos os produtos
Search
Central de documentação

Application Real-Time Monitoring Service: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

  1. Faça login no console do Application Real-Time Monitoring Service (ARMS). No painel de navegação à esquerda, clique em Integration Center.

  2. Na página Integration Center, clique no cartão OpenTelemetry na seção Server-side Applications.

  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

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.

    Faça login no console do ARMS. No painel de navegação à esquerda, escolha Application Monitoring > Applications. Na página Applications, clique em nome do aplicativo. Na página exibida, visualize os dados de rastreamento.

    Nota

    Se o ícone image for exibido na coluna Language, o aplicativo está conectado ao Application Monitoring. Se um hífen (-) for exibido, o aplicativo está conectado ao Managed Service for OpenTelemetry.

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.