Android App in Kotlin Instrumentation
This document contains instructions on how to set up OpenTelemetry instrumentation in your Android applications built using Kotlin and view your application traces in SigNoz.
Requirements
Send traces directly to SigNoz cloud
You can test sample application for Kotlin
Step 1 : Instrument your application with OpenTelemetry
To configure your Kotlin application to send traces to OpenTelemetry you need to add the following dependencies to the build.gradle file of a module or project
For that, paste the following inside build.gradle
of your project.
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'
Step 2: Configure network settings
Create a file named network_security_config.xml
in the app/res/xml
directory and add the following content to the file
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">ingest.<region>.signoz.cloud</domain>
</domain-config>
</network-security-config>
Add the following content to the app/src/main/AndroidManifest.xml
file to allow the application to access the network
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<!-- Add the following line to grant network access permissions. -->
<uses-permission android:name="android.permission.INTERNET" />
<application
...
<!-- Add the following line to configure the network for the domain name to which you want to report data. -->
android:networkSecurityConfig="@xml/network_security_config"
...>
...
</application>
</manifest>
Create a file named OpentelemetryUtil.kt with the following content
package com.example.androidkotlindemo
import io.opentelemetry.api.OpenTelemetry
import io.opentelemetry.api.common.Attributes
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
import io.opentelemetry.context.propagation.ContextPropagators
import io.opentelemetry.exporter.logging.LoggingSpanExporter
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter
import io.opentelemetry.sdk.OpenTelemetrySdk
import io.opentelemetry.sdk.resources.Resource
import io.opentelemetry.sdk.trace.SdkTracerProvider
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes
class OpenTelemetryUtil {
companion object {
@JvmStatic
fun init() {
val otelResource = Resource.getDefault().merge(
Resource.create(
Attributes.of(
ResourceAttributes.SERVICE_NAME, "<service_name>",
ResourceAttributes.HOST_NAME, "<service_name>"
)
)
)
val sdkTracerProvider = SdkTracerProvider.builder()
.addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create()))
.addSpanProcessor(
BatchSpanProcessor.builder(
OtlpGrpcSpanExporter.builder()
.setEndpoint("ingest.<region>.signoz.cloud:443/v1/traces")
.addHeader("signoz-ingestion-key", "<your-ingestion-key>")
.build()
).build()
)
.setResource(otelResource)
.build()
val openTelemetry: OpenTelemetry = OpenTelemetrySdk.builder()
.setTracerProvider(sdkTracerProvider)
.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
.buildAndRegisterGlobal()
tracer = openTelemetry.getTracer("android-tracer", "1.0.0")
}
private var tracer: Tracer? = null
@JvmStatic
fun getTracer(): Tracer? {
return tracer
}
}
}
- Set the
<region>
to match your SigNoz Cloud region - Replace
<your-ingestion-key>
with your SigNoz ingestion key. <service_name>
is name of your service
Inside MainActivity.kt file, initialize the util
class MainActivity : AppCompatActivity() {
...
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
// Add the following line to initialize OpenTelemetry.
OpenTelemetryUtil.init()
...
}
}
Step 3: Send Telemetry data to SigNoz
Import these at top
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;
Use this function to create span
fun parentSpan() {
val tracer: Tracer = OpenTelemetryUtil.getTracer()!!
val span = tracer.spanBuilder("Parent Span").startSpan()
try {
span.makeCurrent().use { scope ->
println(span.spanContext.traceId)
println(span.spanContext.spanId)
childSpan()
}
} finally {
span.end()
}
}
fun childSpan() {
val tracer: Tracer = OpenTelemetryUtil.getTracer()!!
val span = tracer.spanBuilder("Child Span").startSpan()
try {
span.makeCurrent().use { scope ->
println(span.spanContext.traceId)
println(span.spanContext.spanId)
}
} finally {
span.end()
}
}
Step 4: Run app
Run your application from Android Studio to see the output & you can verify the sent span in SigNoz .