Manually instrument React Native applications
Manually instrument React Native applications to collect additional telemetry, sanitize personally identifiable information, add global attributes, and more.
When adding custom attributes to Splunk RUM data, prefix each attribute name with a string unique to your application or organization to prevent overlap with internal Splunk RUM attributes. For example, use tmo.session.id instead of session.id. Overwriting an internal RUM attribute can affect how telemetry is processed or associated with sessions. This guidance applies to global attributes, span attributes, and attributes added to custom events or workflows.
Manage global attributes
Global attributes are key-value pairs added to all reported data. Global attributes are useful for reporting application- or user-specific values as tags. The following examples show how to define global attributes:
-
To add metadata during agent initialization:
TYPESCRIPT<SplunkRumProvider agentConfiguration={{ endpoint: { realm: 'your-splunk-realm', rumAccessToken: 'your-splunk-rum-access-token', }, appName: 'your-application-name', deploymentEnvironment: 'your-environment-name', globalAttributes: { 'app.region': 'us-east', 'app.build': 123, }, }} > <AppRoot /> </SplunkRumProvider> -
To add metadata after agent initialization:
TYPESCRIPTimport { SplunkRum } from '@splunk/otel-react-native'; const attrs = SplunkRum.instance.globalAttributes; await attrs.setString('user.id', '123'); await attrs.setNumber('cart.items', 3); await attrs.setAllInNamespace('device', { model: 'iPhone', os: 'iOS', });
Track users
By default, the Splunk RUM React Native agent uses NO_TRACKING. To activate anonymous user tracking:
import { SplunkRum } from '@splunk/otel-react-native';
await SplunkRum.instance.user.preferences.setTrackingMode('ANONYMOUS_TRACKING');
Report custom events and workflows
You can report custom events and workflows happening in your application using the trackCustomEvent and trackWorkflow APIs. Additionally, you have the option to set custom attributes. See example below:
import { SplunkRum } from '@splunk/otel-react-native';
await SplunkRum.instance.customTracking.trackCustomEvent('checkout_complete', {
'order.total': 99.99,
'order.items': 3,
});
The following example shows how to start a workflow for which metrics are recorded by Splunk RUM:
const workflow = await SplunkRum.instance.customTracking.startWorkflow('checkout');
// ... perform checkout steps ...
await workflow.end();
Get agent and session state
You can inspect the current state of the agent and the active session:
const state = await SplunkRum.instance.getState();
const session = await SplunkRum.instance.session.state();
WebView integration (browser RUM correlation)
Use SplunkWebView to integrate browser RUM running inside a WebView with the native RUM session:
import { WebView } from 'react-native-webview';
import { SplunkWebView } from '@splunk/otel-react-native';
<SplunkWebView
WebViewComponent={WebView}
source={{ uri: 'https://example.com' }}
/>;
For manual integration, call integrateWebViewWithBrowserRum once you have the native view tag:
import { WebView } from 'react-native-webview';
import { SplunkRum } from '@splunk/otel-react-native';
const webViewRef = useRef<WebView>(null);
const onLoadEnd = () => {
const nativeRef = (webViewRef.current as any)?.webViewRef?.current;
const viewTag = nativeRef?._nativeTag;
if (viewTag) {
SplunkRum.instance.integrateWebViewWithBrowserRum(viewTag);
}
};
<WebView
ref={webViewRef}
onLoadEnd={onLoadEnd}
source={{ uri: 'https://example.com' }}
/>;
Track native screens automatically
Activity and Fragment instances or iOS UIViewController instances:
import { NavigationModuleConfiguration } from '@splunk/otel-react-native';
const modules = [
new NavigationModuleConfiguration(
true, // Enable the navigation module
true, // Enable native automatic tracking
),
];
await SplunkRum.install(agentConfiguration, modules);
Add server trace context from Splunk APM
The Splunk RUM React Native agent collects server trace context using back-end data provided by Splunk APM instrumentation through the Server-Timing header. In some cases, you might want to generate the header manually.
To create the Server-Timing header manually, provide a Server-Timing header with the name traceparent, where the desc field holds the version, the trace ID, the parent ID, and the trace flag.
Consider the following HTTP header:
Server-Timing: traceparent;desc="00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
The example resolves to a context containing the following data:
version=00 trace-id=4bf92f3577b34da6a3ce929d0e0e4736parent-id=00f067aa0ba902b7 trace-flags=01
When generating a value for the traceparent header, make sure that it matches the following regular expression:
00-([0-9a-f]{32})-([0-9a-f]{16})-01
Server timing headers with values that don't match the pattern are automatically discarded. For more information, see the Server-Timing and traceparent documentation on the W3C website.
If multiple valid Server-Timing headers are found, the last valid one is used.
Report errors manually
Report errors that your application catches, such as errors in a catch block, an error boundary, or a handled promise rejection, by calling trackError. Configure automatic crash and error capture separately through module configuration.
Each reported error creates a Real User Monitoring (RUM) span with component=error. The span includes the error type, message, source, and handled state. Reports created from an Error object also include the JavaScript stack trace when one is available. You can attach custom attributes to the span.
Report a caught error
Pass the caught Error object to trackError, as shown in the following example:
import { SplunkRum } from '@splunk/otel-react-native';
try {
await riskyOperation();
} catch (e) {
await SplunkRum.instance.customTracking.trackError(e as Error);
}
The agent derives the error type from the error's name or constructor name, reads the message from error.message, and records the JavaScript stack trace from error.stack without modification.
You can report an error from a message string when you don't have an Error object. A string report doesn't include a stack trace.
await SplunkRum.instance.customTracking.trackError('Cart is empty');
The returned Promise resolves if reporting fails, and the agent logs the failure. The method doesn't consume or modify the error. Before SDK installation, the call resolves without reporting an error.
Add attributes to an error
Attach custom attributes to add application context to the error span:
try {
await checkout(cart);
} catch (e) {
await SplunkRum.instance.customTracking.trackError(e as Error, {
attributes: {
'checkout.step': 'payment',
'cart.items': 3,
},
});
}
Mark an error as unhandled
By default, the agent reports an error as handled and nonfatal. Set handled: false when an error escapes your code. The error span records exception.escaped=true.
await SplunkRum.instance.customTracking.trackError(e as Error, {
handled: false,
});