SigNoz
Docs
PricingCustomers
Get Started - Free
Docs
IntroductionContributingMigrate from DatadogSigNoz API
OpenTelemetry
What is OpenTelemetryOpenTelemetry Collector GuideOpenTelemetry Demo
Community
Support
Slack
X
Launch Week
Changelog
Dashboard Templates
DevOps Wordle
Newsletter
KubeCon, Atlanta 2025
More
SigNoz vs DatadogSigNoz vs New RelicSigNoz vs GrafanaSigNoz vs Dynatrace
Careers
AboutTermsPrivacySecurity & Compliance
SigNoz Logo
SigNoz
All systems operational
HIPAASOC-2
SigNoz Cloud - This page applies to SigNoz Cloud editions.
Self-Host - This page applies to self-hosted SigNoz editions.

Android app in Kotlin instrumentation

Overview

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.

Prerequisites

  • Kotlin support in your Android app project.
  • Kotlin toolchain installed; see the Kotlin documentation.
  • Access to a SigNoz Cloud account or self-hosted SigNoz instance.

Send traces to SigNoz

Test the sample app for Kotlin.

Step 1: Add OpenTelemetry dependencies

Add these to your module build.gradle:

app/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")

Step 2: Configure network settings

app/src/main/res/xml/network_security_config.xml:

app/src/main/res/xml/network_security_config.xml
<?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>

app/src/main/AndroidManifest.xml:

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>

For self-hosted, replace the domain with your collector host (emulator often 10.0.2.2). Allow cleartext only when you use http://.

Step 3: Initialize OpenTelemetry

Create OpentelemetryUtil.kt:

app/src/main/java/com/example/androidkotlindemo/OpenTelemetryUtil.kt
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.SERVICE_VERSION, "<service_version>",
                        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
        }
    }
}

Verify these values:

  • <service_name>: logical name of your mobile service; this is what you will see in SigNoz.
  • <service_version> (optional): Your release version, image tag, or git SHA (e.g., 1.4.2, a01dbef8).
  • <region>: Your SigNoz Cloud region
  • <your-ingestion-key>: Your SigNoz ingestion key

Set service.version to a per-build value, not a static string. SigNoz detects a deployment each time this value changes. Common sources:

  • Bash / shell: service.version=$(git rev-parse --short HEAD)
  • GitHub Actions: service.version=${{ github.sha }}
  • GitLab CI: service.version=$CI_COMMIT_SHORT_SHA
  • Kubernetes: inject from your Helm chart image tag or CI variable

Using self-hosted SigNoz? Most steps are identical. Update the endpoint and remove the ingestion key header as shown in Cloud → Self-Hosted.

Initialize OpenTelemetry in MainActivity.kt:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        OpenTelemetryUtil.init()
        ...
    }
}

Step 4: Send telemetry data

Add the tracer imports where you create spans:

app/src/main/java/com/example/androidkotlindemo/MainActivity.kt
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.api.trace.Span
import io.opentelemetry.context.Scope

Create spans:

app/src/main/java/com/example/androidkotlindemo/MainActivity.kt
fun parentSpan() {
    val tracer: Tracer = OpenTelemetryUtil.getTracer()!!
    val span = tracer.spanBuilder("Parent Span").startSpan()
    try {
        span.makeCurrent().use {
            childSpan()
        }
    } finally {
        span.end()
    }
}

fun childSpan() {
    val tracer: Tracer = OpenTelemetryUtil.getTracer()!!
    val span = tracer.spanBuilder("Child Span").startSpan()
    try {
        span.makeCurrent().use {
            // add attributes/events as needed
        }
    } finally {
        span.end()
    }
}

Step 5: Run the app

Run your application from Android Studio.

Validate

  • In SigNoz, go to Traces Explorer and confirm that the traces for your service (for example <service_name>) are present.
  • Open a recent trace and verify that spans from your Kotlin Android app are present with the attributes you set.

Troubleshooting

  • If spans are missing, verify that the ingest.<region>.signoz.cloud or your self-hosted collector endpoint is reachable from the emulator/device and that the ingestion key (for Cloud) is correct.

Next steps

  • Explore your mobile traces in the Trace Explorer.
  • Create latency and error alerts for your service using Alert Management.

Last updated: May 14, 2026

Edit on GitHub

Was this page helpful?

Your response helps us improve this page.

Prev
Java
Next
Flutter
On this page
Overview
Prerequisites
Send traces to SigNoz
Step 1: Add OpenTelemetry dependencies
Step 2: Configure network settings
Step 3: Initialize OpenTelemetry
Step 4: Send telemetry data
Step 5: Run the app
Validate
Troubleshooting
Next steps

Is this page helpful?

Your response helps us improve this page.