Generated banner for Dd Android SDK V3 Upgrade
Generated logo for Dd Android SDK V3 Upgrade

Dd Android SDK V3 Upgrade

DatadogOfficialCreated by datadog-labs

  • Skill
  • Workflow
  • Software development
  • MIT
  • No issues found

From the author

Upgrade an Android application from Datadog's v2 mobile RUM SDK to the latest stable v3 SDK, including Core, RUM, Logs, Trace, OkHttp, and Session Replay breaking changes.
— the description by datadog-labs

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured, step-by-step procedure for upgrading Android projects from Datadog Mobile SDK v2 to v3. It covers critical breaking changes, including the removal of OpenTracing support, updates to RUM, Logs, Trace, and Session Replay APIs, and the transition to new builder-based configurations for OkHttp interceptors. The guide ensures that existing telemetry behavior is preserved while meeting new platform requirements, such as minimum SDK levels and Kotlin version constraints.

What it does

  • Guides the update of Datadog Android SDK dependencies to the latest stable v3 release.
  • Provides instructions for migrating from OpenTracing to either OpenTelemetry or the Datadog tracing API.
  • Details the transition of OkHttp interceptors from positional constructors to builder patterns.
  • Outlines mandatory configuration updates for custom endpoints and user identification.
  • Includes verification steps to ensure all telemetry features remain functional post-migration.

When to use it

  • When an Android application currently using Datadog SDK 2.x needs to be upgraded to 3.x.
  • When developers need to resolve breaking API changes introduced in the Datadog Android v3 SDK.
  • When migrating legacy OpenTracing instrumentation to modern OpenTelemetry standards within a Datadog-monitored app.

Advantages

  • Ensures a systematic and complete migration by covering all major SDK modules.
  • Helps maintain telemetry continuity by explicitly warning against removing existing instrumentation.
  • Provides clear mapping tables for API changes to reduce manual lookup time.
  • Includes specific guidance for handling complex dependencies like Jetpack Compose and OkHttp.

Usage examples

“How do I update my Android project from Datadog SDK v2 to v3?”
The agent will walk through the dependency updates, platform requirement checks, and specific code changes required for RUM, Logs, and Tracing.
“I need to migrate my OpenTracing implementation to v3. What are my options?”
The agent will present the two supported paths: migrating to OpenTelemetry (preferred) or using the transitional Datadog tracing API.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/datadog-labs/dd-android-sdk-v3-upgrade/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip dd-android-sdk-v3-upgrade.zip -d .agents/skills

Documentation by datadog-labs

Upgrade Datadog RUM Android SDK from v2 to v3

Use this skill when an Android project uses Datadog Mobile SDK 2.x and must be upgraded to the latest stable 3.x release. The v3 migration removes legacy OpenTracing support and updates APIs across the Android SDK modules.

This skill incorporates the Android v2-to-v3 migration guidance from DataDog/documentation, reviewed at commit a27f7562165b9058f8cd597b48473cc7ecbeda81 on 2026-09-25. Use the instructions below as the migration source of truth; consult the live documentation only when the project contains an API not covered here or the requested target is newer than this reviewed revision.

1. Establish the migration scope

Before editing, inspect the entire Android project for:

  • every com.datadoghq:dd-sdk-android-* dependency, including dependencies in version catalogs, convention plugins, and included builds;

  • every com.datadog.android and io.opentracing import;

  • calls that initialize Datadog or enable RUM, Logs, Trace, Crash Reporting, Session Replay, WebView tracking, or NDK crash reporting;

  • custom endpoints passed to useCustomEndpoint;

  • manual RUM resource calls and custom tracing;

  • DatadogInterceptor and TracingInterceptor construction;

  • the project's minSdk and Kotlin version.

Do not remove a Datadog feature, instrumentation path, or test merely to make the upgrade compile. Preserve the application's existing telemetry behavior.

2. Satisfy v3 platform requirements

  • Set the Android minimum API level to at least 23. If the application cannot raise minSdk to 23, stop and report that it cannot adopt SDK v3.

  • Use Kotlin 1.9 or newer.

  • If the project uses Jetpack Compose with Kotlin below 2.0, update Kotlin and composeOptions.kotlinCompilerExtensionVersion together using the official Compose-to-Kotlin compatibility map. Do not suppress the compatibility check.

  • For Kotlin 2.0 or newer, use the Compose Compiler Gradle plugin as directed by the compatibility documentation instead of choosing a version from the legacy compatibility table.

  • Remove direct OpenTracing dependencies after migrating all OpenTracing code.

  • If the preferred OpenTelemetry trace migration is used with minSdk below 26, enable core-library desugaring as required by OpenTelemetry Java.

3. Upgrade the SDK dependencies

Before editing dependencies, query the official DataDog/dd-sdk-android GitHub releases and select the highest stable semantic version matching 3.x.y. Ignore drafts, prereleases, release candidates, -SNAPSHOT versions, and releases from other major versions. The GitHub Releases API can be queried at:

https://api.github.com/repos/DataDog/dd-sdk-android/releases?per_page=100

Use each release object's tag_name, draft, and prerelease fields rather than assuming the first tag or the repository's development changelog is a stable release. If GitHub cannot be reached or the response cannot be parsed, use 3.14.1 as the fallback version and report that fallback explicitly.

Change every Datadog Android SDK artifact from 2.x to the selected concrete 3.x version. Follow the project's existing version-management convention and update the lockfile or version catalog where applicable.

Do not introduce moving versions such as 3.+ or latest.release, and do not leave a mixture of v2 and v3 Datadog artifacts in the resolved dependency graph.

If the application uses Jetpack Compose and enables Compose instrumentation in the Datadog Gradle plugin, add the v3 Compose integration at the same SDK version:

implementation("com.datadoghq:dd-sdk-android-compose:<datadog-v3-version>")

Leaving Compose instrumentation enabled without this artifact causes the Datadog compiler plugin to fail compilation with a missing-dependency error.

4. Migrate Core

The user ID passed to Datadog.setUserInfo is mandatory in v3. Replace null with the application's stable user identifier:

// v2
Datadog.setUserInfo(null, "Jane Smith", "[email protected]")

// v3
Datadog.setUserInfo("user123", "Jane Smith", "[email protected]")

Do not invent a production identity value. Reuse the application's actual user identifier or preserve its existing anonymous-user strategy with an appropriate non-null identifier.

5. Migrate RUM

Custom endpoint

RumConfiguration.Builder.useCustomEndpoint must receive the complete RUM upload URL rather than only a host:

Rum.enable(
    RumConfiguration.Builder("<application-id>")
        .useCustomEndpoint("https://example.com/rum/upload")
        .build()
)

Preserve the project's custom host and path.

Manual resources

Replace the string HTTP method argument of startResource with RumResourceMethod:

import com.datadog.android.rum.RumResourceMethod

GlobalRumMonitor.get().startResource(
    key = "resource-key",
    method = RumResourceMethod.GET,
    url = "https://example.com/api/resource",
    attributes = mapOf("source" to "manual")
)

Use the enum member corresponding to the original method; do not default every resource to GET.

Global monitor rename

Update the global RUM symbol:

v2v3
com.datadog.android.rum.GlobalRumcom.datadog.android.rum.GlobalRumMonitor

Use GlobalRumMonitor.get() to access the registered monitor. Do not replace it with RumMonitor.get(); RumMonitor does not provide that v3 accessor.

Optional attributes

In v3, the attributes: Map<String, Any?> parameter is optional for these APIs:

  • RumMonitor.addAction

  • RumMonitor.startAction

  • RumMonitor.stopResource

  • RumMonitor.addError

  • RumMonitor.addErrorWithStacktrace

  • AdvancedNetworkRumMonitor.stopResource

Existing attribute maps remain valid. Remove redundant empty maps only when it improves the migrated code without changing behavior.

6. Migrate Logs and crash Error Tracking

Logs no longer reports fatal errors on its own. If the existing application expects crashes to appear in Error Tracking, keep RUM enabled and enable Crash Reporting explicitly in addition to Logs.

LogsConfiguration.Builder.useCustomEndpoint must receive the complete Logs upload URL:

Logs.enable(
    LogsConfiguration.Builder()
        .useCustomEndpoint("https://example.com/logs/upload")
        .build()
)

Preserve all products that were enabled before the migration. In particular, do not remove Rum.enable(...) or Logs.enable(...) to resolve compilation failures.

7. Migrate Trace

TraceConfiguration.Builder.useCustomEndpoint must receive the complete Trace upload URL:

Trace.enable(
    TraceConfiguration.Builder()
        .useCustomEndpoint("https://example.com/trace/upload")
        .build()
)

SDK v3 removes OpenTracing. Choose one of the following migrations based on the project's constraints.

Preferred: migrate to OpenTelemetry

Add the v3 OpenTelemetry bridge using the same SDK version as the other Datadog artifacts:

implementation("com.datadoghq:dd-sdk-android-trace-otel:<datadog-v3-version>")

For the simple case, replace global tracer registration:

// v2 OpenTracing
GlobalTracer.registerIfAbsent(
    AndroidTracer.Builder()
        .setService(BuildConfig.APPLICATION_ID)
        .build()
)

// v3 OpenTelemetry
GlobalOpenTelemetry.set(
    DatadogOpenTelemetry(BuildConfig.APPLICATION_ID)
)

DatadogOpenTelemetry is a convenience wrapper. Its constructor accepts only the service name; do not pass an SdkCore to it. When the v2 tracer has custom builder configuration, such as an SDK instance or partial-flush threshold, build the provider directly instead:

val tracerProvider = OtelTracerProvider.Builder(sdkCore)
    .setService(BuildConfig.APPLICATION_ID)
    .setPartialFlushThreshold(4)
    .build()

GlobalOpenTelemetry.set(object : OpenTelemetry {
    override fun getTracerProvider(): TracerProvider = tracerProvider

    override fun getPropagators(): ContextPropagators = ContextPropagators.noop()
})

val tracer = tracerProvider.get("SampleApplicationTracer")

OtelTracerProvider.Builder(...).build() returns a TracerProvider, not an OpenTelemetry instance. Do not pass the provider directly to GlobalOpenTelemetry.set(...); wrap it as shown above.

setPartialFlushThreshold belongs to OtelTracerProvider.Builder, not to the built OtelTracerProvider. Configure it before calling build(); do not cast openTelemetry.tracerProvider and attempt to mutate it afterward.

Replace manual tracing with the OpenTelemetry API:

val tracer: Tracer = GlobalOpenTelemetry
    .get()
    .getTracer("SampleApplicationTracer")

val span = tracer
    .spanBuilder("Executing operation")
    .startSpan()

// Instrumented operation

span.end()

Apply these type and API mappings:

v2 OpenTracingv3 OpenTelemetry
io.opentracing.util.GlobalTracerio.opentelemetry.api.GlobalOpenTelemetry
com.datadog.android.trace.AndroidTracerio.opentelemetry.api.trace.Tracer
io.opentracing.Spanio.opentelemetry.api.trace.Span
io.opentracing.Scopeio.opentelemetry.context.Scope
io.opentracing.SpanContextio.opentelemetry.api.trace.SpanContext
AndroidTracer.Builder(...).setPartialFlushThreshold(Int)OtelTracerProvider.Builder(...).setPartialFlushThreshold(Int)
SpanContext.toTraceId()SpanContext.traceId (Kotlin) / SpanContext.getTraceId() (Java)
Span.setError()Span.recordException()
Transitional fallback: migrate to the Datadog tracing API

Use this path only when the project cannot enable the desugaring required by OpenTelemetry. It exists to ease migration and may be removed in a future major SDK version.

Replace global tracer registration:

// v2 OpenTracing
GlobalTracer.registerIfAbsent(
    AndroidTracer.Builder()
        .setService(BuildConfig.APPLICATION_ID)
        .build()
)

// v3 Datadog tracing API
GlobalDatadogTracer.registerIfAbsent(
    DatadogTracing.newTracerBuilder(sdkCore)
        .withServiceName(BuildConfig.APPLICATION_ID)
        .withPartialFlushMinSpans(4)
        .build()
)

Replace manual tracing:

val tracer = GlobalDatadogTracer.get()

val span = tracer
    .buildSpan("Executing operation")
    .start()

val scope = tracer.activateSpan(span)
try {
    // Instrumented operation
    val traceId = span.context().traceId.toString()
} finally {
    scope?.close()
    span.finish()
}

DatadogTracer.activateSpan() returns a nullable DatadogScope; close it with scope?.close().

DatadogSpan.context() is a function, not a Kotlin property. Call it with parentheses: use span.context().traceId, not span.context.traceId.

Apply these type and API mappings:

v2 OpenTracingv3 Datadog tracing API
io.opentracing.util.GlobalTracercom.datadog.android.trace.GlobalDatadogTracer
com.datadog.android.trace.AndroidTracercom.datadog.android.trace.api.tracer.DatadogTracer
io.opentracing.Spancom.datadog.android.trace.api.span.DatadogSpan
io.opentracing.Scopecom.datadog.android.trace.api.scope.DatadogScope
io.opentracing.SpanContextcom.datadog.android.trace.api.span.DatadogSpanContext
AndroidTracer.Builder().build()DatadogTracing.newTracerBuilder().build()
AndroidTracer.Builder(...).setService(String)DatadogTracerBuilder.withServiceName(String)
AndroidTracer.Builder(...).setPartialFlushThreshold(Int)DatadogTracerBuilder.withPartialFlushMinSpans(Int)
SpanContext.toTraceId()DatadogSpanContext.traceId.toString()
Span.setError()DatadogSpan.addThrowable()

After either path, verify that no source or dependency still relies on io.opentracing.

8. Migrate OkHttp instrumentation

The com.datadoghq:dd-sdk-android-okhttp artifact itself does not require desugaring. Replace the removed positional constructors with builders while preserving service names, traced hosts and header types, listeners, resource attribute providers, and samplers.

Removed v2 constructor familyv3 replacement
TracingInterceptor(...)TracingInterceptor.Builder(tracedHosts)
DatadogInterceptor(...)DatadogInterceptor.Builder(tracedHosts)

Search every overload, including constructors that accept any combination of:

  • a nullable service name;

  • List<String> traced hosts;

  • Map<String, Set<TracingHeaderType>> traced-host configuration;

  • TracedRequestListener;

  • RumResourceAttributesProvider;

  • Sampler<Span>.

The builder requires either List<String> or Map<String, Set<TracingHeaderType>> in its constructor. There is no zero-argument builder and no setTracedHostsWithHeaderType method. Do not drop constructor arguments during the conversion; map each behavior to the corresponding builder option:

val datadogInterceptor = DatadogInterceptor.Builder(tracedHostsWithHeaderType)
    .setSdkInstanceName(sdkCore.name)
    .setTracedRequestListener(tracedRequestListener)
    .setRumResourceAttributesProvider(resourceAttributesProvider)
    .setTraceSampler(DeterministicTraceSampler(20f))
    .build()

val tracingInterceptor = TracingInterceptor.Builder(tracedHostsWithHeaderType)
    .setSdkInstanceName(sdkCore.name)
    .setTracedRequestListener(tracedRequestListener)
    .setTraceSampler(DeterministicTraceSampler(20f))
    .build()

In v3, TracedRequestListener receives a Datadog span, even when the application's manual tracing uses OpenTelemetry:

val tracedRequestListener = object : TracedRequestListener {
    override fun onRequestIntercepted(
        request: Request,
        span: DatadogSpan,
        response: Response?,
        throwable: Throwable?
    ) {
        span.setTag("request.method", request.method)
    }
}

Update custom samplers from Sampler<io.opentracing.Span> to Sampler<DatadogSpan>.

9. Migrate Session Replay

SessionReplayConfiguration.Builder.useCustomEndpoint must receive the full Session Replay upload URL:

SessionReplay.enable(
    SessionReplayConfiguration.Builder(...)
        .useCustomEndpoint("https://example.com/session_replay/upload")
        .build()
)

Preserve the application's existing Session Replay privacy and sampling configuration.

10. Verify the result

Run the project's normal Gradle compilation task. Prefer the same compilation command used by the project's CI.

Before finishing, confirm:

  • all resolved com.datadoghq:dd-sdk-android-* artifacts are on one stable 3.x version;

  • minSdk is at least 23 and Kotlin is at least 1.9;

  • no io.opentracing dependency or import remains;

  • every user ID is non-null;

  • manual RUM resources use RumResourceMethod;

  • global RUM access uses GlobalRumMonitor.get();

  • every custom endpoint is a full product-specific upload URL;

  • every previously enabled Datadog product remains enabled;

  • migrated OkHttp interceptors preserve their previous configuration;

  • Gradle compilation exits successfully.

Fix only migration-related failures. Do not rewrite unrelated application code or remove instrumentation to obtain a successful compilation.

Report the original and resulting SDK versions, the migration path chosen for tracing, the files changed, and the exact Gradle compilation command that passed.

Files

ATTRIBUTION.md

Attribution

This folder is an unmodified copy of the Agent Skill "dd-android-sdk-v3-upgrade", distributed by AutoGineer (https://autogineer.com/agent-skills).

The skill's own files are unmodified copies. AutoGineer is not affiliated with or endorsed by the author or the publisher.

Files added by AutoGineer

  • ATTRIBUTION.md: this file, written by AutoGineer

  • LICENSE: copied from LICENSE

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
datadog-labs
Publisher
Datadog (Official)
Source
datadog-labs/agent-skills · dd-android-sdk/upgrade-v3 · commit 8e1306a
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by datadog-labs or Datadog.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download dd-android-sdk-v3-upgrade.zip