This topic describes how to import trace data from Android apps to Log Service by using Log Service SDK for Android.

Prerequisites

A trace instance is created. For more information, see Create a trace instance.
Note Log Service SDK for Android provides the sls-android-trace SDK module that is used to collect Android trace data. However, the sls-android-trace SDK module will no longer be updated or maintained. We recommend that you use OpenTelemetry SDK for Android to collect Android trace data. For more information, see Import trace data from Android apps to Log Service by using OpenTelemetry SDK for Android.

Step 1: Integrate the SDK

You can integrate the SDK in automatic or manual mode.

(Recommended) Integrate the SDK in automatic mode

Note Only the Maven repository is supported.
  1. Add the following settings to the build.gradle file of your project:
    buildscript {
        repositories {
            google()
            jcenter()
            mavenCentral()
        }
    }
    
    allprojects {
        repositories {
            google()
            jcenter()
            mavenCentral()
        }
    }
  2. Add the following settings to the build.gradle file of your app:
    android {
       defaultConfig {
           ndk {
               // Specify the architecture that is supported by .so libraries. If you do not specify an architecture, all architectures are supported by default. 
               abiFilters 'armeabi' //, 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
           }
       }
    }
    
    dependencies {
        // Use implementation in Gradle 3.0 or later. 
        implementation 'com.aliyun.openservices:aliyun-log-android-sdk:2.6.10'
        implementation 'com.aliyun.openservices:sls-android-core:1.0.5'
        implementation 'com.aliyun.openservices:sls-android-ot:1.0.6'
        implementation 'com.aliyun.openservices:sls-android-trace:1.0.3'
        // If you want to import trace data from the mobile side to the server side, add the following settings and use OkHttp3 as the network library: 
        implementation 'com.aliyun.openservices:sls-android-okhttp:1.0.1'
    }
    Note If you want to use other network libraries when you import trace data from the mobile side to the server side, submit a ticket

Integrate the SDK in manual mode

Download the latest versions of the following SDKs from the Maven repository:

Step 2: Configure permissions

Add the following permission declarations to the AndroidManifest.xml file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Step 3: Configure obfuscation

If your project code is packaged and obfuscated, you must add obfuscation settings. Package obfuscation rules require that all the class names and method names of the com.aliyun.sls.android package be retained. For example, add the following settings to the progaurd.cfg file:

-keep class com.aliyun.sls.android.producer.* { *; }
-keep interface com.aliyun.sls.android.producer.* { *; }
-keep class com.aliyun.sls.android.** { *; }

Step 4: Configure access

  1. Add an Application class to the $PROJECT/app/src/main/AndroidManifest.xml file.

    The following example shows how to add the MyApplication class:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.aliyun.sls.android.demo">
        ...
    
        <application
            android:icon="@mipmap/ic_launcher"
            ...
            android:name="com.aliyun.sls.android.demo.SLSDemoApplication"
            ...
            android:theme="@style/AppTheme">
                ...
        </application>
    </manifest>
    The integrated development environment (IDE) that is used automatically creates a class named MyApplication and adds the class to the current project based on the instructions sent by Android Studio.
  2. Add the following initialization code to the MyApplication.onCreate method:
    public class MyApplication extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            Credentials credentials = new Credentials();
            credentials.accessKeyId = "your access key id";
            credentials.accessKeySecret = "your access key secret";
            // If the preceding AccessKey pair is obtained by using Security Token Service (STS), you must configure securityToken. 
            credentials.securityToken = "your access security token";
    
            TracerCredentials tracerCredentials = credentials.createTraceCredentials();
            tracerCredentials.endpoint = "your trace endpoint";
            tracerCredentials.project = "your trace project";
            tracerCredentials.logstore = "your trace logstore";
    
            // Initialize the SLSAndroid class before you use the trace feature. 
            SLSAndroid.initialize(
                this,
                credentials,
                configuration -> {
                    // Enable the trace feature. 
                    configuration.enableTracer = true;
                }
            );
    
            // If you want to import trace data from the mobile side to the server side, you must specify a network library. For more information, see the following Step 3. 
        }
    
    }
    • Credentials
      The Credentials class defines authentication-related fields.
      FieldExampleDescription
      accessKeyIdLTAI****eYDwThe AccessKey ID that is used to access the required Log Service project. For more information, see AccessKey pair.
      accessKeySecretlrRq****GOVMThe AccessKey secret that is used to access the required Log Service project. For more information, see AccessKey pair.
      securityToken124f****a369The STS token that is used to access the required Log Service project. If you want to use STS to access the project, you must configure this field. For more information, see AssumeRole.
    • TracerCredentials

      The TracerCredentials class defines important configuration fields.

      FieldExampleDescription
      endpointhttps://cn-hangzhou.log.aliyuncs.comThe endpoint of the project that you specified when you created the trace instance. You must specify https:// as the prefix of the endpoint. For more information, see Public Log Service endpoints.
      Important Only public endpoints are supported.
      projectsls-ayasls-demoThe name of the project that you specified when you created the trace instance. For more information, see Create a trace instance.
      logstoreayasls-tracesThe name of the Logstore that is automatically created after you created the trace instance. The name is in the {instance}-traces format, where {instance} is the ID of the trace instance. For more information, see Create a trace instance.

      You must set this field to the name of the Logstore.

    • SLSAndroid

      The SLSAndroid class implements the interfaces that are used to configure user information and all parameters related to SDK initialization.

      TypeField or methodDescription
      Debugging methodsetLogLevelConfigures the log level for the SDK. Valid values: Log.VERBOSE, Log.DEBUG, Log.INFO, Log.WARN, and Log.ERROR.
      Credential updatesetCredentialsUpdates credential information. Hot update is supported.
      registerCredentialsCallbackCalls back the onCall method when span data is sent or failed to be sent.
      Configuration methodsetUserInfoUpdates user information.
      Configuration of extension parameterssetExtraAdds global extension parameters. The operation takes effect globally.
      removeExtraRemoves global extension parameters. The operation takes effect globally.
      clearExtraClears global extension parameters. The operation takes effect globally.
    • Configuration
      The Configuration class implements the interfaces that are used to configure additional parameters other than the parameters required for SDK initialization.
      TypeField or methodDescription
      Configuration methodenableTracerSpecifies whether to enable the trace feature.
      spanProviderSpecifies the resource and attribute information about a custom span.
      Environment configurationenvSpecifies the environment information about an app. Default value: default.

      We recommend that you set env to dev for a development environment and to prod for an online environment.

  3. Optional:Specify a network library.
    If you want to import trace data from the mobile side to the server side, you must use OkHttp3 as the network library. To specify OkHttp3 as the network library, use the following settings at the position where OkHttp is called in your project:
    // Pass in the client parameter. 
    // We recommend that you use a singleton class to implement the callFactory interface. 
    Call.Factory callFactory = OKHttp3Tracer.newCallFactory(client);
    
    // Generate a request. 
    Call call = callFactory.newCall(request);
  4. Optional:Call an STS operation to update credentials.accessKeyId, credentials.accessKeySecret, and credentials.securityToken.
    public class MyApplication extends Application {
    
        // You can initiate the call after you obtain the information such as the required AccessKey pair. 
        private void onUpdateSLS() {
            Credentials credentials = new Credentials();
    
            // (Optional) Update the AccessKey pair. 
            credentials.accessKeyId = "your access key id";
            credentials.accessKeySecret = "your access key secret";
            credentials.securityToken = "your access security token";
    
            // (Optional) Update information such as project information. 
            TracerCredentials tracerCredentials = credentials.createTraceCredentials();
            tracerCredentials.endpoint = "your trace endpoint";
            tracerCredentials.project = "your trace project";
            tracerCredentials.logstore = "your trace logstore";
    
            SLSAndroid.setCredentials(credentials);
        }
    
    }

Step 5: Create trace data

Create a single span

The SDK provides multiple methods to create a single span.

  • Use SpanBuilder
    • Code format
      SpanBuilder builder = Tracer.spanBuilder("span name");
      builder.setParent(span); // Specify the parent span. 
      builder.setStart(start); // Specify the start time. 
      builder.addAttribute(attribute); // Add attribute information. 
      builder.addResource(resource); // Add resource information. 
      builder.setActive(true/false); // Specify whether to keep the span active. 
      Span span = builder.build(); // Create and enable a span. 
      span.end(); // Stop the current span. 
    • Configuration example
      Span span = Tracer.spanBuilder("span with children (SpanBuilder)")
                      .addAttribute(Attribute.of("attr_key", "attr_value"))
                      .addResource(Resource.of("res_key", "res_value"))
                      .build();
      span.end();
  • Use startSpan
    • Code format
      Span span = Tracer.startSpan("span name"); // After you call the startSpan method, the span is started. 
      span.addAttribute(attribute); // Add attribute information. 
      span.addResource(resource); // Add resource information. 
      span.setStart(start); // Specify the start time. In most cases, you do not need to specify the start time. 
      span.setName("span name"); // Specify the name of the span. 
      span.setStatus(ERROR/OK/UNSET); // Specify the status of the span. Default value: UNSET. 
      span.setStatusMessage("span status message"); // Specify the description of the span status. 
      span.setParentSpanId("parent span id"); // Specify the ID of the parent span. 
      span.setService("service name"); // Specify the service name. Default value: Android. In most cases, you do not need to specify the service name. 
      span.setSpanId("span id"); // The custom ID of the span. In most cases, you do not need to specify the custom ID of the span. 
      span.setTraceId("trace id"); // The custom ID of the trace. In most cases, you do not need to specify the custom ID of the trace. 
      span.end(); // Stop the current span. 
    • Configuration example
      Span span = Tracer.startSpan("span 1");
              span.addAttribute(Attribute.of("attr_key", "attr_value"))
                  .addResource(Resource.of("res_key", "res_value"));
              span.end();
  • Use withinSpan

    If you use withinSpan to create a span, you do not need to configure the start or end settings for the span. In most cases, you need to add business code to Runnable. In addition, you cannot specify additional information about the span.

    • Code format
      Tracer.withinSpan("span name", new Runnable() {
          @Override
          public void run() {
              // The code block. 
          }
      });
    • Configuration example
      Tracer.withinSpan("span with block", new Runnable() {
          @Override
          public void run() {
              android.util.Log.d("debug", "print log from withinSpan");
          }
      });

Create a piece of trace data that contains multiple spans

A piece of trace data is associated with one or more spans. The SDK provides multiple methods to associate different spans with trace data.

  • Use SpanBuilder
    Span span = Tracer.spanBuilder("span with children (SpanBuilder)")
        .setActive(true) // Set the value to true. 
        .addAttribute(Attribute.of("attr_key", "attr_value"))
        .addResource(Resource.of("res_key", "res_value"))
        .build();
    
    Tracer.startSpan("child span 1 (SpanBuilder)").end();
    Tracer.startSpan("child span 2 (SpanBuilder)").end();
    
    span.end(); // Stop the trace. 
  • Use startSpan
    Span span = Tracer.startSpan("span with children", true); // Set the second parameter to true. 
    
    Tracer.startSpan("child span 1").end();
    Tracer.startSpan("child span 2").end();
    
    span.end(); // Stop the trace. 
  • Use withinSpan
    Tracer.withinSpan("span with func block", new Runnable() {
        @Override
        public void run() {
            Tracer.startSpan("span within func block 1").end();
    
            // The child trace. 
            Tracer.withinSpan("nested span with func block", new Runnable() {
                @Override
                public void run() {
                    Tracer.startSpan("nested span 1").end();
                    Tracer.startSpan("nested span 2").end();
                }
            });
    
            Tracer.startSpan("span within func block 2").end();
        }
    });

Add custom attribute and resource information

The SDK allows you to use SpanProvider to add custom information. If you use SpanProvider to add custom resource and attribute information, the information is added to all spans. This way, you can add business-related resource and attribute information to all spans at a time.

// The initialization process of the Credentials class is omitted. 
// ...

SLSAndroid.initialize(
    this,
    credentials,
    configuration -> {
        // Other settings of the configuration class are omitted. 
        // ...
        configuration.spanProvider = new ISpanProvider() {
            @Override
            public Resource provideResource() {
                return Resource.of("other_resource_key", "other_resource_value");
            }

            @Override
            public List<Attribute> provideAttribute() {
                List<Attribute> attributes = new ArrayList<>();
                attributes.add(Attribute.of("other_attribute_key", "other_attribute_value"));
                return attributes;
            }
        };
    }
);
// Other configuration processes are omitted. 
// ...

Parameters

  • Tracer
    Field or methodDescription
    spanBuilder(name)Creates a SpanBuider object.
    startSpan(name)Creates a span object.
    startSpan(name, active)Creates a span object and specifies whether to keep the span active. The value of active determines whether the span is active.
    withinSpan(name, runnable)Creates a span object, keeps the span active, and automatically runs the code block that is specified in runnable.
    withinSpan(name, active, runnable)Creates a span object, specifies whether to keep the span active, and automatically runs the code block that is specified in runnable. The value of active determines whether the span is active.
    withinSpan(name, active, parent, runnable)Creates a span object, specifies whether to keep the span active, specifies the parent span of the span, and automatically runs the code block that is specified in runnable. The value of active determines whether the span is active. The value of parent determines the parent span.
  • SpanBuilder
    Field or methodDescription
    SpanBuilder(name, processor, provider)Creates a SpanBuilder object, specifies the name of the span, and configures SpanProcessor and SpanProvider.

    We recommend that you do not directly call the method.

    setParent(parent)Specifies the parent span.
    setActive(active)Specifies whether to keep the span active.
    setKind(SpanKind)Specifies the type of the span. Valid values: INTERNAL, SERVER, CLIENT, PRODUCER, and CONSUMER. Default value: CLIENT.
    setStart(start)Specifies the start time of the span.
    addAttribute(attribute)Adds attribute information.
    addAttribute(attributes)Adds a set of attribute information.
    addResource(resource)Adds resource information.
  • Span
    Field or methodDescription
    setName(name)Specifies the name of the span.
    setKind(SpanKind)Specifies the type of the span. Valid values: INTERNAL, SERVER, CLIENT, PRODUCER, and CONSUMER. Default value: CLIENT.
    setTraceId(traceId)Specifies the ID of the trace. We recommend that you do not manually specify the ID.
    setSpanId(spanId)Specifies the ID of the span. We recommend that you do not manually specify the ID.
    setParentSpanId(spanId)Specifies the ID of the parent span.
    setStart(start)Specifies the start time of the span. We recommend that you do not manually specify the time.
    setEnd(end)Specifies the end time of the span.
    setDuration(duration)Specifies the duration of the span. We recommend that you do not manually specify the duration.
    setStatus(StatusCode)Specifies the status of the span. Valid values: ERROR, UNSET, and OK. Default value: UNSET.
    setStatusMessage(message)Specifies the description of the span status.
    setHost(host)Specifies the host.
    setService(service)Specifies the service name. Default value: Android.
    addAttribute(attribute)Adds attribute information.
    addAttribute(attribute...)Adds attribute information.
    addAttribute(attributes)Adds a set of attribute information.
    addResource(resource)Adds resource information.
    end()Stops the current span.
    isEnd()Checks whether the current span is stopped.
    toMap()Converts the span to a map object.
  • Resource
    Field or methodDescription
    getDefault()Returns the default resource object. For more information about the default resource information, see Resource object information.
    of(String key, Object value)Returns a resource object based on the key and value that are passed in.
    of(Pair<String, Object>... resources)Returns a resource object based on the key-value pair that is passed in.
    of(List<Attribute> attributes)Returns a resource object based on the attribute list that is passed in.
    add(String key, Object value)Adds key and value information to the current resource object.
    merge(Resource resource)Merges the resource object information that is passed in into the current resource object for implementation.

    Resource object information

    KeyValue
    sdk.languageAndroid
    host.nameAndroid
    device.model.identifierBuild.MODEL
    device.model.nameBuild.PRODUCT
    device.manufacturerBuild.MANUFACTURER
    os.typeLinux
    os.descriptionBuild.DISPLAY
    os.nameAndroid
    os.versionBuild.VERSION.RELEASE
    os.sdkBuild.VERSION.SDK
    host.nameBuild.HOST
    host.typeBuild.TYPE
    host.archBuild.CPU_ABI + (TextUtils.isEmpty(Build.CPU_ABI2) ? "" : (", " + Build.CPU_ABI2))
    sls.sdk.versionBuildConfig.VERSION_NAME
  • Attribute
    Field or methodDescription
    of(String key, boolean value)Returns an attribute object.
    of(String key, int value)Returns an attribute object.
    of(String key, long value)Returns an attribute object.
    of(String key, double value)Returns an attribute object.
    of(String key, String value)Returns an attribute object.
    of(final String key, final Object value)Returns an attribute object.
    of(Pair<String, Object>... kvs)Returns an attribute list object.

Additional information

If you set a span to active, the new spans in the current context are all automatically associated with the active span. Implementations: currentSpan.parentSpanID = activeSpan.spanID and currentSpan.traceID = activeSpan.traceID.
Note If the code of different services runs on the same thread, the thread is the current context. Only one span can be active in the same context.

What to do next