RUM React Native Monitoring Setup
Overview
Datadog Real User Monitoring (RUM) enables you to visualize and analyze the real-time performance and user journeys of your application’s individual users.
The minimum supported version for the RUM React Native SDK is React Native v0.63.4+. Compatibility with older versions is not guaranteed out-of-the-box.
The RUM React Native SDK supports Expo. For more information, see the Expo documentation.
Setup
To install with NPM, run:
npm install @datadog/mobile-react-native
To install with Yarn, run:
yarn add @datadog/mobile-react-native
iOS
Install the added pod:
Android
If you use a React Native version strictly over 0.67, make sure to use Java version 17. If you use React Native version equal or below ot 0.67, make sure to use Java version 11.
In your android/build.gradle
file, specify the kotlinVersion
to avoid clashes among kotlin dependencies:
buildscript {
ext {
// targetSdkVersion = ...
kotlinVersion = "1.8.21"
}
}
The Datadog React Native SDK requires you to have compileSdkVersion = 31
or higher in the Android application setup, which implies that you should use Build Tools version 31 or higher, Android Gradle Plugin version 7, and Gradle version 7 or higher. To modify the versions, change the values in the buildscript.ext
block of your application’s top-level build.gradle
file. Datadog recommends using a React Native version that’s actively supported.
Specify application details in the UI
In Datadog, navigate to Digital Experience > Add an Application.
Choose react-native
as the application type.
Provide an application name to generate a unique Datadog application ID and client token.
To disable automatic user data collection for either client IP or geolocation data, uncheck the boxes for those settings.
To ensure the safety of your data, you must use a client token. If you used only Datadog API keys to configure the @datadog/mobile-react-native
library, they would be exposed client-side in the React Native application’s code.
For more information about setting up a client token, see the Client Token documentation.
Initialize the library with application context
import {
DatadogProvider,
DatadogProviderConfiguration
} from '@datadog/mobile-react-native';
const config = new DatadogProviderConfiguration(
'<CLIENT_TOKEN>',
'<ENVIRONMENT_NAME>',
'<RUM_APPLICATION_ID>',
true, // track user interactions (such as a tap on buttons).
true, // track XHR resources
true // track errors
);
config.site = 'US1';
// Optional: Enable or disable native crash reports
config.nativeCrashReportEnabled = true;
// Optional: Sample RUM sessions (in this example, 80% of session are sent to Datadog. Default is 100%).
config.sessionSamplingRate = 80;
// Optional: Sample tracing integrations for network calls between your app and your backend (in this example, 80% of calls to your instrumented backend are linked from the RUM view to the APM view. Default is 20%)
// You need to specify the hosts of your backends to enable tracing with these backends
config.resourceTracingSamplingRate = 80;
config.firstPartyHosts = ['example.com']; // matches 'example.com' and subdomains like 'api.example.com'
// Optional: set the reported service name (by default, it uses the package name or bundleIdentifier of your Android or iOS app respectively)
config.serviceName = 'com.example.reactnative';
// Optional: let the SDK print internal logs above or equal to the provided level. Default is undefined (meaning no logs)
config.verbosity = SdkVerbosity.WARN;
//Wrap the content of your App component in a DatadogProvider component, passing it your configuration:
export default function App() {
return (
<DatadogProvider configuration={config}>
<Navigation />
</DatadogProvider>
);
}
// Once the Datadog React Native SDK for RUM is initialized, you need to setup view tracking to be able to see data in the RUM dashboard
import {
DatadogProvider,
DatadogProviderConfiguration
} from '@datadog/mobile-react-native';
const config = new DatadogProviderConfiguration(
'<CLIENT_TOKEN>',
'<ENVIRONMENT_NAME>',
'<RUM_APPLICATION_ID>',
true, // track user interactions (such as a tap on buttons).
true, // track XHR resources
true // track errors
);
config.site = 'US3';
// Optional: enable or disable native crash reports
config.nativeCrashReportEnabled = true;
// Optional: sample RUM sessions (here, 80% of session will be sent to Datadog. Default = 100%)
config.sessionSamplingRate = 80;
// Optional: sample tracing integrations for network calls between your app and your backend (here, 80% of calls to your instrumented backend will be linked from the RUM view to the APM view. Default = 20%)
// You need to specify the hosts of your backends to enable tracing with these backends
config.resourceTracingSamplingRate = 80;
config.firstPartyHosts = ['example.com']; // matches 'example.com' and subdomains like 'api.example.com'
//Wrap the content of your App component in a DatadogProvider component, passing it your configuration:
export default function App() {
return (
<DatadogProvider configuration={config}>
<Navigation />
</DatadogProvider>
);
}
// Once the Datadog React Native SDK for RUM is initialized, you need to setup view tracking to be able to see data in the RUM dashboard
import {
DatadogProvider,
DatadogProviderConfiguration
} from '@datadog/mobile-react-native';
const config = new DatadogProviderConfiguration(
'<CLIENT_TOKEN>',
'<ENVIRONMENT_NAME>',
'<RUM_APPLICATION_ID>',
true, // track User interactions (e.g.: Tap on buttons).
true, // track XHR Resources
true // track Errors
);
config.site = 'US5';
// Optional: enable or disable native crash reports
config.nativeCrashReportEnabled = true;
// Optional: sample RUM sessions (here, 80% of session will be sent to Datadog. Default = 100%)
config.sessionSamplingRate = 80;
// Optional: sample tracing integrations for network calls between your app and your backend (here, 80% of calls to your instrumented backend will be linked from the RUM view to the APM view. Default = 20%)
// You need to specify the hosts of your backends to enable tracing with these backends
config.resourceTracingSamplingRate = 80;
config.firstPartyHosts = ['example.com']; // matches 'example.com' and subdomains like 'api.example.com'
//Wrap the content of your App component in a DatadogProvider component, passing it your configuration:
export default function App() {
return (
<DatadogProvider configuration={config}>
<Navigation />
</DatadogProvider>
);
}
// Once the Datadog React Native SDK for RUM is initialized, you need to setup view tracking to be able to see data in the RUM dashboard
import {
DatadogProvider,
DatadogProviderConfiguration
} from '@datadog/mobile-react-native';
const config = new DatadogProviderConfiguration(
'<CLIENT_TOKEN>',
'<ENVIRONMENT_NAME>',
'<RUM_APPLICATION_ID>',
true, // track User interactions (e.g.: Tap on buttons).
true, // track XHR Resources
true // track Errors
);
config.site = 'EU1';
// Optional: enable or disable native crash reports
config.nativeCrashReportEnabled = true;
// Optional: sample RUM sessions (here, 80% of session will be sent to Datadog. Default = 100%)
config.sessionSamplingRate = 80;
// Optional: sample tracing integrations for network calls between your app and your backend (here, 80% of calls to your instrumented backend will be linked from the RUM view to the APM view. Default = 20%)
// You need to specify the hosts of your backends to enable tracing with these backends
config.resourceTracingSamplingRate = 80;
config.firstPartyHosts = ['example.com']; // matches 'example.com' and subdomains like 'api.example.com'
//Wrap the content of your App component in a DatadogProvider component, passing it your configuration:
export default function App() {
return (
<DatadogProvider configuration={config}>
<Navigation />
</DatadogProvider>
);
}
// Once the Datadog React Native SDK for RUM is initialized, you need to setup view tracking to be able to see data in the RUM dashboard
import {
DatadogProvider,
DatadogProviderConfiguration
} from '@datadog/mobile-react-native';
const config = new DatadogProviderConfiguration(
'<CLIENT_TOKEN>',
'<ENVIRONMENT_NAME>',
'<RUM_APPLICATION_ID>',
true, // track User interactions (e.g.: Tap on buttons).
true, // track XHR Resources
true // track Errors
);
config.site = 'US1_FED';
// Optional: enable or disable native crash reports
config.nativeCrashReportEnabled = true;
// Optional: sample RUM sessions (here, 80% of session will be sent to Datadog. Default = 100%)
config.sessionSamplingRate = 80;
// Optional: sample tracing integrations for network calls between your app and your backend (here, 80% of calls to your instrumented backend will be linked from the RUM view to the APM view. Default = 20%)
// You need to specify the hosts of your backends to enable tracing with these backends
config.resourceTracingSamplingRate = 80;
config.firstPartyHosts = ['example.com']; // matches 'example.com' and subdomains like 'api.example.com'
//Wrap the content of your App component in a DatadogProvider component, passing it your configuration:
export default function App() {
return (
<DatadogProvider configuration={config}>
<Navigation />
</DatadogProvider>
);
}
// Once the Datadog React Native SDK for RUM is initialized, you need to setup view tracking to be able to see data in the RUM dashboard
Sample RUM sessions
To control the data your application sends to Datadog RUM, you can specify a sampling rate for RUM sessions while initializing the RUM React Native SDK as a percentage between 0 and 100. You can specify the rate with the config.sessionSamplingRate
parameter.
Set tracking consent (GDPR compliance)
To be compliant with the GDPR regulation, the RUM React Native SDK requires the tracking consent value at initialization.
The trackingConsent
setting can be one of the following values:
.PENDING
: The RUM React Native SDK starts collecting and batching the data but does not send it to Datadog. The RUM iOReact NativeS SDK waits for the new tracking consent value to decide what to do with the batched data..GRANTED
: The RUM React Native SDK starts collecting the data and sends it to Datadog..NOTGRANTED
: The RUM iReact NativeOS SDK does not collect any data. No logs, traces, or RUM events are sent to Datadog.
To change the tracking consent value after the RUM React Native SDK is initialized, use the Datadog.set(trackingConsent:)
API call. The RUM React Native SDK changes its behavior according to the new value.
For example, if the current tracking consent is .PENDING
:
- If you change the value to
.GRANTED
, the RUM React Native SDK sends all current and future data to Datadog; - If you change the value to
.NOTGRANTED
, the RUM React Native SDK wipes all current data and does not collect future data.
Override the reported version
By default, the Datadog React Native SDK reports the version
as the commercial version of your app (for example, “1.2.44”).
If you use an Over The Air (OTA) updates provider like Microsoft’s CodePush, you can override this version to indicate which version of your JavaScript code is running.
Datadog recommends using a versionSuffix
to the DatadogProviderConfiguration
object:
const config = new DatadogProviderConfiguration(
'<CLIENT_TOKEN>',
'<ENVIRONMENT_NAME>',
'<RUM_APPLICATION_ID>',
true,
true,
true
);
config.versionSuffix = 'codepush.3';
If the commercial version of your app is “1.2.44”, it is reported as “1.2.44-codepush.3” in Datadog. A dash (-
) is automatically added between the version and the suffix.
You can also completely override the version by specifying the version
field. However, make sure you set it correctly, as it has to match the one specified during the upload of your source maps and other mapping files.
For more information about limitations on the version field, see the Tags documentation.
User interactions tracking
If user interactions tracking is enabled as in the code example above, the Datadog React Native SDK traverses up the hierarchy of components starting from the component that received a tap, looking for dd-action-name
property. Once found, it is used as a name for the action reported.
Alternatively, you can use the accessibilityLabel
element property to give the tap action a name; otherwise, the element type is reported. You can check the sample app for usage examples.
Track view navigation
Because React Native offers a wide range of libraries to create screen navigation, only manual view tracking is supported by default. To see RUM sessions populate in Datadog, you need to implement view tracking.
You can manually start and stop a view using the following startView()
and stopView
methods.
import {
DdRum
} from '@datadog/mobile-react-native';
// Start a view with a unique view identifier, a custom view name, and an object to attach additional attributes to the view
DdRum.startView(
'<view-key>', // <view-key> has to be unique, for example it can be ViewName-unique-id
'View Name',
{ 'custom.foo': 'something' },
Date.now()
);
// Stops a previously started view with the same unique view identifier, and an object to attach additional attributes to the view
DdRum.stopView('<view-key>', { 'custom.bar': 42 }, Date.now());
Use one of Datadog’s integrations to automatically track views for the following libraries:
If you experience any issues setting up View tracking with @datadog/mobile-react-navigation
you can see this Datadog example application as a reference.
Sending data when device is offline
RUM ensures availability of data when your user device is offline. In cases of low-network areas, or when the device battery is too low, all RUM events are first stored on the local device in batches. They are sent as soon as the network is available, and the battery is high enough to ensure the React Native RUM SDK does not impact the end user’s experience. If the network is not available with your application running in the foreground, or if an upload of data fails, the batch is kept until it can be sent successfully.
This means that even if users open your application while offline, no data is lost.
Note: The data on the disk is automatically deleted if it gets too old to ensure the React Native RUM SDK does not use too much disk space.
Track background events
Tracking background events may lead to additional sessions, which can impact billing. For questions, contact Datadog support.
You can track events such as crashes and network requests when your application is in the background (for example, when no active view is available).
Add the following snippet during initialization in your Datadog configuration:
configuration.trackBackgroundEvents = true;
Data Storage
Android
Before data is uploaded to Datadog, it is stored in cleartext in your application’s cache directory. This cache folder is protected by Android’s Application Sandbox, meaning that on most devices this data can’t be read by other applications. However, if the mobile device is rooted, or someone tampers with the Linux kernel, the stored data might become readable.
iOS
Before data is uploaded to Datadog, it is stored in cleartext in the cache directory (Library/Caches
) of your application sandbox, which can’t be read by any other app installed on the device.
Development mode
While in development mode, your application can submit extra events related to the React Native tooling, such as code transformation errors and requests to a local development server.
To prevent these events from showing in the dashboard, you can disable errors and resources tracking in dev mode using the __DEV__
flag:
const config = new DatadogProviderConfiguration(
CLIENT_TOKEN,
ENVIRONMENT,
APPLICATION_ID,
true,
!__DEV__ /* trackResources will be false in DEV mode, true otherwise */,
!__DEV__ /* trackErrors will be false in DEV mode, true otherwise */,
trackingConsent
)
New architecture support
The React Native new architecture is supported by the RUM React Native SDK in version >=1.8.0
.
The minimum supported React Native version for the new architecture is 0.71
.
Troubleshooting
Usage with use_frameworks!
If you have use_frameworks!
enabled in your Podfile
, running pod install
after adding the SDK is likely to trigger an error like this one:
The 'Pods-MyApp' target has transitive dependencies that include statically linked binaries: (DatadogSDKBridge, DatadogSDKCrashReporting)
To prevent that error, edit your Podfile
to install the React Native SDK pod as a static library:
static_libraries = ['DatadogSDKReactNative']
# Turn pods with static dependencies into static libraries by overriding the static_framework? function to return true
pre_install do |installer|
installer.pod_targets.each do |pod|
if static_libraries.include?(pod.name)
def pod.static_framework?;
true
end
def pod.build_type;
Pod::BuildType.static_library
end
end
end
end
Note: This solution comes from this StackOverflow post.
Further Reading
Additional helpful documentation, links, and articles: