Após instrumentar seu aplicativo e relatar dados de rastreamento para o Managed Service for OpenTelemetry, o serviço inicia o monitoramento. Em seguida, visualize dados como topologia do aplicativo, traces e análises de erros, transações lentas e SQL. Este tópico descreve como instrumentar um aplicativo Android com OpenTelemetry e relatar seus dados.
Pré-requisitos
Demonstração
Este tópico demonstra como usar o OpenTelemetry para relatar dados de rastreamento de um aplicativo Android. O método aplica-se tanto a aplicativos Java quanto Kotlin.
Repositório de código de exemplo: opentelemetry-android-demo
Etapa 1: Crie e configure um aplicativo
-
Crie um aplicativo.
No Android Studio, crie um novo aplicativo, selecione o modelo Basic Views Activity e clique em Next.
Escolha Java ou Kotlin como linguagem. Defina a versão mínima do SDK como API 24: Android 7.0 (Nougat) e clique em Finish.
-
Adicione as dependências.
No arquivo build.gradle no nível do módulo ou do projeto, adicione as seguintes dependências.
Este exemplo utiliza a versão 1.25.0 do OpenTelemetry Java SDK. Para outras versões, consulte Opentelemetry Java Releases. Para o código de exemplo completo do build.gradle, 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' -
Configure as definições de rede.
-
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 with the endpoint 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> -
Modifique o arquivo
app/src/main/AndroidManifest.xmle adicione as duas linhas a seguir para habilitar permissões de rede para o 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 enable network permissions. --> <uses-permission android:name="android.permission.INTERNET" /> <application ... <!-- Add the following line to apply the network configuration for the data reporting domain. --> android:networkSecurityConfig="@xml/network_security_config" ...> ... </application> </manifest>
-
Etapa 2: Inicializar o OpenTelemetry
-
Crie uma classe utilitária do OpenTelemetry.
No mesmo diretório da MainActivity, crie um arquivo OpenTelemetryUtil e adicione o seguinte conteúdo.
-
Opção 1: Relatar dados de rastreamento 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 logs or the command line. Comment out this line if not needed. // Replace <gRPC-endpoint> with the endpoint and <gRPC-token> with the authentication token that you obtained in the Prerequisites section. .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(); // Get 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 logs or the command line. Comment out this line if not needed. // Replace <gRPC-endpoint> with the endpoint and <gRPC-token> with the authentication token that you obtained in the Prerequisites section. .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() // Get a tracer to create spans. tracer = openTelemetry.getTracer("android-tracer", "1.0.0") -
Opção 2: Relatar dados de rastreamento 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 logs or the command line. Comment out this line if not needed. // Replace <HTTP-endpoint> with the endpoint that 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(); // Get 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 logs or the command line. Comment out this line if not needed. // Replace <HTTP-endpoint> with the endpoint that 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() // Get a tracer to create spans. tracer = openTelemetry.getTracer("android-tracer", "1.0.0")
-
-
Inicialize o OpenTelemetry ao iniciar o aplicativo.
Chame o método OpenTelemetryUtil.init() dentro do método
onCreateda MainActivity./** 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: Crie spans para rastrear traces
-
Crie um span.
No listener de eventos de clique do botão do arquivo
FirstFragment, crie um span chamado First Fragment Button onClick./** 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 traceId. 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 traceId. println(span.spanContext.traceId) // Get the spanId. println(span.spanContext.spanId) findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment) } } catch (t: Throwable) { span.setStatus(StatusCode.ERROR, "Something wrong in onClick") throw t } finally { span.end() } } -
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) -
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() } -
Crie spans aninhados.
/** 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 traceId. System.out.println(span.getSpanContext().getTraceId()); // Get the spanId. 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 traceId. System.out.println(span.getSpanContext().getTraceId()); // Get the spanId. 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 traceId. println(span.spanContext.traceId) // Get the spanId. 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 traceId. println(span.spanContext.traceId) // Get the spanId. println(span.spanContext.spanId) } } finally { span.end() } }
Etapa 4: Execute e visualize dados de rastreamento
-
Execute o projeto e clique no botão na página do aplicativo de demonstração. Após a execução no Android Studio, o aplicativo AndroidJavaDemo inicia no emulador e exibe a página padrão First Fragment. Isso confirma que o projeto está configurado corretamente e funcionando conforme o esperado.
Verifique os logs no Logcat. Visualize as informações de span exportadas pelo
LoggingSpanExporter.2023-xx-xx 15547-15547 System.out com.example.androidjavademo I 0c8b92db3d8b038ea3eedd0ec25a4abb 2023-xx-xx 15547-15547 System.out com.example.androidjavademo I 9ecd666297f5d8f6 2023-xx-xx 15547-15547 System.out com.example.androidjavademo I 0c8b92db3d8b038ea3eedd0ec25a4abb 2023-xx-xx 15547-15547 System.out com.example.androidjavademo I 7e7eaffe7bd23cb8 2023-xx-xx 15547-15547 System.out com.example.androidjavademo I 0c8b92db3d8b038ea3eedd0ec25a4abb 2023-xx-xx 15547-15547 System.out com.example.androidjavademo I 98ef17d962ecf4d1 2023-xx-xx 15547-15547 LoggingSpanExporter com.example.androidjavademo I 'Child Span' : 0c8b92db3d8b038ea3eedd0ec25a4abb 98ef17d962ecf4d1 INTERNAL [tracer: android-tracer:1.0.0] 2023-xx-xx 15547-15547 LoggingSpanExporter com.example.androidjavademo I 'Parent Span' : 0c8b92db3d8b038ea3eedd0ec25a4abb 7e7eaffe7bd23cb8 INTERNAL [tracer: android-tracer:1.0.0] 2023-xx-xx 15547-15547 LoggingSpanExporter com.example.androidjavademo I 'First Fragment Button onClick' : 0c8b92db3d8b038ea3eedd0ec25a4abb 9ecd666297f5d8f6 INTERNAL [tracer: android-tracer:1.0.0] 2023-xx-xx 15547-15585 EGL_emulation com.example.androidjavademo D app_time_stats: avg=460.19ms min=2.23ms max=3653.05ms count=8 -
Na página de detalhes do trace, o resumo mostra a duração, o número de aplicativos, a profundidade do trace e o número total de spans. A lista de spans exibe uma hierarquia de três níveis: o span raiz First Fragment Button onClick (6.835 ms), o span filho Parent Span (2.998 ms) e o span neto Child Span (0,14 ms). O nome do aplicativo para todos esses spans é
otel-android-demoe seus status estão normais.Na página Applications do console do Managed Service for OpenTelemetry, clique no nome do aplicativo. Na página exibida, visualize os dados de rastreamento.
Faça logon no console do ARMS. No painel de navegação à esquerda, escolha . Na página Applications, clique no nome do aplicativo. Na página exibida, visualize os dados de rastreamento.
NotaSe o ícone
aparecer na coluna Language, o aplicativo estará conectado ao Application Monitoring. Se um hífen (-) aparecer, o aplicativo estará conectado ao Managed Service for OpenTelemetry.
Etapa 5: Correlacionar traces de cliente e servidor
-
Modifique o formato de propagação de rastreamento no cabeçalho.
Protocolos diferentes utilizam cabeçalhos HTTP distintos para propagar o contexto de rastreamento. Por exemplo, o OpenTelemetry usa o formato W3C Trace Context por padrão, enquanto o Zipkin utiliza o formato B3 ou B3 Multi. Também é possível alterar o formato padrão. Para mais informações sobre formatos de propagação, consulte Especificar o formato para passar dados de rastreamento.
-
Com base no protocolo do aplicativo backend, defina o formato de propagação correspondente (
textPropagators) no cliente para correlacionar traces entre o cliente Android e o backend.Se o aplicativo backend utilizar o formato padrão W3C Trace Context do OpenTelemetry, não será necessário definir
textPropagatorsno cliente.-
Caso o aplicativo backend utilize o formato B3 ou B3 Multi do Zipkin, defina o
textPropagatorsdo cliente comoB3Propagator.// Set the B3 propagation format. OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() .setTracerProvider(sdkTracerProvider) .setPropagators(ContextPropagators.create(TextMapPropagator.composite( B3Propagator.injectingMultiHeaders(), B3Propagator.injectingSingleHeader()))) .buildAndRegisterGlobal(); -
Se o aplicativo backend utilizar o protocolo Jaeger, defina o
textPropagatorsdo cliente comoJaegerPropagator.// Set the Jaeger propagation format. OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() .setTracerProvider(sdkTracerProvider) .setPropagators(ContextPropagators.create(TextMapPropagator.composite( JaegerPropagator.getInstance()))) .buildAndRegisterGlobal(); -
Também é possível definir vários formatos de propagação de rastreamento simultaneamente.
// Use W3C Trace Context, B3, and Jaeger trace propagation formats simultaneously. OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() .setTracerProvider(sdkTracerProvider) .setPropagators(ContextPropagators.create(TextMapPropagator.composite( W3CTraceContextPropagator.getInstance(), B3Propagator.injectingMultiHeaders(), B3Propagator.injectingSingleHeader() JaegerPropagator.getInstance()))) .buildAndRegisterGlobal();
-
Importe okhttp3 e opentelemetry-okhttp.
O
opentelemetry-okhttp-3.0é um plugin de instrumentação automática do OpenTelemetry para OkHttp. Ele intercepta automaticamente todas as requisições de rede enviadas via OkHttp3 e cria traces.-
Adicione as duas dependências a seguir ao
build.gradle.dependencies { ... implementation 'io.opentelemetry.instrumentation:opentelemetry-okhttp-3.0:2.3.0-alpha' implementation 'com.squareup.okhttp3:okhttp:4.12.0' } -
Crie uma
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(); } }
-
-
Use OkHttp3 para enviar uma requisição de rede ao aplicativo backend.
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()) { // Make a network request, for example, using OkHttp. OkHttpConfiguration configuration = new OkHttpConfiguration(); Call.Factory tracedClient = configuration.createTracedClient(GlobalOpenTelemetry.get()); Request request = new Request.Builder().url("${Server_Address}").get().build(); Call call = tracedClient.newCall(request); try (Response response = call.execute()) { // Handle the response. String responseBody = response.body().string(); System.out.println(responseBody); } catch (IOException e) { // Handle errors. e.printStackTrace(); } } finally { span.end(); } } -
Na página Trace Explorer, visualize o rastreamento ponta a ponta correlacionado que conecta os aplicativos cliente e backend.
Neste exemplo,
AsyncRequestZipkinServeré o aplicativo Android ezipkin-demo-serveré o aplicativo backend.


