Overview

Follow this guide to migrate between major versions of the Mobile RUM, Logs, and Trace SDKs. See each SDK’s documentation for details on its features and capabilities.

Most common migrations:

  • v2 to v3: Focus on Open Tracing removal and API updates
  • v1 to v2: Major architectural changes to modular design

From v2 to v3

The transition from version 2 to version 3 focuses on removing support for the legacy Open Tracing project, improving the stability and consistency of the SDK.

The migration from v2 to v3 focuses on streamlining modules, refining defaults, and improving reliability across product features.

All SDK products (RUM, Trace, Logs, Session Replay, and so on) remain modular and separated into distinct libraries. The main change is that the DatadogObjc module has been removed, with its contents integrated into the corresponding product modules.

Modules

We are following Google's AndroidX library version policy for the AndroidX libraries so the minimum Android API level supported by SDK v3 is `23`.

Requirements:

  • Kotlin 1.9 is required
  • The Open Tracing dependency was removed because it is obsolete

Libraries continue to be modularized in v3. Adopt the following libraries:

  • DatadogCore
  • DatadogCrashReporting
  • DatadogLogs
  • DatadogRUM
  • DatadogSessionReplay
  • DatadogTrace
  • DatadogWebViewTracking
SPM (Recommended)
let package = Package(
  ...
  dependencies: [
      .package(url: "https://github.com/DataDog/dd-sdk-ios", from: "3.0.0")
  ],
  targets: [
      .target(
          ...
          dependencies: [
              .product(name: "DatadogCore", package: "dd-sdk-ios"),
              .product(name: "DatadogCrashReporting", package: "dd-sdk-ios"),
              .product(name: "DatadogLogs", package: "dd-sdk-ios"),
              .product(name: "DatadogRUM", package: "dd-sdk-ios"),
              .product(name: "DatadogSessionReplay", package: "dd-sdk-ios"),
              .product(name: "DatadogTrace", package: "dd-sdk-ios"),
              .product(name: "DatadogWebViewTracking", package: "dd-sdk-ios"),
          ]
      ),
  ]
)
CocoaPods
pod 'DatadogCore'
pod 'DatadogCrashReporting'
pod 'DatadogLogs'
pod 'DatadogRUM'
pod 'DatadogSessionReplay'
pod 'DatadogTrace'
pod 'DatadogWebViewTracking'
Carthage

The Cartfile stays the same:

github "DataDog/dd-sdk-ios"

In Xcode, you must link the following frameworks:

DatadogInternal.xcframework
DatadogCore.xcframework

Then, you can select the modules you want to use:

DatadogCrashReporting.xcframework + CrashReporter.xcframework
DatadogLogs.xcframework
DatadogRUM.xcframework
DatadogSessionReplay.xcframework
DatadogTrace.xcframework
DatadogWebViewTracking.xcframework

Required changes and API updates

Core

Action Required: In SDK v3, the user info ID becomes mandatory, and the null value cannot be provided anymore.

API changes:

2.x3.0
Datadog.setUserInfo(null, "Jane Smith", "jane@example.com")Datadog.setUserInfo("user123", "Jane Smith", "jane@example.com")

RUM

We made minor improvements to the RUM modules. They don’t require significant changes to your code, but it’s worth checking if you can refactor some redundant parameters.

API changes:

2.x3.0
DatadogRumMonitor.startResource(String, String, String,Map<String, Any?>)Use startResource method which takes RumHttpMethod as method parameter instead
com.datadog.android.rum.GlobalRumGlobalRum object was renamed to com.datadog.android.rum.GlobalRumMonitor
com.datadog.android.rum.RumMonitor.addAction()Parameter attributes: Map<String, Any?> is optional
com.datadog.android.rum.RumMonitor.startAction()Parameter attributes: Map<String, Any?> is optional
com.datadog.android.rum.RumMonitor.stopResource()Parameter attributes: Map<String, Any?> is optional
com.datadog.android.rum.RumMonitor.addError()Parameter attributes: Map<String, Any?> is optional
com.datadog.android.rum.RumMonitor.addErrorWithStacktrace()Parameter attributes: Map<String, Any?> is optional
com.datadog.android.rum.internal.monitor.AdvancedNetworkRumMonitor.stopResource()Parameter attributes: Map<String, Any?> is optional
com.datadog.android.rum.internal.monitor.AdvancedNetworkRumMonitor.stopResource()Parameter attributes: Map<String, Any?> is optional

Logs

The Logs product no longer reports fatal errors. To enable Error Tracking for crashes, Crash Reporting must be enabled in conjunction with RUM.

Trace

The Open Tracing project has been marked as archived and it is no longer supported. The Open Tracing dependencies on has been removed from SDK v3.

The Datadog SDK already supports Open Telemetry, which is the recommended way to use the tracing feature API.

Note that the Open Telemetry specification library requires desugaring to be enabled for projects with a minSdk < 26.

  1. Add the Open Telemetry dependency to your build.gradle.kts:
implementation(project("com.datadoghq:dd-sdk-android-trace-otel:x.x.x"))
  1. Replace the Open Tracing configuration:
GlobalTracer.registerIfAbsent(
  AndroidTracer.Builder()
    .setService(BuildConfig.APPLICATION_ID)
    .build()
)

with the Open Telemetry configuration:

GlobalOpenTelemetry.set(
  DatadogOpenTelemetry(BuildConfig.APPLICATION_ID)
)

To access the tracer object for manual (custom) tracing, use io.opentelemetry.api.GlobalOpenTelemetry.get() instead of io.opentracing.util.GlobalTracer.get(). For example:

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

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

// Code that should be instrumented

span.end()

Refer to the official Open Telemetry documentation for more details.

Migrating tracing from Open Tracing to DatadogTracing (transition period)

This option has been added for compatibility and to simplify the transition from Open Tracing to Open Telemetry, but it may not be available in future major releases. Datadog recommends using Open Telemetry as the standard for tracing tasks. However, if it is not possible to enable desugaring in your project for some reason, you can use this method.
Replace the `Open Tracing` configuration: ```kotlin GlobalTracer.registerIfAbsent( AndroidTracer.Builder() .setService(BuildConfig.APPLICATION_ID) .build() ) ```

with the DatadogTracing configuration:

GlobalDatadogTracer.registerIfAbsent(
  DatadogTracing.newTracerBuilder()
    .build()
)

For manual (custom) tracing use com.datadog.android.trace.GlobalDatadogTracer.get() instead of io.opentracing.util.GlobalTracer.get() to access the tracer object. For example:

val tracer = GlobalDatadogTracer.get()

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

// Code that should be instrumented

span.finish()

Refer to the Datadog documentation for more details.

API changes:

2.x3.0 Open Telemetry3.0 Datadog API
io.opentracing.util.GlobalTracerio.opentelemetry.api.GlobalOpenTelemetrycom.datadog.android.trace.GlobalDatadogTracer
com.datadog.android.trace.AndroidTracerio.opentelemetry.api.trace.Tracercom.datadog.android.trace.api.tracer.DatadogTracer
io.opentracing.Spanio.opentelemetry.api.trace.Spancom.datadog.android.trace.api.span.DatadogSpan
io.opentracing.Scopeio.opentelemetry.context.Scopecom.datadog.android.trace.api.scope.DatadogScope
io.opentracing.SpanContextio.opentelemetry.api.trace.SpanContextcom.datadog.android.trace.api.span.DatadogSpanContext

Replacement hints:

2.x3.0 Open Telemetry3.0 Datadog API
AndroidTracer.Builder().build()DatadogTracing.newTracerBuilder().build()
AndroidTracer.setPartialFlushThreshold(Int)OtelTracerProvider.setPartialFlushThreshold()DatadogTracerBuilder.withPartialFlushMinSpans()
io.opentracing.SpanContext.toTraceId()io.opentelemetry.api.trace.SpanContext.getTraceId()DatadogSpanContext.traceId.toString()
io.opentracing.Span.setError()io.opentelemetry.api.trace.recordException()DatadogSpan.addThrowable()

OkHttp instrumentation

The OkHttp instrumentation (com.datadoghq:dd-sdk-android-okhttp:x.x.x) does not require desugaring support. However, a few migration actions may be necessary.

API changes:

2.x3.0
TracingInterceptor(String, List<String>, TracedRequestListener,Sampler<Span>)Use TracingInterceptor.Builder() instead.
TracingInterceptor(String?,Map<String, Set<TracingHeaderType>>, TracedRequestListener, Sampler<Span>)Use TracingInterceptor.Builder() instead.
TracingInterceptor(String?,TracedRequestListener,Sampler<Span>)Use TracingInterceptor.Builder() instead.
DatadogInterceptor(String?, Map<String, Set<TracingHeaderType>>,TracedRequestListener, RumResourceAttributesProvider, Sampler<Span>)Use DatadogInterceptor.Builder() instead.
DatadogInterceptor(String?,List<String>,TracedRequestListener,RumResourceAttributesProvider,Sampler<Span>)Use DatadogInterceptor.Builder() instead.
DatadogInterceptor(String?,TracedRequestListener,RumResourceAttributesProvider,Sampler<Span>)Use DatadogInterceptor.Builder() instead.

The SDK should be initialized as early as possible in the app lifecycle, specifically in the AppDelegate’s application(_:didFinishLaunchingWithOptions:) callback. This ensures accurate measurement of all metrics, including application startup duration. For apps built with SwiftUI, use @UIApplicationDelegateAdaptor to access the AppDelegate.

import DatadogCore

Datadog.initialize(
    with: Datadog.Configuration(
        clientToken: "<client token>",
        env: "<environment>",
        service: "<service name>"
    ),
    trackingConsent: .granted
)

Note: Initializing the SDK elsewhere (for example later during view loading) may result in inaccurate or missing telemetry, especially around app startup performance.

Action Required: The API to set the user info requires the id parameter, which was optional in 2.x.
2.x3.0
Datadog.setUserInfo(id: nil, name: "Jane Smith", email: "jane@example.com")Datadog.setUserInfo(id: "user123", name: "Jane Smith", email: "jane@example.com")

RUM

RUM View-level attributes are automatically propagated to all related child events, including resources, user actions, errors, and long tasks. This ensures consistent metadata across events, making it easier to filter and correlate data on Datadog dashboards.

To manage View level attributes more effectively, new APIs were added:

  • Monitor.addViewAttribute(forKey:value:)
  • Monitor.addViewAttributes(_:)
  • Monitor.removeViewAttribute(forKey:)
  • Monitor.removeViewAttributes(forKeys:)

Other notable changes:

  • All Objective-C RUM APIs are included in DatadogRUM. The separate DatadogObjc module is no longer available.
  • App Hangs and Watchdog terminations are no longer reported from app extensions or widgets.
  • A new property trackMemoryWarnings was added to RUM.Configuration to report memory warnings as RUM Errors.

API changes:

2.x3.0
-RUM.Configuration.trackMemoryWarnings
RUMView(path:attributes:)RUMView(name:attributes:isUntrackedModal:)
-Monitor.addViewAttribute(forKey:value:)
-Monitor.addViewAttributes(:)
-Monitor.removeViewAttribute(forKey:)
-Monitor.removeViewAttributes(forKeys:)

Logs

The Logs product no longer reports fatal errors. To enable Error Tracking for crashes, Crash Reporting must be enabled in conjunction with RUM.

Additionally, all Objective-C Logs APIs are included in DatadogLogs. The separate DatadogObjc module is no longer available.

Trace

Trace sampling is now deterministic when used alongside RUM. It uses the RUM session.id to ensure consistent sampling.

Also:

  • The Trace.Configuration.URLSessionTracking.FirstPartyHostsTracing configuration sets sampling for all requests by default and the trace context is injected only into sampled requests.
  • All Objective-C Trace APIs are included in DatadogTrace. The separate DatadogObjc module is no longer available.

Note: A similar configuration exists in RUM.Configuration.URLSessionTracking.FirstPartyHostsTracing.

Session Replay

Privacy settings are more granular. The previous defaultPrivacyLevel parameter has been replaced with:

  • textAndInputPrivacyLevel
  • imagePrivacyLevel
  • touchPrivacyLevel

Learn more about privacy levels.

API changes:

2.x3.0
SessionReplay.Configuration(replaySampleRate:defaultPrivacyLevel:startRecordingImmediately:customEndpoint:)SessionReplay.Configuration(replaySampleRate:textAndInputPrivacyLevel:imagePrivacyLevel:touchPrivacyLevel:startRecordingImmediately:customEndpoint:featureFlags:)
SessionReplay.Configuration(replaySampleRate:defaultPrivacyLevel:startRecordingImmediately:customEndpoint:)SessionReplay.Configuration(replaySampleRate:textAndInputPrivacyLevel:imagePrivacyLevel:touchPrivacyLevel:startRecordingImmediately:customEndpoint:featureFlags:)

URLSession Instrumentation

To enable URLSession Instrumentation, make sure to also enable RUM and/or Trace to report to those products respectively.

Legacy delegate types have been replaced by a unified instrumentation API:

2.x3.0
DatadogURLSessionDelegate()URLSessionInstrumentation.enable(with:)
DDURLSessionDelegate()URLSessionInstrumentation.enable(with:)
DDNSURLSessionDelegate()URLSessionInstrumentation.enable(with:)

From v1 to v2

The migration from v1 to v2 represents a migration from a monolith SDK into a modular architecture. RUM, Trace, Logs, Session Replay, and so on each have individual modules, allowing you to integrate only what is needed into your application.

SDK v2 offers a unified API layout and naming alignment between the iOS SDK, the Android SDK, and other Datadog products.

SDK v2 enables the usage of Mobile Session Replay on Android and iOS applications.

The migration from v1 to v2 represents a migration from a monolith SDK into a modular architecture. RUM, Trace, Logs, Session Replay, and so on each have individual modules, allowing you to integrate only what is needed into your application.

SDK v2 offers a unified API layout and naming alignment between the iOS SDK, the Android SDK, and other Datadog products.

SDK v2 enables the usage of Mobile Session Replay on Android and iOS applications.

The migration from v1 to v2 comes with improved performance.

The migration from v1 to v2 comes with improved performance and additional features supplied by the v2 Native SDKs.

Modules

Artifacts are modularized in v2. Adopt the following artifacts:

  • RUM: com.datadoghq:dd-sdk-android-rum:x.x.x
  • Logs: com.datadoghq:dd-sdk-android-logs:x.x.x
  • Trace: com.datadoghq:dd-sdk-android-trace:x.x.x
  • Session Replay: com.datadoghq:dd-sdk-android-session-replay:x.x.x
  • WebView Tracking: com.datadoghq:dd-sdk-android-webview:x.x.x
  • OkHttp instrumentation: com.datadoghq:dd-sdk-android-okhttp:x.x.x

Note: If you use NDK Crash Reporting and WebView Tracking, you must add RUM and Logs artifacts to report events to RUM and Logs respectively.

Reference to the com.datadoghq:dd-sdk-android artifact should be removed from your Gradle build script, as this artifact doesn’t exist anymore.

Note: The Maven coordinates of all the other artifacts stay the same.

v2 does not support Android API 19 (KitKat). The minimum SDK supported is now API 21 (Lollipop). Kotlin 1.7 is required. The SDK itself is compiled with Kotlin 1.8, so a compiler of Kotlin 1.6 and below cannot read SDK classes metadata.

Should you encounter an error such as the following:

A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and kotlin-stdlib-jdk8-1.7.20 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20)

Add the following rules to your build script (more details in the relevant Stack Overflow issue):

dependencies {
    constraints {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.10") {
            because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib")
        }
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.10") {
            because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib")
        }
    }
}

See the Android sample application for an example of how to set up the SDK.

Libraries are modularized in v2. Adopt the following libraries:

  • DatadogCore
  • DatadogLogs
  • DatadogTrace
  • DatadogSessionReplay
  • DatadogRUM
  • DatadogWebViewTracking

These come in addition to the existing DatadogCrashReporting and DatadogObjc.

SPM (Recommended)
let package = Package(
  ...
  dependencies: [
      .package(url: "https://github.com/DataDog/dd-sdk-ios", from: "2.0.0")
  ],
  targets: [
      .target(
          ...
          dependencies: [
              .product(name: "DatadogCore", package: "dd-sdk-ios"),
              .product(name: "DatadogLogs", package: "dd-sdk-ios"),
              .product(name: "DatadogTrace", package: "dd-sdk-ios"),
              .product(name: "DatadogSessionReplay", package: "dd-sdk-ios"),
              .product(name: "DatadogRUM", package: "dd-sdk-ios"),
              .product(name: "DatadogCrashReporting", package: "dd-sdk-ios"),
              .product(name: "DatadogWebViewTracking", package: "dd-sdk-ios"),
          ]
      ),
  ]
)
CocoaPods
pod 'DatadogCore'
pod 'DatadogLogs'
pod 'DatadogTrace'
pod 'DatadogSessionReplay'
pod 'DatadogRUM'
pod 'DatadogCrashReporting'
pod 'DatadogWebViewTracking'
pod 'DatadogObjc'
Carthage

The Cartfile stays the same:

github "DataDog/dd-sdk-ios"

In Xcode, you must link the following frameworks:

DatadogInternal.xcframework
DatadogCore.xcframework

Then, you can select the modules you want to use:

DatadogLogs.xcframework
DatadogTrace.xcframework
DatadogSessionReplay.xcframework
DatadogRUM.xcframework
DatadogCrashReporting.xcframework + CrashReporter.xcframework
DatadogWebViewTracking.xcframework
DatadogObjc.xcframework

Note: When using Crash Reporting and WebView Tracking, you must add the RUM and Logs modules to report events to RUM and Logs respectively.

Update @datadog/mobile-react-native in your package.json:

"@datadog/mobile-react-native": "2.0.0"

Update your iOS pods:

(cd ios && bundle exec pod update)

If you use a React Native version strictly over 0.67, use Java version 17. If you use React Native version equal or below ot 0.67, use Java version 11. To check your Java version, run the following in a terminal:

java --version

For React Native < 0.73

In your android/build.gradle file, specify the kotlinVersion to avoid clashes among Kotlin dependencies:

buildscript {
    ext {
        // targetSdkVersion = ...
        kotlinVersion = "1.8.21"
    }
}

For React Native < 0.68

In your android/build.gradle file, specify the kotlinVersion to avoid clashes among Kotlin dependencies:

buildscript {
    ext {
        // targetSdkVersion = ...
        kotlinVersion = "1.8.21"
    }
}

If you are using a version of com.android.tools.build:gradle below 5.0 in your android/build.gradle, add in your android/gradle.properties file:

android.jetifier.ignorelist=dd-sdk-android-core

Troubleshooting

Android build fails with Unable to make field private final java.lang.String java.io.File.path accessible

If your Android build fails with an error like:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:processReleaseMainManifest'.
> Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not "opens java.io" to unnamed module @1bbf7f0e

You are using Java 17, which is not compatible with your React Native version. Switch to Java 11 to solve the issue.

Android build fails with Unsupported class file major version 61

If your Android build fails with an error like:

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':app:lintVitalRelease'.
> Could not resolve all artifacts for configuration ':app:debugRuntimeClasspath'.
   > Failed to transform dd-sdk-android-core-2.0.0.aar (com.datadoghq:dd-sdk-android-core:2.0.0) to match attributes {artifactType=android-manifest, org.gradle.category=library, org.gradle.dependency.bundling=external, org.gradle.libraryelements=aar, org.gradle.status=release, org.gradle.usage=java-runtime}.
      > Execution failed for JetifyTransform: /Users/me/.gradle/caches/modules-2/files-2.1/com.datadoghq/dd-sdk-android-core/2.0.0/a97f8a1537da1de99a86adf32c307198b477971f/dd-sdk-android-core-2.0.0.aar.
         > Failed to transform '/Users/me/.gradle/caches/modules-2/files-2.1/com.datadoghq/dd-sdk-android-core/2.0.0/a97f8a1537da1de99a86adf32c307198b477971f/dd-sdk-android-core-2.0.0.aar' using Jetifier. Reason: IllegalArgumentException, message: Unsupported class file major version 61. (Run with --stacktrace for more details.)

You use a version of Android Gradle Plugin below 5.0. To fix the issue, add in your android/gradle.properties file:

android.jetifier.ignorelist=dd-sdk-android-core

Android build fails with Duplicate class kotlin.collections.jdk8.*

If your Android build fails with an error like:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:checkReleaseDuplicateClasses'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
   > Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.7.20 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20)
     Duplicate class kotlin.internal.jdk7.JDK7PlatformImplementations found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk7-1.7.20 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.20)

You need to set a Kotlin version for your project to avoid clashes among Kotlin dependencies. In your android/build.gradle file, specify the kotlinVersion:

buildscript {
    ext {
        // targetSdkVersion = ...
        kotlinVersion = "1.8.21"
    }
}

Alternatively, you can add the following rules to your build script in your android/app/build.gradle file:

dependencies {
    constraints {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.10") {
            because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib")
        }
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.10") {
            because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib")
        }
    }
}

Update datadog_flutter_plugin in your pubspec.yaml:

dependencies:
  'datadog_flutter_plugin: ^2.0.0

Troubleshooting

Duplicate interface (iOS)

If you see this error while building iOS after upgrading to datadog_flutter_plugin v2.0:

Semantic Issue (Xcode): Duplicate interface definition for class 'DatadogSdkPlugin'
/Users/exampleuser/Projects/test_app/build/ios/Debug-iphonesimulator/datadog_flutter_plugin/datadog_flutter_plugin.framework/Headers/DatadogSdkPlugin.h:6:0

Try performing flutter clean && flutter pub get and rebuilding. This usually resolves the issue.

Duplicate classes (Android)

If you see this error while building Android after the upgrading to datadog_flutter_plugin v2.0:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:checkDebugDuplicateClasses'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable

Make sure that you’ve updated your version of Kotlin to at least 1.8 in your build.gradle file.

SDK initialization

With the extraction of different products into independent modules, the SDK configuration is organized by module.

com.datadog.android.core.configuration.Configuration.Builder class has the following changes:

  • Client token, env name, variant name (default value is empty string), and service name (default value is application ID taken from the manifest) should be provided in the constructor.
  • The com.datadog.android.core.configuration.Credentials class is removed.
  • logsEnabled, tracesEnabled, and rumEnabled are removed from the constructor in favour of individual product configuration (see below).
  • crashReportsEnabled constructor argument is removed. You can enable or disable JVM crash reporting with the Configuration.Builder.setCrashReportsEnabled method. By default, JVM crash reporting is enabled.
  • RUM, Logs, and Trace product configuration methods are removed from Configuration.Builder in favor of the individual product configuration (see below).

The Datadog.initialize method has the Credentials class removed from the list of the arguments.

The com.datadog.android.plugin package and all related classes/methods are removed.

Logs

All the classes related to the Logs product are strictly contained in the com.datadog.android.log package.

To use Logs product, import the following artifact:

implementation("com.datadoghq:dd-sdk-android-logs:x.x.x")

You can enable the Logs product with the following snippet:

val logsConfig = LogsConfiguration.Builder()
    ...
    .build()

Logs.enable(logsConfig)

val logger = Logger.Builder()
    ...
    .build()

API changes:

1.x2.0
com.datadog.android.core.configuration.Configuration.Builder.setLogEventMappercom.datadog.android.log.LogsConfiguration.Builder.setEventMapper
com.datadog.android.core.configuration.Configuration.Builder.useCustomLogsEndpointcom.datadog.android.log.LogsConfiguration.Builder.useCustomEndpoint
com.datadog.android.log.Logger.Builder.setLoggerNamecom.datadog.android.log.Logger.Builder.setName
com.datadog.android.log.Logger.Builder.setSampleRatecom.datadog.android.log.Logger.Builder.setRemoteSampleRate
com.datadog.android.log.Logger.Builder.setDatadogLogsEnabledThis method has been removed. Use com.datadog.android.log.Logger.Builder.setRemoteSampleRate(0f) instead to disable sending logs to Datadog.
com.datadog.android.log.Logger.Builder.setServiceNamecom.datadog.android.log.Logger.Builder.setService
com.datadog.android.log.Logger.Builder.setDatadogLogsMinPrioritycom.datadog.android.log.Logger.Builder.setRemoteLogThreshold

Trace

All the classes related to the Trace product are strictly contained in the com.datadog.android.trace package (this means that all classes residing in com.datadog.android.tracing before have moved).

To use the Trace product, import the following artifact:

implementation("com.datadoghq:dd-sdk-android-trace:x.x.x")

You can enable the Trace product with the following snippet:

val traceConfig = TraceConfiguration.Builder()
    ...
    .build()

Trace.enable(traceConfig)

val tracer = AndroidTracer.Builder()
    ...
    .build()

GlobalTracer.registerIfAbsent(tracer)

API changes:

1.x2.0
com.datadog.android.core.configuration.Configuration.Builder.setSpanEventMappercom.datadog.android.trace.TraceConfiguration.Builder.setEventMapper
com.datadog.android.core.configuration.Configuration.Builder.useCustomTracesEndpointcom.datadog.android.trace.TraceConfiguration.Builder.useCustomEndpoint
com.datadog.android.tracing.AndroidTracer.Builder.setSamplingRatecom.datadog.android.trace.AndroidTracer.Builder.setSampleRate
com.datadog.android.tracing.AndroidTracer.Builder.setServiceNamecom.datadog.android.trace.AndroidTracer.Builder.setService

RUM

All classes related to the RUM product are strictly contained in the com.datadog.android.rum package.

To use the RUM product, import the following artifact:

implementation("com.datadoghq:dd-sdk-android-rum:x.x.x")

You can enable the RUM product with the following snippet:

val rumConfig = RumConfiguration.Builder(rumApplicationId)
    ...
    .build()

Rum.enable(rumConfig)

API changes:

1.x2.0
com.datadog.android.core.configuration.Configuration.Builder.setRumViewEventMappercom.datadog.android.rum.RumConfiguration.Builder.setViewEventMapper
com.datadog.android.core.configuration.Configuration.Builder.setRumResourceEventMappercom.datadog.android.rum.RumConfiguration.Builder.setResourceEventMapper
com.datadog.android.core.configuration.Configuration.Builder.setRumActionEventMappercom.datadog.android.rum.RumConfiguration.Builder.setActionEventMapper
com.datadog.android.core.configuration.Configuration.Builder.setRumErrorEventMappercom.datadog.android.rum.RumConfiguration.Builder.setErrorEventMapper
com.datadog.android.core.configuration.Configuration.Builder.setRumLongTaskEventMappercom.datadog.android.rum.RumConfiguration.Builder.setLongTaskEventMapper
com.datadog.android.core.configuration.Configuration.Builder.useCustomRumEndpointcom.datadog.android.rum.RumConfiguration.Builder.useCustomEndpoint
com.datadog.android.event.ViewEventMappercom.datadog.android.rum.event.ViewEventMapper
com.datadog.android.core.configuration.VitalsUpdateFrequencycom.datadog.android.rum.configuration.VitalsUpdateFrequency
com.datadog.android.core.configuration.Configuration.Builder.trackInteractionscom.datadog.android.rum.RumConfiguration.Builder.trackUserInteractions
com.datadog.android.core.configuration.Configuration.Builder.disableInteractionTrackingcom.datadog.android.rum.RumConfiguration.Builder.disableUserInteractionTracking
com.datadog.android.core.configuration.Configuration.Builder.sampleRumSessionscom.datadog.android.rum.RumConfiguration.Builder.setSessionSampleRate
com.datadog.android.core.configuration.Configuration.Builder.sampleTelemetrycom.datadog.android.rum.RumConfiguration.Builder.setTelemetrySampleRate
com.datadog.android.rum.RumMonitor.BuilderThis class has been removed. The RUM monitor is created and registered during the Rum.enable call.
com.datadog.android.rum.RumMonitor.Builder.sampleRumSessionscom.datadog.android.rum.RumConfiguration.Builder.setSessionSampleRate
com.datadog.android.rum.RumMonitor.Builder.setSessionListenercom.datadog.android.rum.RumConfiguration.Builder.setSessionListener
com.datadog.android.rum.RumMonitor.addUserActioncom.datadog.android.rum.RumMonitor.addAction
com.datadog.android.rum.RumMonitor.startUserActioncom.datadog.android.rum.RumMonitor.startAction
com.datadog.android.rum.RumMonitor.stopUserActioncom.datadog.android.rum.RumMonitor.stopAction
com.datadog.android.rum.GlobalRum.registerIfAbsentThis method has been removed. The RUM monitor is created and registered during the Rum.enable call.
com.datadog.android.rum.GlobalRumcom.datadog.android.rum.GlobalRumMonitor
com.datadog.android.rum.GlobalRum.addAttributecom.datadog.android.rum.RumMonitor.addAttribute
com.datadog.android.rum.GlobalRum.removeAttributecom.datadog.android.rum.RumMonitor.removeAttribute

NDK Crash Reporting

The artifact name stays the same as before: com.datadoghq:dd-sdk-android-ndk:x.x.x.

You can enable NDK Crash Reporting with the following snippet:

NdkCrashReports.enable()

This configuration replaces the com.datadog.android.core.configuration.Configuration.Builder.addPlugin call.

Note: You should have RUM and Logs products enabled to receive NDK crash reports in RUM and Logs respectively.

WebView Tracking

The artifact name stays the same as before: com.datadoghq:dd-sdk-android-webview:x.x.x

You can enable WebView Tracking with the following snippet:

WebViewTracking.enable(webView, allowedHosts)

Note: You should have RUM and Logs products enabled to receive events coming from WebView in RUM and Logs respectively.

API changes:

1.x2.0
com.datadog.android.webview.DatadogEventBridgeThis method became an internal class. Use WebViewTracking instead.
com.datadog.android.rum.webview.RumWebChromeClientThis class was removed. Use WebViewTracking instead.
com.datadog.android.rum.webview.RumWebViewClientThis class was removed. Use WebViewTracking instead.

OkHttp Tracking

To use OkHttp Tracking, import the following artifact:

implementation("com.datadoghq:dd-sdk-android-okhttp:x.x.x")

OkHttp instrumentation supports the initialization of the Datadog SDK after the OkHttp client, allowing you to create com.datadog.android.okhttp.DatadogEventListener, com.datadog.android.okhttp.DatadogInterceptor, and com.datadog.android.okhttp.trace.TracingInterceptor before the Datadog SDK. OkHttp instrumentation starts reporting events to Datadog once the Datadog SDK is initialized.

Both com.datadog.android.okhttp.DatadogInterceptor and com.datadog.android.okhttp.trace.TracingInterceptor allow you to control sampling dynamically through integration with a remote configuration system.

To dynamically adjust sampling, provide your own implementation of the com.datadog.android.core.sampling.Sampler interface in the com.datadog.android.okhttp.DatadogInterceptor/com.datadog.android.okhttp.trace.TracingInterceptor constructor. It is queried for each request to make the sampling decision.

dd-sdk-android-ktx module removal

To improve granularity for the Datadog SDK libraries used, the dd-sdk-android-ktx module is removed. The code is distributed between the other modules to provide extension methods for both RUM and Trace features.

1.x‘2.0’Module name
com.datadog.android.ktx.coroutine#kotlinx.coroutines.CoroutineScope.launchTracedcom.datadog.android.trace.coroutines#kotlinx.coroutines.CoroutineScope.launchTraceddd-sdk-android-trace-coroutines
com.datadog.android.ktx.coroutine#runBlockingTracedcom.datadog.android.trace.coroutines#runBlockingTraceddd-sdk-android-trace-coroutines
com.datadog.android.ktx.coroutine#kotlinx.coroutines.CoroutineScope.asyncTracedcom.datadog.android.trace.coroutines#kotlinx.coroutines.CoroutineScope.asyncTraceddd-sdk-android-trace-coroutines
com.datadog.android.ktx.coroutine#kotlinx.coroutines.Deferred<T>.awaitTracedcom.datadog.android.trace.coroutines#kotlinx.coroutines.Deferred<T>.awaitTraceddd-sdk-android-trace-coroutines
com.datadog.android.ktx.coroutine#withContextTracedcom.datadog.android.trace.coroutines#withContextTraceddd-sdk-android-trace-coroutines
com.datadog.android.ktx.coroutine.CoroutineScopeSpancom.datadog.android.trace.coroutines.CoroutineScopeSpandd-sdk-android-trace-coroutines
com.datadog.android.ktx.sqlite#android.database.sqlite.SQLiteDatabase.transactionTracedcom.datadog.android.trace.sqlite#android.database.sqlite.SQLiteDatabase.transactionTraceddd-sdk-android-trace
com.datadog.android.ktx.tracing#io.opentracing.Span.setErrorcom.datadog.android.trace#io.opentracing.Span.setErrordd-sdk-android-trace
com.datadog.android.ktx.tracing#withinSpancom.datadog.android.trace#withinSpandd-sdk-android-trace
com.datadog.android.ktx.coroutine#sendErrorToDatadogcom.datadog.android.rum.coroutines#sendErrorToDatadogdd-sdk-android-rum-coroutines
com.datadog.android.ktx.rum#java.io.Closeable.useMonitoredcom.datadog.android.rum#java.io.Closeable.useMonitoreddd-sdk-android-rum
com.datadog.android.ktx.rum#android.content.Context.getAssetAsRumResourcecom.datadog.android.rum.resource#android.content.Context.getAssetAsRumResourcedd-sdk-android-rum
com.datadog.android.ktx.rum#android.content.Context.getRawResAsRumResourcecom.datadog.android.rum.resource#android.content.Context.getRawResAsRumResourcedd-sdk-android-rum
com.datadog.android.ktx.rum#java.io.InputStream.asRumResourcecom.datadog.android.rum.resource#java.io.InputStream.asRumResourcedd-sdk-android-rum
com.datadog.android.ktx.tracing#okhttp3.Request.Builder.parentSpancom.datadog.android.okhttp.trace#okhttp3.Request.Builder.parentSpandd-sdk-android-okhttp

Session Replay

For instructions on setting up Mobile Session Replay, see Mobile Session Replay Setup and Configuration.

With the extraction of different products into independent modules, the SDK configuration is organized by module.

The SDK must be initialized before enabling any product.

The Builder pattern of the SDK initialization has been removed in favor of structure definitions. The following example shows how a 1.x initialization would translate in 2.0.

V1 Initialization

import Datadog

Datadog.initialize(
    appContext: .init(),
    trackingConsent: .granted,
    configuration: Datadog.Configuration
        .builderUsing(
            clientToken: "<client token>",
            environment: "<environment>"
        )
        .set(serviceName: "<service name>")
        .build()

V2 Initialization

import DatadogCore

Datadog.initialize(
    with: Datadog.Configuration(
        clientToken: "<client token>",
        env: "<environment>",
        service: "<service name>"
    ),
    trackingConsent: .granted
)

API changes:

1.x2.0
Datadog.Configuration.Builder.set(serviceName:)Datadog.Configuration.service
Datadog.Configuration.Builder.set(batchSize:)Datadog.Configuration.batchSize
Datadog.Configuration.Builder.set(uploadFrequency:)Datadog.Configuration.uploadFrequency
Datadog.Configuration.Builder.set(proxyConfiguration:)Datadog.Configuration.proxyConfiguration
Datadog.Configuration.Builder.set(encryption:)Datadog.Configuration.encryption
Datadog.Configuration.Builder.set(serverDateProvider:)Datadog.Configuration.serverDateProvider
Datadog.AppContext(mainBundle:)Datadog.Configuration.bundle

Logs

All the classes related to Logs are strictly in the DatadogLogs module. You first need to enable the product:

import DatadogLogs

Logs.enable(with: Logs.Configuration(...))

Then, you can create a logger instance:

import DatadogLogs

let logger = Logger.create(
    with: Logger.Configuration(name: "<logger name>")
)

API changes:

1.x2.0
Datadog.Configuration.Builder.setLogEventMapper(_:)Logs.Configuration.eventMapper
Datadog.Configuration.Builder.set(loggingSamplingRate:)Logs.Configuration.eventMapper
Logger.Builder.set(serviceName:)Logger.Configuration.service
Logger.Builder.set(loggerName:)Logger.Configuration.name
Logger.Builder.sendNetworkInfo(_:)Logger.Configuration.networkInfoEnabled
Logger.Builder.bundleWithRUM(_:)Logger.Configuration.bundleWithRumEnabled
Logger.Builder.bundleWithTrace(_:)Logger.Configuration.bundleWithTraceEnabled
Logger.Builder.sendLogsToDatadog(false)Logger.Configuration.remoteSampleRate = 0
Logger.Builder.set(datadogReportingThreshold:)Logger.Configuration.remoteLogThreshold
Logger.Builder.printLogsToConsole(_:, usingFormat)Logger.Configuration.consoleLogFormat

Trace

All the classes related to Trace are strictly in the DatadogTrace module. You first need to enable the product:

import DatadogTrace

Trace.enable(
    with: Trace.Configuration(...)
)

Then, you can access the shared Tracer instance:

import DatadogTrace

let tracer = Tracer.shared()

API changes:

1.x2.0
Datadog.Configuration.Builder.trackURLSession(_:)Trace.Configuration.urlSessionTracking
Datadog.Configuration.Builder.setSpanEventMapper(_:)Trace.Configuration.eventMapper
Datadog.Configuration.Builder.set(tracingSamplingRate:)Trace.Configuration.sampleRate
Tracer.Configuration.serviceNameTrace.Configuration.service
Tracer.Configuration.sendNetworkInfoTrace.Configuration.networkInfoEnabled
Tracer.Configuration.globalTagsTrace.Configuration.tags
Tracer.Configuration.bundleWithRUMTrace.Configuration.bundleWithRumEnabled
Tracer.Configuration.samplingRateTrace.Configuration.sampleRate

RUM

All the classes related to RUM are strictly in the DatadogRUM module. You first need to enable the product:

import DatadogRUM

RUM.enable(
    with: RUM.Configuration(applicationID: "<RUM Application ID>")
)

Then, you can access the shared RUM monitor instance:

import DatadogRUM

let monitor = RUMMonitor.shared()

API changes:

1.x2.0
Datadog.Configuration.Builder.trackURLSession(_:)RUM.Configuration.urlSessionTracking
Datadog.Configuration.Builder.set(rumSessionsSamplingRate:)RUM.Configuration.sessionSampleRate
Datadog.Configuration.Builder.onRUMSessionStartRUM.Configuration.onSessionStart
Datadog.Configuration.Builder.trackUIKitRUMViews(using:)RUM.Configuration.uiKitViewsPredicate
Datadog.Configuration.Builder.trackUIKitRUMActions(using:)RUM.Configuration.uiKitActionsPredicate
Datadog.Configuration.Builder.trackRUMLongTasks(threshold:)RUM.Configuration.longTaskThreshold
Datadog.Configuration.Builder.setRUMViewEventMapper(_:)RUM.Configuration.viewEventMapper
Datadog.Configuration.Builder.setRUMResourceEventMapper(_:)RUM.Configuration.resourceEventMapper
Datadog.Configuration.Builder.setRUMActionEventMapper(_:)RUM.Configuration.actionEventMapper
Datadog.Configuration.Builder.setRUMErrorEventMapper(_:)RUM.Configuration.errorEventMapper
Datadog.Configuration.Builder.setRUMLongTaskEventMapper(_:)RUM.Configuration.longTaskEventMapper
Datadog.Configuration.Builder.setRUMResourceAttributesProvider(_:)RUM.Configuration.urlSessionTracking.resourceAttributesProvider
Datadog.Configuration.Builder.trackBackgroundEvents(_:)RUM.Configuration.trackBackgroundEvents
Datadog.Configuration.Builder.trackFrustrations(_:)RUM.Configuration.frustrationsTracking
Datadog.Configuration.Builder.set(mobileVitalsFrequency:)RUM.Configuration.vitalsUpdateFrequency
Datadog.Configuration.Builder.set(sampleTelemetry:)RUM.Configuration.telemetrySampleRate

Crash Reporting

To enable Crash Reporting, make sure to enable RUM and Logs to report to those products respectively.

import DatadogCrashReporting

CrashReporting.enable()
1.x2.0
Datadog.Configuration.Builder.enableCrashReporting()CrashReporting.enable()

WebView Tracking

To enable WebViewTracking, make sure to also enable RUM and Logs to report to those products respectively.

import WebKit
import DatadogWebViewTracking

let webView = WKWebView(...)
WebViewTracking.enable(webView: webView)
1.x2.0
WKUserContentController.startTrackingDatadogEventsWebViewTracking.enable(webView:)

Session Replay

For instructions on setting up Mobile Session Replay, see Mobile Session Replay Setup and Configuration.

No change in the SDK initialization is needed.

SDK Configuration Changes

Certain configuration properties have been moved or renamed to support modularity in Datadog’s native SDKs.

The following structures have been renamed:

1.x2.x
DdSdkConfigurationDatadogConfiguration
LoggingConfigurationDatadogLoggingConfiguration
RumConfigurationDatadogRumConfiguration
DdSdkExistingConfigurationDatadogAttachConfiguration

The following properties have changed:

1.x2.xNotes
DdSdkConfiguration.trackingConsentRemovedPart of Datadog.initialize
DdSdkConfiguration.customEndpointRemovedNow configured per-feature
DdSdkConfiguration.serviceNameDatadogConfiguration.service
DdSdkConfiguration.logEventMapperDatadogLoggingConfiguration.eventMapper
DdSdkConfiguration.customLogsEndpointDatadogLoggingConfiguration.customEndpoint
DdSdkConfiguration.telemetrySampleRateDatadogRumConfiguration.telemetrySampleRate

In addition, the following APIs have changed:

1.x2.xNotes
VerbosityRemovedSee CoreLoggerLevel or LogLevel
DdLogs DatadogSdk.logsDatadogLogging DatadogSdk.logsType changed
DdRum DatadogSdk.rumDatadogRum DatadogSdk.rumType changed
Verbosity DatadogSdk.sdkVerbosityCoreLoggerLevel DatadogSdk.sdkVerbosity
DatadogSdk.runAppDatadogSdk.runAppAdded trackingConsent parameter
DatadogSdk.initializeDatadogSdk.initializeAdded trackingConsent parameter
DatadogSdk.createLoggerDatadogLogging.createLoggerMoved

Flutter Web Changes

Clients using Flutter Web should update to using the Datadog Browser SDK v5. Change the following import in your index.html:

-  <script type="text/javascript" src="https://www.datadoghq-browser-agent.com/datadog-logs-v4.js"></script>
-  <script type="text/javascript" src="https://www.datadoghq-browser-agent.com/datadog-rum-slim-v4.js"></script>
+  <script type="text/javascript" src="https://www.datadoghq-browser-agent.com/us1/v5/datadog-logs.js"></script>
+  <script type="text/javascript" src="https://www.datadoghq-browser-agent.com/us1/v5/datadog-rum-slim.js"></script>

Note: Datadog provides one CDN bundle per site. See the Browser SDK README for a list of all site URLs.

Logs product changes

As with v1, Datadog Logging can be enabled by setting the DatadogConfiguration.loggingConfiguration member. However, unlike v1, Datadog does not create a default logger for you. DatadogSdk.logs is now an instance of DatadogLogging, which can be used to create logs. Many options were moved to DatadogLoggerConfiguration to give developers more granular support over individual loggers.

The following APIs have changed:

1.x2.xNotes
LoggingConfigurationDatadogLoggingConfigurationRenamed most members are now on DatadogLoggerConfiguration
LoggingConfiguration.sendNetworkInfoDatadogLoggerConfiguration.networkInfoEnabled
LoggingConfiguration.printLogsToConsoleDatadogLoggerConfiguration.customConsoleLogFunction
LoggingConfiguration.sendLogsToDatadogRemoved. Use remoteLogThreshold instead
LoggingConfiguration.datadogReportingThresholdDatadogLoggerConfiguration.remoteLogThreshold
LoggingConfiguration.bundleWithRumDatadogLoggerConfiguration.bundleWithRumEnabled
LoggingConfiguration.bundleWithTraceDatadogLoggerConfiguration.bundleWithTraceEnabled
LoggingConfiguration.loggerNameDatadogLoggerConfiguration.name
LoggingConfiguration.sampleRateDatadogLoggerConfiguration.remoteSampleRate

RUM Product Changes

The following APIs have changed:

1.x2.xNotes
RumConfigurationDatadogRumConfigurationType renamed
RumConfiguration.vitalsUpdateFrequencyDatadogRumConfiguration.vitalsUpdateFrequencySet to null to disable vitals updates
RumConfiguration.tracingSampleRateDatadogRumConfiguration.traceSampleRate
RumConfiguration.rumViewEventMapperDatadogRumConfiguration.viewEventMapper
RumConfiguration.rumActionEventMapperDatadogRumConfiguration.actionEventMapper
RumConfiguration.rumResourceEventMapperDatadogRumConfiguration.resourceEventMapper
RumConfiguration.rumErrorEventMapperDatadogRumConfiguration.rumErrorEventMapper
RumConfiguration.rumLongTaskEventMapperDatadogRumConfiguration.longTaskEventMapper
RumUserActionTypeRumActionTypeType renamed
DdRum.addUserActionDdRum.addAction
DdRum.startUserActionDdRum.startAction
DdRum.stopUserActionDdRum.stopAction
DdRum.startResourceLoadingDdRum.startResource
DdRum.stopResourceLoadingDdRum.stopResource
DdRum.stopResourceLoadingWithErrorDdRum.stopResourceWithError

Additionally, event mappers no longer allow you to modify their view names. To rename a view, use a custom ViewInfoExtractor instead.

Further Reading