文档

通过OpenTelemetry上报Android应用数据

更新时间:

通过OpenTelemetry为应用埋点并上报链路数据至可观测链路 OpenTelemetry 版后,可观测链路 OpenTelemetry 版即可开始监控应用,您可以查看应用拓扑、调用链路、异常事务、慢事务和SQL分析等一系列监控数据。本文介绍如何使用OpenTelemetry为Android应用埋点并上报数据。

前提条件

获取接入点信息

  1. 登录可观测链路 OpenTelemetry 版控制台

  2. 在左侧导航栏单击集群配置,然后在右侧页面单击接入点信息页签。

  3. 在页面顶部选择需要接入的地域,然后在集群信息区域打开显示Token开关。

  4. 客户端采集工具区域单击OpenTelemetry

    在下方表格的相关信息列中,获取接入点信息。OT接入点信息

    说明

    如果应用部署于阿里云生产环境,则选择阿里云VPC网络接入点,否则选择公网接入点。

示例Demo

本文将通过具体示例介绍如何使用OpenTelemetry上报Android应用程序的链路数据,该方法同样适用于Java语言和Kotlin语言应用。

示例代码仓库地址:opentelemetry-android-demo

步骤一:创建并配置应用

  1. 创建应用。

    1. 在Android Studio中新建应用,选择Basic Views Activity应用模板,然后单击Nextimage..png

    2. 选择Java语言或者Kotlin语言,SDK支持的最小版本选择API 24: Android 7.0 (Nougat),然后单击Finish

  2. 添加依赖项。

    在Module或Project级别的build.gradle中,添加以下依赖。

    本例中使用的OpenTelemetry Java SDK版本为1.25.0,更多版本请参见Opentelemetry Java Releases。build.gradle完整示例代码请参见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. 添加网络配置。

    1. app/res/xml目录下创建network_security_config.xml文件并添加以下内容。

      <!-- 查看文件完整内容: 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">
          <!-- 请将下面的域名替换为您在前提条件中获取的接入点,请不要包含"http://"、端口号和URL路径 -->
          <domain includeSubdomains="true">tracing-analysis-dc-hz.aliyuncs.com</domain>
        </domain-config>
      </network-security-config>
    2. 修改 app/src/main/AndroidManifest.xml文件,添加以下两行内容为应用开启网络权限。

      <!-- 查看文件完整内容: https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/AndroidManifest.xml -->
      
      <?xml version="1.0" encoding="utf-8"?>
      <manifest ...>
        <!-- 添加下面一行内容,以开启网络权限 -->
        <uses-permission android:name="android.permission.INTERNET" />
      
        <application
          ...
          <!-- 添加下面一行内容,对要上报数据的域名进行网络配置 -->
          android:networkSecurityConfig="@xml/network_security_config"
          ...>
      
          ...
        </application>
      
      </manifest>

步骤二:OpenTelemetry初始化

  1. 创建OpenTelemetry工具类。

    在MainActivity所在的同级目录下创建OpenTelemetryUtil文件并添加以下内容。

    • 方法一:通过gRPC上报Trace数据

      /**
       请访问以下链接获取完整代码
       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(
                  // 请将<your-service-name>替换为您的应用名。
              	ResourceAttributes.SERVICE_NAME, "<your-service-name>",
                  // 请将<your-host-name>替换为您的主机名。
              	ResourceAttributes.HOST_NAME, "<your-host-name>"
              )
          )
      );
      
      SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
          .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) // 可选,将链路数据打印到日志/命令行,如不需要请注释这一行。
          // 请将<gRPC-endpoint>替换为从前提条件中获取的接入点,<gRPC-token>替换为鉴权Token。
          .addSpanProcessor(BatchSpanProcessor.builder(
              OtlpGrpcSpanExporter.builder()
                   .setEndpoint("<gRPC-endpoint>") // 例如:http://tracing-analysis-dc-hz.aliyuncs.com:8090
                   .addHeader("Authentication", "<gRPC-token>") // 例如:xxxx@xxxx_xxxx@xxxx
                   .build()).build()
          )
          .setResource(otelResource)
          .build();
      
      OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
          .setTracerProvider(sdkTracerProvider)
          .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
          .buildAndRegisterGlobal();
      
      // 获取tracer,用来创建Span。
      tracer = openTelemetry.getTracer("android-tracer", "1.0.0");
      /**
       请访问以下链接获取完整代码
       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>", // 请将<your-service-name>替换为您的应用名。
                  ResourceAttributes.HOST_NAME, "<your-host-name>"    // 请将<your-host-name>替换为您的主机名。
              )
          )
      )
      
      /* 使用gRPC协议上报链路数据 */
      val sdkTracerProvider = SdkTracerProvider.builder()
          .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) // 可选,将链路数据打印到日志/命令行,如不需要请注释这一行。
      	// 请将<gRPC-endpoint>替换为从前提条件中获取的接入点,<gRPC-token>替换为鉴权Token。
          .addSpanProcessor(
              BatchSpanProcessor.builder(
                  OtlpGrpcSpanExporter.builder()
                      .setEndpoint("<gRPC-endpoint>") // 例如:http://tracing-analysis-dc-hz.aliyuncs.com:8090
                      .addHeader("Authentication", "<gRPC-token>") // 例如:xxxx@xxxx_xxxx@xxxx
                      .build()
              ).build()
          )
          .setResource(otelResource)
          .build()
      
      val openTelemetry: OpenTelemetry = OpenTelemetrySdk.builder()
          .setTracerProvider(sdkTracerProvider)
          .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
          .buildAndRegisterGlobal()
      
      // 获取tracer,用来创建Span。
      tracer = openTelemetry.getTracer("android-tracer", "1.0.0")
    • 方法二:通过HTTP上报Trace数据

      /**
       请访问以下链接获取完整代码
       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(
                  // 请将<your-service-name>替换为您的应用名。
                  ResourceAttributes.SERVICE_NAME, "<your-service-name>",
                  // 请将<your-host-name>替换为您的主机名。
                  ResourceAttributes.HOST_NAME, "<your-host-name>"
              )
          )
      );
      
      SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
          .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) // 可选,将链路数据打印到日志/命令行,如不需要请注释这一行
          // 请将<HTTP-endpoint>替换为从前提条件中获取的接入点。
          .addSpanProcessor(BatchSpanProcessor.builder(
              OtlpHttpSpanExporter.builder()
                   .setEndpoint("<HTTP-endpoint>") // 例如 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();
      
      // 获取tracer,用来创建Span。
      tracer = openTelemetry.getTracer("android-tracer", "1.0.0");
      /**
       请访问以下链接获取完整代码
       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>", // 请将<your-service-name>替换为您的应用名。
                  ResourceAttributes.HOST_NAME, "<your-host-name>"    // 请将<your-host-name>替换为您的主机名。
              )
          )
      )
      
      /* 使用HTTP协议上报链路数据 */
      val sdkTracerProvider = SdkTracerProvider.builder()
          .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) // 可选,将链路数据打印到日志/命令行,如不需要请注释这一行。
      	// 请将<HTTP-endpoint>替换为从前提条件中获取的接入点。
          .addSpanProcessor(BatchSpanProcessor.builder(
              OtlpHttpSpanExporter.builder()
                  .setEndpoint("<HTTP-endpoint>") // 例如: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()
      
      // 获取tracer,用来创建Span。
      tracer = openTelemetry.getTracer("android-tracer", "1.0.0")
  2. 在应用程序初始化时对OpenTelemetry进行初始化。

    在MainActivity的onCreate方法中调用OpenTelemetryUtil.init()方法。

    /**
     请访问以下链接获取完整代码
     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);
            // 请添加这一行,对OpenTelemetry进行初始化。
            OpenTelemetryUtil.init();
            ...
        }
        ...
    }
    /**
     请访问以下链接获取完整代码
     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)
            // 请添加这一行,OpenTelemetry初始化。
            OpenTelemetryUtil.init()
    
                ...
        }
    }

步骤三:创建Span追踪链路数据

  1. 创建Span。

    在FirstFragment文件的按钮点击事件监听方法中,创建一个名为First Fragment Button onClick的Span。

    /**
     请访问以下链接获取完整代码
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/java/com/example/androidjavademo/FirstFragment.java
    */
    
    public void onClick(View view) {
        // 获取Tracer
        Tracer tracer = OpenTelemetryUtil.getTracer();
    	// 创建Span
        Span span = tracer.spanBuilder("First Fragment Button onClick").startSpan();
    	try (Scope scope = span.makeCurrent()) {
            // 获取traceId
            System.out.println(span.getSpanContext().getTraceId());
            ...
        } finally {
            span.end();
        }
    }
    /**
     请访问以下链接获取完整代码
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/FirstFragment.kt
    */
    
    binding.buttonFirst.setOnClickListener {
        // 获取Tracer
        val tracer: Tracer = OpenTelemetryUtil.getTracer()!!
        // 创建Span
        val span = tracer.spanBuilder("First Fragment Button onClick").startSpan()
        try {
            span.makeCurrent().use { scope ->
                // 获取traceId
                println(span.spanContext.traceId)
                // 获取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()
        }
    }
  2. 为Span设置属性和事件(Event)。

    /**
     请访问以下链接获取完整代码
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/java/com/example/androidjavademo/FirstFragment.java
    */
    
    // 设置属性
    span.setAttribute("key", "value");
    
    Attributes eventAttributes = Attributes.of(
        AttributeKey.stringKey("key"), "value",
        AttributeKey.longKey("result"), 0L);
    // 添加事件
    span.addEvent("onClick", eventAttributes);
    /**
     请访问以下链接获取完整代码
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/FirstFragment.kt
    */
    
    // 设置属性
    span.setAttribute("key", "value")
    val eventAttributes =
        Attributes.of(
            AttributeKey.stringKey("key"), "value",
            AttributeKey.longKey("result"), 0L
        )
    
    // 添加事件
    span.addEvent("onClick", eventAttributes)
  3. 为Span设置状态(Status)。

    /**
     请访问以下链接获取完整代码
     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) {
        // 设置Span状态
        span.setStatus(StatusCode.ERROR, "Something wrong in onClick");
        throw t;
    } finally {
        span.end(); 
    }
    /**
     请访问以下链接获取完整代码
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/FirstFragment.kt
    */
    
    ...
    try {
        ...
    } catch (t: Throwable) {
        // 为Span设置状态
        span.setStatus(StatusCode.ERROR, "Something wrong in onClick")
        throw t
    } finally {
        span.end()
    }
  4. 创建嵌套的Span。

    /**
     请访问以下链接获取完整代码
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidJavaDemo/app/src/main/java/com/example/androidjavademo/FirstFragment.java
    */
    
    public void parentSpan() {
        // 获取Tracer
        Tracer tracer = OpenTelemetryUtil.getTracer();
        // 创建Span
        Span span = tracer.spanBuilder("Parent Span").startSpan();
        try (Scope scope = span.makeCurrent()) {
            // 获取traceId
            System.out.println(span.getSpanContext().getTraceId());
            // 获取spanId
            System.out.println(span.getSpanContext().getSpanId());
            childSpan();
        } finally {
            span.end();
        }
    }
    
    public void childSpan() {
        // 获取Tracer
        Tracer tracer = OpenTelemetryUtil.getTracer();
        // 创建Span
        Span span = tracer.spanBuilder("Child Span").startSpan();
        try (Scope scope = span.makeCurrent()) {
            // 获取traceId
            System.out.println(span.getSpanContext().getTraceId());
            // 获取spanId
            System.out.println(span.getSpanContext().getSpanId());
        } finally {
            span.end();
        }
    }
    /**
     请访问以下链接获取完整代码
     https://github.com/alibabacloud-observability/android-demo/blob/master/AndroidKotlinDemo/app/src/main/java/com/example/androidkotlindemo/FirstFragment.kt
    */
    
    // 嵌套Span
    fun parentSpan() {
        // 获取Tracer
        val tracer: Tracer = OpenTelemetryUtil.getTracer()!!
        // 创建Span
        val span = tracer.spanBuilder("Parent Span").startSpan()
        try {
            span.makeCurrent().use { scope ->
                // 获取traceId
                println(span.spanContext.traceId)
                // 获取spanId
                println(span.spanContext.spanId)
                childSpan()
            }
        } finally {
            span.end()
        }
    }
    
    // 嵌套Span
    fun childSpan() {
        // 获取Tracer
        val tracer: Tracer = OpenTelemetryUtil.getTracer()!!
        // 创建Span
        val span = tracer.spanBuilder("Child Span").startSpan()
        try {
            span.makeCurrent().use { scope ->
                // 获取traceId
                println(span.spanContext.traceId)
                // 获取spanId
                println(span.spanContext.spanId)
            }
        } finally {
            span.end()
        }
    }

步骤四:运行项目查看上报的链路数据

  1. 运行项目,单击Demo应用页面中的按钮。image..png

    通过logcat查看日志,可以看到通过LoggingSpanExporter导出的Span信息。

    image..png

  2. 可观测链路 OpenTelemetry 版控制台应用列表页面选择目标应用,查看链路数据。

    image..png

  • 本页导读 (1)
文档反馈