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 or higher.
- Android Studio with a working Android app project.
- Access to a SigNoz Cloud account or self-hosted SigNoz instance.
Send traces to SigNoz
Test the sample app for Java.
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/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.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;
}
}
Replace the placeholders:
<service_name>: logical name of your mobile service; this is what you will see in SigNoz.<region>: your SigNoz Cloud region, for exampleus,eu, orin.<your-ingestion-key>: ingestion key for your SigNoz Cloud organization.
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.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
- 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.