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
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
-
Créez une application.
Dans Android Studio, créez une nouvelle application. Sélectionnez le modèle Basic Views Activity et cliquez sur Next.
Sélectionnez Java ou Kotlin comme langage, choisissez API 24: Android 7.0 (Nougat) comme version minimale du SDK, puis cliquez sur Finish.
-
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' -
Ajoutez la configuration réseau.
-
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> -
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
-
Créez une classe utilitaire OpenTelemetry.
Dans le même répertoire que MainActivity, créez un fichier nommé
OpenTelemetryUtilet 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")
-
-
Initialisez OpenTelemetry au démarrage de l'application.
Dans la méthode
onCreatedeMainActivity, 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
-
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() } } -
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) -
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() } -
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
-
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 -
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 . Sur la page Applications, cliquez sur le nom de l'application. Sur la page qui s'affiche, consultez les données de trace.
RemarqueSi l'icône
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
-
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
textPropagatorssur 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
textPropagatorssur le client.-
Si le serveur utilise le format B3 ou B3 Multi de Zipkin, vous devez définir les
textPropagatorssur le client surB3Propagator.// 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
textPropagatorssur le client surJaegerPropagator.// 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();
-
Importez okhttp3 et opentelemetry-okhttp.
Le plugin
opentelemetry-okhttp-3.0pour 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(); } }
-
-
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(); } } -
Sur la page Trace Explorer, affichez la trace de bout en bout entre le client et le serveur.
AsyncRequestZipkinServerest l'application Android etzipkin-demo-serverest l'application côté serveur.
