Overview
This document contains instructions on how to set up OpenTelemetry instrumentation in your Android mobile applications built using Java and view your application traces in SigNoz.
Prerequisites
- Java 8+ for Android.
- Android Studio with a working Android app project.
- Access to a SigNoz Cloud account or self-hosted SigNoz instance.
Send traces to SigNoz
Step 1: Add OpenTelemetry dependencies
Add these dependencies to your module 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
Create 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>Add network permissions and config in 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 in network_security_config.xml with your collector host (for Android emulators often 10.0.2.2). Set cleartextTrafficPermitted="false" when you use HTTPS.
Step 3: Initialize OpenTelemetry
Create OpentelemetryUtil.java:
package com.example.androidjavademo;
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;
public class OpenTelemetryUtil {
public static void init() {
Resource otelResource = Resource.getDefault().merge(
Resource.create(
Attributes.of(
ResourceAttributes.SERVICE_NAME, "<service_name>",
ResourceAttributes.SERVICE_VERSION, "<service_version>",
ResourceAttributes.HOST_NAME, "<service_name>"
)
)
);
SdkTracerProvider 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();
OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
.setTracerProvider(sdkTracerProvider)
.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
.buildAndRegisterGlobal();
tracer = openTelemetry.getTracer("android-tracer", "1.0.0");
}
private static Tracer tracer;
public static Tracer getTracer() {
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
Initialize OpenTelemetry in MainActivity.java:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OpenTelemetryUtil.init();
...
}
}Step 4: Send telemetry data
Import the APIs:
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;Create spans:
public void parentSpan() {
Tracer tracer = OpenTelemetryUtil.getTracer();
Span span = tracer.spanBuilder("Parent Span").startSpan();
try (Scope scope = span.makeCurrent()) {
childSpan();
} finally {
span.end();
}
}
public void childSpan() {
Tracer tracer = OpenTelemetryUtil.getTracer();
Span span = tracer.spanBuilder("Child Span").startSpan();
try (Scope scope = span.makeCurrent()) {
// 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 Android app are present with the attributes you set.
Troubleshooting
Still not seeing data in SigNoz? Work through Debug missing traces, logs, and metrics, which covers SDK diagnostics, Collector connectivity, and the common ingestion errors for all three signals.
- If spans do not show up, check that the
ingest.<region>.signoz.cloudor 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.