@dynatrace/react-native-plugin 2.343.1 → 2.347.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +674 -656
- package/android/build.gradle +6 -2
- package/android/src/main/java/com/dynatrace/android/agent/DynatraceRNBridgeImpl.kt +24 -0
- package/files/plugin-runtime.gradle +17 -33
- package/files/plugin.gradle +1 -1
- package/instrumentation/BabelPluginDynatrace.js +1 -1
- package/instrumentation/libs/UserInteraction.js +20 -6
- package/instrumentation/libs/react-native/Lists.js +94 -0
- package/instrumentation/libs/react-native/index.js +4 -1
- package/instrumentation/libs/react-native.js +3 -0
- package/instrumentation/libs/react-navigation/ReactNavigation.js +14 -58
- package/instrumentation/libs/withOnPressMonitoring.js +3 -54
- package/internal.d.ts +2 -0
- package/internal.js +5 -1
- package/ios/DynatraceRNBridge.mm +37 -1
- package/lib/core/configuration/ConfigurationHandler.js +0 -21
- package/lib/core/logging/LogMessages.js +50 -0
- package/lib/dynatrace-reporter.js +1 -30
- package/lib/dynatrace-transformer.js +6 -34
- package/lib/next/configuration/INativeRuntimeConfiguration.js +0 -1
- package/lib/next/configuration/RuntimeConfigurationObserver.js +1 -6
- package/lib/next/events/spec/EventSpecContstants.js +1 -1
- package/lib/next/navigation/NavigationTracker.js +101 -0
- package/lib/next/navigation/useNavigationTracking.js +54 -0
- package/lib/next/triggers/TableReloadTracker.js +23 -0
- package/package.json +11 -21
- package/public.js +3 -1
- package/react-native-dynatrace.podspec +1 -1
- package/scripts/Android.js +1 -20
- package/scripts/Config.js +0 -4
- package/scripts/Deprecations.js +18 -0
- package/scripts/Install.js +13 -0
- package/scripts/PathsConstants.js +0 -4
- package/scripts/Uninstall.js +0 -15
- package/scripts/core/InstrumentCall.js +2 -3
- package/scripts/util/DeprecationReport.js +24 -0
- package/types.d.ts +212 -10
- package/instrumentation/DynatraceInstrumentation.js +0 -1
- package/instrumentation/libs/community/Picker.InstrInfo.js +0 -20
- package/instrumentation/libs/community/gesture-handler/Touchables.InstrInfo.js +0 -25
- package/instrumentation/libs/react-native/RefreshControl.InstrInfo.js +0 -12
- package/instrumentation/libs/react-native/Switch.InstrInfo.js +0 -12
- package/instrumentation/libs/react-native/Touchables.InstrInfo.js +0 -25
- package/instrumentation/model/Reference.js +0 -2
- package/instrumentation/parser/Babel.js +0 -60
- package/instrumentation/parser/ParserUtil.js +0 -11
- package/lib/features/ui-interaction/Config.js +0 -42
- package/lib/features/ui-interaction/IUserInteractionEvent.js +0 -16
- package/lib/features/ui-interaction/Plugin.Fragment.Test.js +0 -170
- package/lib/features/ui-interaction/Plugin.js +0 -289
- package/lib/features/ui-interaction/RootDetection.js +0 -51
- package/lib/features/ui-interaction/RootWrapper.js +0 -236
- package/lib/features/ui-interaction/Run.js +0 -38
- package/lib/features/ui-interaction/Runtime.js +0 -843
- package/lib/features/ui-interaction/TouchMetaResolver.js +0 -493
- package/lib/features/ui-interaction/Types.js +0 -14
- package/lib/metro/getSourceMapInfo.js +0 -26
- package/scripts/LineOffsetAnalyze.js +0 -25
- package/scripts/core/LineOffsetAnalyzeCall.js +0 -165
- package/scripts/util/SourceMapUtil.js +0 -68
package/README.md
CHANGED
|
@@ -35,8 +35,8 @@ If you want to start using this plugin and are not a Dynatrace customer yet, hea
|
|
|
35
35
|
## Agent Versions
|
|
36
36
|
These agent versions are configured in this plugin:
|
|
37
37
|
|
|
38
|
-
* Android Agent: 8.
|
|
39
|
-
* iOS Agent: 8.
|
|
38
|
+
* Android Agent: 8.347.1.1003
|
|
39
|
+
* iOS Agent: 8.347.1.1004
|
|
40
40
|
|
|
41
41
|
## Quick Setup
|
|
42
42
|
|
|
@@ -48,36 +48,36 @@ These agent versions are configured in this plugin:
|
|
|
48
48
|
|
|
49
49
|
## Advanced topics
|
|
50
50
|
* [Manual OneAgent Startup](#manual-oneagent-startup)
|
|
51
|
-
* [
|
|
52
|
-
* [
|
|
51
|
+
* [Real User Monitoring (RUM)](#real-user-monitoring-rum)
|
|
52
|
+
* [User Interaction](#user-interaction)
|
|
53
|
+
* [Send Event](#send-event)
|
|
54
|
+
* [Send Session Property Event](#send-session-property-event)
|
|
55
|
+
* [Event Modifier](#event-modifier)
|
|
56
|
+
* [Send Exception Event](#send-exception-event)
|
|
57
|
+
* [Send HTTP Request Event](#send-http-request-event)
|
|
58
|
+
* [View Monitoring](#view-monitoring)
|
|
59
|
+
* [App start user action](#app-start-user-action)
|
|
60
|
+
* [React Native Symbolication](#react-native-symbolication)
|
|
61
|
+
* [RUM Classic](#rum-classic)
|
|
53
62
|
* [Monitor a Component](#monitor-a-component)
|
|
54
63
|
* [Create Custom Action](#create-custom-actions)
|
|
55
64
|
* [Cancel Actions](#cancel-actions)
|
|
56
65
|
* [Manual Web Request Tagging](#manual-web-request-tagging)
|
|
57
66
|
* [Report Values](#report-values)
|
|
58
67
|
* [Report Stacktrace](#report-an-error-stacktrace)
|
|
59
|
-
* [Identify User](#identify-a-user)
|
|
60
|
-
* [End Session](#end-the-current-user-session)
|
|
61
68
|
* [Crash Reporting](#manually-report-a-crash)
|
|
62
|
-
* [User Privacy Options](#user-privacy-options)
|
|
63
69
|
* [Report GPS Position](#report-gps-location)
|
|
64
70
|
* [Business event capturing](#business-event-capturing)
|
|
65
71
|
* [Platform independent reporting](#platform-independent-reporting)
|
|
66
72
|
* [Set beacon headers](#setting-beacon-headers)
|
|
67
73
|
* [Exclude Individual JSX Elements](#exclude-individual-jsx-elements)
|
|
68
|
-
* [
|
|
69
|
-
* [User
|
|
70
|
-
* [
|
|
71
|
-
* [
|
|
72
|
-
* [Event Modifier](#event-modifier)
|
|
73
|
-
* [Send Exception Event](#send-exception-event)
|
|
74
|
-
* [Send HTTP Request Event](#send-http-request-event)
|
|
75
|
-
* [View Monitoring](#view-monitoring)
|
|
76
|
-
* [React Native Symbolication](#react-native-symbolication)
|
|
74
|
+
* [Extended topics](#extended-topics)
|
|
75
|
+
* [Identify User](#identify-a-user)
|
|
76
|
+
* [End Session](#end-the-current-user-session)
|
|
77
|
+
* [User Privacy Options](#user-privacy-options)
|
|
77
78
|
* [NPX Commands](#npx-commands)
|
|
78
79
|
* [npx instrumentDynatrace](#npx-instrumentdynatrace)
|
|
79
80
|
* [npx configDynatrace](#npx-configdynatrace)
|
|
80
|
-
* [npx lineOffsetDynatrace](#npx-lineoffsetdynatrace)
|
|
81
81
|
* [Customizing paths for configuration](#customizing-paths-for-configuration)
|
|
82
82
|
* [Manual adding iOS Agent to project](#manually-adding-ios-oneagent-to-a-project)
|
|
83
83
|
* [Setup for tvOS](#setup-for-tvos)
|
|
@@ -91,10 +91,8 @@ These agent versions are configured in this plugin:
|
|
|
91
91
|
* [Autostart](#autostart)
|
|
92
92
|
* [Bundle Name and Version](#bundle-name-and-version)
|
|
93
93
|
* [Navigation](#navigation)
|
|
94
|
-
* [Source Map](#source-map)
|
|
95
94
|
* [User Interaction Configuration](#user-interaction-configuration)
|
|
96
95
|
* [Debugging our auto-instrumentation](#debugging-our-auto-instrumentation)
|
|
97
|
-
* [Using our legacy jscodeshift auto-instrumentation](#using-our-legacy-jscodeshift-auto-instrumentation)
|
|
98
96
|
* [Android block](#android-block)
|
|
99
97
|
* [iOS block](#ios-block)
|
|
100
98
|
* [Lifecycle modes](#lifecycle)
|
|
@@ -221,31 +219,7 @@ module.exports = {
|
|
|
221
219
|
};
|
|
222
220
|
```
|
|
223
221
|
|
|
224
|
-
2.
|
|
225
|
-
|
|
226
|
-
Example of a startup call:
|
|
227
|
-
|
|
228
|
-
```ts
|
|
229
|
-
import { Dynatrace, ConfigurationBuilder } from '@dynatrace/react-native-plugin';
|
|
230
|
-
|
|
231
|
-
await Dynatrace.start(new ConfigurationBuilder("beaconUrl", "applicationId").buildConfiguration());
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
For more details see the section about [startup API](#plugin-startup).
|
|
235
|
-
|
|
236
|
-
**Note**: If you don't deactivate the automated startup with the `dynatrace.config.js` file, the `beaconUrl` and `applicationId` values have no impact and are thrown away.
|
|
237
|
-
|
|
238
|
-
## Manual instrumentation
|
|
239
|
-
|
|
240
|
-
To use the API of the React Native plugin, import the API:
|
|
241
|
-
|
|
242
|
-
```ts
|
|
243
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### Plugin startup
|
|
247
|
-
|
|
248
|
-
The manual startup of the plugin is triggered via the `start(configuration: IConfiguration)` method. If you configured `dynatrace.config.js` for manual startup then the plugin doesn't send any data when not calling this function. Besides the application id and the beacon URL, there are several optional configuration parameters, which are shown in the table below.
|
|
222
|
+
2. Call `Dynatrace.start()` with your configuration. The startup call is triggered via the `start(configuration: IConfiguration)` method — if you configured `dynatrace.config.js` for manual startup, the plugin doesn't send any data until this function is called. At minimum you need `beaconUrl` and `applicationId`, but there are several optional configuration parameters as well:
|
|
249
223
|
|
|
250
224
|
```ts
|
|
251
225
|
import { Dynatrace, ConfigurationBuilder, LogLevel } from '@dynatrace/react-native-plugin';
|
|
@@ -265,6 +239,8 @@ configurationBuilder.withCrashReporting(true)
|
|
|
265
239
|
await Dynatrace.start(configurationBuilder.buildConfiguration());
|
|
266
240
|
```
|
|
267
241
|
|
|
242
|
+
**Note**: If you don't deactivate the automated startup with the `dynatrace.config.js` file, the `beaconUrl` and `applicationId` values have no impact and are thrown away.
|
|
243
|
+
|
|
268
244
|
**Info**: The value used in the function calls for the parameters is also their default value.
|
|
269
245
|
|
|
270
246
|
| Property name | Type | Default | Description |
|
|
@@ -282,866 +258,899 @@ await Dynatrace.start(configurationBuilder.buildConfiguration());
|
|
|
282
258
|
|actionNameAlgorithm |string |'depth-first' |Controls the traversal algorithm used when searching the component tree for the name of an `onPress` action. `'depth-first'` follows the first child branch fully before trying siblings. `'breadth-first'` visits all siblings at a level before going deeper, returning the shallowest match first.|
|
|
283
259
|
|bundleName |string |undefined |Should be used only if you have a multiple bundle setup where you load several .bundle files within your React Native application. Enter the name of your bundle. This should be unique in comparison to your other bundle names. This will ensure that actions coming from different bundles will not interfere with each other.
|
|
284
260
|
|
|
285
|
-
**Attention:**
|
|
261
|
+
**Attention:**
|
|
286
262
|
* Keep in mind that configuration within the `dynatrace.config.js` file is the basis, even for manual startup. When we look at the lifecycleUpdate property: Per default if not used, it is false. If enabled (set to true) in `dynatrace.config.js` file, this will be also true if manual startup is used. You can still override this behavior by calling `ConfigurationBuilder.withLifecycleUpdate(false)`.
|
|
287
263
|
* Please use those parameters only when doing a manual startup. If you want to do an automated startup, please configure the properties via the [auto startup configuration](#manual-startup-counterparts). You will find a list which explains all the counterparts for the available options here.
|
|
288
264
|
|
|
289
|
-
|
|
265
|
+
## Real User Monitoring (RUM)
|
|
290
266
|
|
|
291
|
-
|
|
267
|
+
Real User Monitoring introduces a set of advanced APIs that allow you to send custom events, modify event data, track exceptions, monitor HTTP requests, and manage view contexts in your React Native application. These APIs provide more granular control over the data captured by Dynatrace and are designed for the next generation RUM capabilities.
|
|
292
268
|
|
|
293
|
-
|
|
269
|
+
For more detailed information about Real User Monitoring, see the [official Dynatrace documentation](https://docs.dynatrace.com/docs/shortlink/react-native-main).
|
|
294
270
|
|
|
295
|
-
|
|
296
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
297
|
-
import { FunctionComponent } from 'react';
|
|
271
|
+
### Send Event
|
|
298
272
|
|
|
299
|
-
|
|
300
|
-
return null;
|
|
301
|
-
}
|
|
273
|
+
The `sendEvent()` method allows you to send custom events with arbitrary properties using the EventData class. This is useful for tracking specific user interactions or application state changes.
|
|
302
274
|
|
|
303
|
-
|
|
275
|
+
```ts
|
|
276
|
+
import { Dynatrace, EventData } from '@dynatrace/react-native-plugin';
|
|
277
|
+
|
|
278
|
+
// Send a custom event with properties
|
|
279
|
+
Dynatrace.sendEvent(new EventData()
|
|
280
|
+
.addEventProperty("event_properties.button_clicked", "login_button")
|
|
281
|
+
.addEventProperty("event_properties.user_type", "premium")
|
|
282
|
+
.addEventProperty("event_properties.attempt_count", 3)
|
|
283
|
+
.withDuration(250)
|
|
284
|
+
);
|
|
304
285
|
```
|
|
305
|
-

|
|
306
286
|
|
|
307
|
-
|
|
287
|
+
**Property Requirements:**
|
|
288
|
+
* Only properties prefixed with `event_properties.*` are allowed
|
|
289
|
+
* Additionally, the `duration` property is allowed
|
|
290
|
+
* Maximum of 50 custom properties per event
|
|
291
|
+
* If the limit is exceeded, properties are sorted alphabetically by key and excess properties are dropped deterministically
|
|
292
|
+
* String properties are limited to 5000 characters (exceeding characters are truncated)
|
|
293
|
+
* Field names must contain only alphabetic characters, numbers, underscores, and dots
|
|
294
|
+
* Each dot must be followed by an alphabetic character
|
|
295
|
+
* Each underscore must be followed by an alphabetic character or number
|
|
296
|
+
* Values must be primitive types (string, number, boolean)
|
|
297
|
+
* Cannot contain functions, undefined, Infinity, or NaN as values (they will be replaced with null)
|
|
308
298
|
|
|
309
|
-
|
|
299
|
+
### Send Session Property Event
|
|
310
300
|
|
|
311
|
-
|
|
301
|
+
Session properties apply to all events within the current session. Use `sendSessionPropertyEvent()` to set properties that should be available across the entire user session.
|
|
312
302
|
|
|
313
|
-
|
|
303
|
+
```ts
|
|
304
|
+
import { Dynatrace, SessionPropertyEventData } from '@dynatrace/react-native-plugin';
|
|
314
305
|
|
|
315
|
-
|
|
306
|
+
// Set session-wide properties
|
|
307
|
+
Dynatrace.sendSessionPropertyEvent(new SessionPropertyEventData()
|
|
308
|
+
.addSessionProperty("session_properties.user_tier", "premium")
|
|
309
|
+
.addSessionProperty("session_properties.app_version", "2.1.0")
|
|
310
|
+
.addSessionProperty("session_properties.feature_flag_enabled", true)
|
|
311
|
+
);
|
|
312
|
+
```
|
|
316
313
|
|
|
317
|
-
|
|
314
|
+
**Important Notes:**
|
|
315
|
+
* Session properties persist throughout the entire session
|
|
316
|
+
* If you send the same property multiple times, only one value will be kept (first or last)
|
|
317
|
+
* Use session properties for data that applies to the entire user session
|
|
318
|
+
* Field naming follows the same rules as events, but with `session_properties.` prefix
|
|
319
|
+
* Maximum of 50 custom properties per event
|
|
320
|
+
* If the limit is exceeded, properties are sorted alphabetically by key and excess properties are dropped deterministically
|
|
318
321
|
|
|
319
|
-
|
|
320
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
322
|
+
### Event Modifier
|
|
321
323
|
|
|
322
|
-
|
|
323
|
-
//Perform the action and whatever else is needed.
|
|
324
|
-
myAction.leaveAction();
|
|
325
|
-
```
|
|
326
|
-

|
|
324
|
+
Event modifiers allow you to intercept and modify events before they are sent to Dynatrace. This is useful for adding common properties, filtering sensitive data, or enriching events with additional context. Event modifiers apply to all event types, including custom events, session properties, exceptions, and HTTP events.
|
|
327
325
|
|
|
328
|
-
|
|
326
|
+
If multiple event modifiers are added, they are executed in the order they were added.
|
|
329
327
|
|
|
330
|
-
|
|
331
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
328
|
+
Most fields and namespaces can't be modified in any way (added, removed or overridden), while others are open for modification.
|
|
332
329
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
```
|
|
330
|
+
**Open for modification and can be added:**
|
|
331
|
+
- `event_properties.*`
|
|
332
|
+
- `session_properties.*`
|
|
337
333
|
|
|
338
|
-
|
|
334
|
+
`session_properties.*` are only allowed to be on a session property event.
|
|
335
|
+
|
|
336
|
+
**Open for modification only:**
|
|
337
|
+
- `url.full`
|
|
338
|
+
- `exception.stack_trace`
|
|
339
|
+
|
|
340
|
+
#### Example
|
|
339
341
|
|
|
340
342
|
```ts
|
|
341
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
343
|
+
import { Dynatrace, IEventModifier } from '@dynatrace/react-native-plugin';
|
|
342
344
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
345
|
+
// Create an event modifier
|
|
346
|
+
const myModifier: IEventModifier = {
|
|
347
|
+
modifyEvent(event) {
|
|
348
|
+
// Add common properties to all events
|
|
349
|
+
event["event_properties.app_build"] = "1.2.3";
|
|
350
|
+
event["event_properties.environment"] = "production";
|
|
351
|
+
|
|
352
|
+
// Return null to discard the event entirely
|
|
353
|
+
if (event["event_properties.ignore"] === true) {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return event;
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
// Add the modifier
|
|
362
|
+
Dynatrace.addEventModifier(myModifier);
|
|
363
|
+
|
|
364
|
+
// Remove the modifier when no longer needed
|
|
365
|
+
Dynatrace.removeEventModifier(myModifier);
|
|
346
366
|
```
|
|
347
367
|
|
|
348
|
-
|
|
368
|
+
#### Important Considerations
|
|
349
369
|
|
|
350
|
-
|
|
370
|
+
- **Execution order**: If multiple event modifiers are added, they are executed in the order they were added
|
|
371
|
+
- **Returning null**: Returning `null` discards the event and prevents future modifier functions from being executed
|
|
372
|
+
- **Performance**: Event modifiers should be efficient as they are called for every event
|
|
373
|
+
- **Field naming**: Custom properties must follow the `event_properties.*` or `session_properties.*` prefix naming convention
|
|
374
|
+
- **Reserved fields**: Certain reserved fields and namespaces cannot be modified. Attempts to modify them will be ignored
|
|
375
|
+
- **Error handling**: If a modifier throws an exception, it will be logged but won't prevent other modifiers from executing
|
|
376
|
+
- **Primitive values**: Event fields can only contain primitive values (String, int, double, bool)
|
|
377
|
+
- **Invalid argument**: In case you pass an invalid argument to `addEventModifier`, we return a no-op placeholder modifier.
|
|
351
378
|
|
|
352
|
-
|
|
379
|
+
### Send Exception Event
|
|
380
|
+
|
|
381
|
+
The `sendExceptionEvent()` method provides a structured way to report exceptions with additional context and custom properties using the ExceptionEventData class.
|
|
353
382
|
|
|
354
383
|
```ts
|
|
355
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
384
|
+
import { Dynatrace, ExceptionEventData } from '@dynatrace/react-native-plugin';
|
|
356
385
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
386
|
+
try {
|
|
387
|
+
// Code that may throw an error
|
|
388
|
+
throw new Error('Something went wrong');
|
|
389
|
+
} catch (error) {
|
|
390
|
+
if (error instanceof Error) {
|
|
391
|
+
Dynatrace.sendExceptionEvent(new ExceptionEventData(error)
|
|
392
|
+
.addEventProperty('event_properties.custom_key', 'custom_value')
|
|
393
|
+
.addEventProperty('event_properties.error_context', 'user_action')
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
362
397
|
```
|
|
363
|
-

|
|
364
398
|
|
|
365
|
-
|
|
399
|
+
**Parameters:**
|
|
400
|
+
* `error`: The Error object containing exception information (required)
|
|
366
401
|
|
|
367
|
-
|
|
402
|
+
### Send HTTP Request Event
|
|
403
|
+
|
|
404
|
+
The `sendHttpRequestEvent()` method allows you to manually report HTTP request events with detailed information about the request and response.
|
|
368
405
|
|
|
369
406
|
```ts
|
|
370
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
407
|
+
import { Dynatrace, HttpRequestEventData } from '@dynatrace/react-native-plugin';
|
|
371
408
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
409
|
+
// Basic HTTP request event
|
|
410
|
+
const requestEventData = new HttpRequestEventData('https://api.example.com/users', 'GET');
|
|
411
|
+
Dynatrace.sendHttpRequestEvent(requestEventData);
|
|
375
412
|
|
|
376
|
-
//
|
|
377
|
-
|
|
413
|
+
// HTTP request with additional details
|
|
414
|
+
const detailedRequestEventData = new HttpRequestEventData('https://api.example.com/data', 'POST')
|
|
415
|
+
.withStatusCode(200)
|
|
416
|
+
.addEventProperty('event_properties.headers.content_type', 'application/json');
|
|
417
|
+
Dynatrace.sendHttpRequestEvent(detailedRequestEventData);
|
|
378
418
|
```
|
|
379
419
|
|
|
380
|
-
|
|
420
|
+
**Parameters:**
|
|
421
|
+
* `url`: The URL of the HTTP request (required)
|
|
422
|
+
* `method`: The HTTP method (e.g., 'GET', 'POST', 'PUT', 'DELETE') (required)
|
|
381
423
|
|
|
382
|
-
|
|
424
|
+
### View Monitoring
|
|
383
425
|
|
|
384
|
-
|
|
385
|
-
Using this API will force the request to be added to the action that is manually created.
|
|
426
|
+
The view monitoring APIs allow you to track different screens or views in your application, providing context for all events happening within those views.
|
|
386
427
|
|
|
387
|
-
|
|
388
|
-
|
|
428
|
+
There are two ways to monitor views:
|
|
429
|
+
1. **Automatic view monitoring** - Enable navigation tracking in your configuration to automatically capture view changes through supported navigation libraries (enabled by default)
|
|
430
|
+
2. **Manual view monitoring** - Use the `startView()` API to manually control when view contexts are created and updated
|
|
389
431
|
|
|
390
|
-
|
|
391
|
-
const url = 'https://api.example.com/data';
|
|
392
|
-
const tag = await action.getRequestTag(url);
|
|
393
|
-
const timing = new DynatraceWebRequestTiming(tag, url);
|
|
432
|
+
> **Important:** These approaches should not be mixed, as the outcome is unpredictable. Choose either automatic or manual view monitoring for your application.
|
|
394
433
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
timing.stopWebRequestTiming(-1, error.message);
|
|
406
|
-
} else {
|
|
407
|
-
timing.stopWebRequestTiming(-1, (error as any).toString());
|
|
434
|
+
#### Automatic Navigation tracking
|
|
435
|
+
|
|
436
|
+
> **Note:** This feature only works with `@react-navigation` versions 5.x through 7.x.
|
|
437
|
+
|
|
438
|
+
The following is an example of how this feature can be configured in your `dynatrace.config.js` file. Note that this feature is enabled by default.
|
|
439
|
+
|
|
440
|
+
```js
|
|
441
|
+
react: {
|
|
442
|
+
navigation: {
|
|
443
|
+
enabled: true
|
|
408
444
|
}
|
|
409
|
-
} finally {
|
|
410
|
-
action.leaveAction();
|
|
411
445
|
}
|
|
412
446
|
```
|
|
413
|
-

|
|
414
447
|
|
|
415
|
-
|
|
448
|
+
When this feature is enabled, the view context will represent the current state of the `@react-navigation` `NavigationContainer`. The state gets represented as a URL-style route. All subsequent events get associated with the view context and thus with the current route.
|
|
416
449
|
|
|
417
|
-
|
|
418
|
-
|
|
450
|
+
For instance, assume the following setup:
|
|
451
|
+
```js
|
|
452
|
+
const Drawer = createDrawerNavigator();
|
|
419
453
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
454
|
+
function App() {
|
|
455
|
+
return (
|
|
456
|
+
<NavigationContainer>
|
|
457
|
+
<Drawer.Navigator initialRouteName="Home">
|
|
458
|
+
<Drawer.Screen name="Home" component={HomeScreen} />
|
|
459
|
+
<Drawer.Screen name="Feature" component={FeatureScreen}/>
|
|
460
|
+
</Drawer.Navigator>
|
|
461
|
+
</NavigationContainer>
|
|
462
|
+
);
|
|
463
|
+
}
|
|
425
464
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
body: requestData
|
|
435
|
-
});
|
|
436
|
-
const responseData = await response.text();
|
|
437
|
-
timing.stopWebRequestTimingWithSize(
|
|
438
|
-
response.status,
|
|
439
|
-
response.statusText,
|
|
440
|
-
requestData.length,
|
|
441
|
-
responseData.length
|
|
465
|
+
const Stack = createStackNavigator();
|
|
466
|
+
|
|
467
|
+
function FeatureScreen() {
|
|
468
|
+
return (
|
|
469
|
+
<Stack.Navigator initialRouteName="ScreenOne">
|
|
470
|
+
<Stack.Screen name="ScreenOne" component={NestedScreenOne} />
|
|
471
|
+
<Stack.Screen name="ScreenTwo" component={NestedScreenTwo} />
|
|
472
|
+
</Stack.Navigator>
|
|
442
473
|
);
|
|
443
|
-
} catch (error) {
|
|
444
|
-
if (error instanceof Error) {
|
|
445
|
-
timing.stopWebRequestTiming(-1, error.message);
|
|
446
|
-
} else {
|
|
447
|
-
timing.stopWebRequestTiming(-1, (error as any).toString());
|
|
448
|
-
}
|
|
449
|
-
} finally {
|
|
450
|
-
action.leaveAction();
|
|
451
474
|
}
|
|
452
475
|
```
|
|
453
|
-

|
|
454
476
|
|
|
455
|
-
|
|
477
|
+
When navigating to `Home`, the view context will be set to `/Home`. When navigating to `Feature` and being redirected to the nested `ScreenOne`, the view context will be set to `/Home/ScreenOne`. When navigating to `ScreenTwo` within `Feature`, the view context will be set to `/Feature/ScreenTwo`.
|
|
456
478
|
|
|
457
|
-
|
|
479
|
+
#### Start View
|
|
480
|
+
|
|
481
|
+
Use `startView()` to begin monitoring a specific view or screen. When a view is started, all subsequent events will be associated with that view context.
|
|
458
482
|
|
|
459
483
|
```ts
|
|
460
|
-
import {
|
|
484
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
461
485
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
reportError(errorName: string, errorCode: number, platform?: Platform): void;
|
|
465
|
-
reportEvent(eventName: string, platform?: Platform): void;
|
|
466
|
-
reportIntValue(valueName: string, value: number, platform?: Platform): void;
|
|
467
|
-
reportStringValue(valueName: string, value: string, platform?: Platform): void;
|
|
468
|
-
}
|
|
486
|
+
// Start monitoring a view
|
|
487
|
+
Dynatrace.startView("HomeScreen");
|
|
469
488
|
```
|
|
470
489
|
|
|
471
|
-
**Important:**
|
|
490
|
+
**Important Considerations:**
|
|
491
|
+
* Only one view can be active at a time
|
|
492
|
+
* Starting a new view will automatically stop the previous one
|
|
493
|
+
* View names should be meaningful and consistent across your application
|
|
494
|
+
* All events captured after starting a view will include the view context
|
|
472
495
|
|
|
473
|
-
|
|
496
|
+
**Complete Example:**
|
|
474
497
|
|
|
475
498
|
```ts
|
|
476
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
499
|
+
import { Dynatrace, EventData } from '@dynatrace/react-native-plugin';
|
|
477
500
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
myAction.leaveAction();
|
|
481
|
-
```
|
|
482
|
-

|
|
501
|
+
// User navigates to profile screen
|
|
502
|
+
Dynatrace.startView("UserProfile");
|
|
483
503
|
|
|
484
|
-
|
|
504
|
+
// Send custom event within the view
|
|
505
|
+
Dynatrace.sendEvent(new EventData()
|
|
506
|
+
.addEventProperty("event_properties.profile_action", "edit_profile")
|
|
507
|
+
.addEventProperty("event_properties.changes_made", true)
|
|
508
|
+
);
|
|
485
509
|
|
|
510
|
+
// User navigates away
|
|
511
|
+
Dynatrace.startView("UserProfileDetailed");
|
|
512
|
+
```
|
|
486
513
|
|
|
487
|
-
###
|
|
514
|
+
### User Interaction
|
|
488
515
|
|
|
489
|
-
|
|
516
|
+
User Interaction is an automatic instrumentation feature that captures touch and press events in your React Native application without requiring any manual API calls. When enabled, the plugin instruments your UI components at build time and sends structured interaction events to Dynatrace at runtime.
|
|
490
517
|
|
|
491
|
-
|
|
492
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
518
|
+
The following is an example of how this feature can be configured in your `dynatrace.config.js` file. Note that this feature is enabled by default.
|
|
493
519
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
if (error instanceof Error) {
|
|
498
|
-
Dynatrace.reportErrorStacktrace(
|
|
499
|
-
'DatabaseError',
|
|
500
|
-
error.message,
|
|
501
|
-
'Failed to connect to remote database',
|
|
502
|
-
error.stack || 'No stack trace available'
|
|
503
|
-
);
|
|
504
|
-
}
|
|
520
|
+
```js
|
|
521
|
+
react: {
|
|
522
|
+
userInteraction: true
|
|
505
523
|
}
|
|
506
524
|
```
|
|
507
|
-

|
|
508
|
-
|
|
509
|
-
**Note:**
|
|
510
|
-
The previous API without *errorValue* is deprecated and will be removed in the future. Please use the new API with errorValue if possible.
|
|
511
525
|
|
|
512
|
-
|
|
526
|
+
When enabled, UI Interaction can be controlled by two layers:
|
|
513
527
|
|
|
514
|
-
|
|
528
|
+
1. **Build/config layer (`dynatrace.config.js`)**
|
|
529
|
+
- `react.userInteraction: true|false` controls whether the UI Interaction instrumentation feature is applied.
|
|
515
530
|
|
|
516
|
-
**
|
|
531
|
+
2. **Runtime remote layer**
|
|
532
|
+
- CP always forwards User Interaction Actions (UIA) to the native agent unconditionally. The native agent decides whether to record or discard each UIA based on its own remote configuration (e.g. `touch_interaction_enabled`).
|
|
517
533
|
|
|
518
|
-
|
|
519
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
534
|
+
#### Masking sensitive UI labels
|
|
520
535
|
|
|
521
|
-
|
|
522
|
-
```
|
|
523
|
-

|
|
536
|
+
UI Interaction also supports masking sensitive labels before events are sent.
|
|
524
537
|
|
|
525
|
-
|
|
538
|
+
Masking is applied when:
|
|
526
539
|
|
|
527
|
-
|
|
540
|
+
* the touched element or one of its parents is marked with `dtMask`
|
|
541
|
+
* the runtime masking rules classify the detected text as sensitive
|
|
542
|
+
* the runtime masking rules classify the element `testID` as sensitive
|
|
528
543
|
|
|
529
|
-
|
|
530
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
544
|
+
When masking is active:
|
|
531
545
|
|
|
532
|
-
|
|
533
|
-
|
|
546
|
+
* the interaction path and component information are still reported
|
|
547
|
+
* the detected UI label is replaced with the configured replacement string (default: `***`)
|
|
548
|
+
* `ui_element.name_origin` is reported as `masked`
|
|
534
549
|
|
|
535
|
-
|
|
550
|
+
Example using `dtMask`:
|
|
536
551
|
|
|
537
|
-
|
|
552
|
+
```tsx
|
|
553
|
+
<View dtMask>
|
|
554
|
+
<Pressable onPress={onPress}>
|
|
555
|
+
<Text>john.doe@example.com</Text>
|
|
556
|
+
</Pressable>
|
|
557
|
+
</View>
|
|
558
|
+
```
|
|
538
559
|
|
|
539
|
-
|
|
560
|
+
This allows you to preserve interaction analytics while avoiding exposure of sensitive text in the emitted UI Interaction event.
|
|
540
561
|
|
|
541
|
-
```ts
|
|
542
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
543
562
|
|
|
544
|
-
|
|
545
|
-
throw new Error('Fatal memory allocation failure');
|
|
546
|
-
} catch (error) {
|
|
547
|
-
if (error instanceof Error) {
|
|
548
|
-
Dynatrace.reportCrash(
|
|
549
|
-
'MemoryError',
|
|
550
|
-
error.message,
|
|
551
|
-
error.stack || 'No stack trace available'
|
|
552
|
-
);
|
|
563
|
+
#### Produced data
|
|
553
564
|
|
|
554
|
-
|
|
555
|
-
Dynatrace.reportCrashWithException('MemoryError', error);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
```
|
|
559
|
-

|
|
565
|
+
Each captured interaction produces an event describing what the user touched and where. The event includes:
|
|
560
566
|
|
|
561
|
-
|
|
567
|
+
- **Detected name** — the resolved label of the touched element, derived from its visible text, accessibility label, component name, or test ID.
|
|
568
|
+
- **Component** — the type of the UI component that was touched (e.g. `Pressable`).
|
|
569
|
+
- **Component Path** — a stable path through the component tree that uniquely identifies the element (e.g. `App/View[1]/Pressable[1]`).
|
|
570
|
+
- **Interaction type** — how the user interacted (e.g. `touch`).
|
|
571
|
+
- **Position** — the screen coordinates where the touch occurred.
|
|
562
572
|
|
|
563
|
-
|
|
573
|
+
In some cases, a **responder** is also included. The responder is the component that ultimately handled the user's touch — for example, a `Pressable` that received the press event. It carries the same name, component type, and path information as the touched element, and can differ when a touch is visually on a child element but handled by a parent.
|
|
564
574
|
|
|
565
|
-
|
|
575
|
+
If masking is active for an interaction, the event still contains the same structural information, but the detected name is replaced and the name origin changes to `masked`.
|
|
566
576
|
|
|
567
|
-
|
|
577
|
+
#### Example event
|
|
568
578
|
|
|
569
|
-
```
|
|
570
|
-
|
|
571
|
-
|
|
579
|
+
```json
|
|
580
|
+
{
|
|
581
|
+
"characteristics.has_user_interaction": true,
|
|
582
|
+
"ui_element.detected_name": "LoginButton",
|
|
583
|
+
"ui_element.components": ["Pressable"],
|
|
584
|
+
"ui_element.id": "App/View/Pressable",
|
|
585
|
+
"ui_element.name_origin": "component",
|
|
586
|
+
"interaction.type": "touch",
|
|
587
|
+
"positions": [{ "x": 120, "y": 460 }],
|
|
588
|
+
"ui_element.responder.detected_name": "Pressable",
|
|
589
|
+
"ui_element.responder.components": ["Pressable"],
|
|
590
|
+
"ui_element.responder.id": "App/View[/Pressable",
|
|
591
|
+
"ui_element.responder.name_origin": "component"
|
|
572
592
|
}
|
|
573
593
|
```
|
|
574
594
|
|
|
575
|
-
|
|
576
|
-
2. Performance: Native Agent captures only anonymous performance data. Monitoring data that can be used to identify individual users, such as user tags and custom values, aren't captured.
|
|
577
|
-
3. UserBehavior: Native Agent captures both performance and user data. In this mode, Native Agent recognizes and reports users who re-visit in future sessions.
|
|
595
|
+
#### Custom Names for Components
|
|
578
596
|
|
|
579
|
-
|
|
597
|
+
You can assign custom names to your components. A custom name affects both the **Component** and the **Component Path** described above. There are two ways to do this, depending on how the component is used.
|
|
580
598
|
|
|
581
|
-
|
|
599
|
+
##### 1. As a JSX prop (`dtActionName`)
|
|
582
600
|
|
|
583
|
-
|
|
584
|
-
import { Platform, UserPrivacyOptions } from '@dynatrace/react-native-plugin';
|
|
601
|
+
Use this when you render the component as JSX. Pass `dtActionName` as a prop, and it overrides the auto-detected name for that specific usage:
|
|
585
602
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
603
|
+
```tsx
|
|
604
|
+
<TouchableOpacity dtActionName="Checkout Button" onPress={onCheckout}>
|
|
605
|
+
<Text dtActionName="Checkout Text">Buy now</Text>
|
|
606
|
+
</TouchableOpacity>
|
|
590
607
|
```
|
|
591
608
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
```ts
|
|
595
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
609
|
+
Touching it produces:
|
|
596
610
|
|
|
597
|
-
|
|
611
|
+
```json
|
|
612
|
+
"ui_element.components": ["Checkout Text"],
|
|
613
|
+
"ui_element.id": ".../Checkout Button/Checkout Text"
|
|
598
614
|
```
|
|
599
615
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
```ts
|
|
603
|
-
import { Dynatrace, DataCollectionLevel, UserPrivacyOptions } from '@dynatrace/react-native-plugin';
|
|
616
|
+
##### 2. As a static property (`Component.dtActionName`)
|
|
604
617
|
|
|
605
|
-
|
|
618
|
+
Use this when the component is **not** rendered as JSX, so the prop approach above is not available — for example, a screen component you define once and hand to a navigator by reference. Set `dtActionName` directly on the component. This affects **every** place the component is used at once:
|
|
606
619
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
620
|
+
```tsx
|
|
621
|
+
import { NavigationContainer } from '@react-navigation/native';
|
|
622
|
+
import { createDrawerNavigator } from '@react-navigation/drawer';
|
|
610
623
|
|
|
611
|
-
const
|
|
612
|
-
const crashReporting = privacyConfig.crashReportingOptedIn;
|
|
624
|
+
const Drawer = createDrawerNavigator();
|
|
613
625
|
|
|
614
|
-
|
|
615
|
-
|
|
626
|
+
function ProfileScreen() {
|
|
627
|
+
return (/* ... */);
|
|
628
|
+
}
|
|
616
629
|
|
|
617
|
-
|
|
630
|
+
// Applies to all usages of ProfileScreen below
|
|
631
|
+
ProfileScreen.dtActionName = 'User Profile';
|
|
618
632
|
|
|
619
|
-
|
|
633
|
+
function App() {
|
|
634
|
+
return (
|
|
635
|
+
<NavigationContainer>
|
|
636
|
+
<Drawer.Navigator>
|
|
637
|
+
{/* Both screens reference the same component,
|
|
638
|
+
so both pick up the 'User Profile' name */}
|
|
639
|
+
<Drawer.Screen name="Me" component={ProfileScreen} />
|
|
640
|
+
<Drawer.Screen name="Account" component={ProfileScreen} />
|
|
641
|
+
</Drawer.Navigator>
|
|
642
|
+
</NavigationContainer>
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
```
|
|
620
646
|
|
|
621
|
-
|
|
622
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
647
|
+
Touches inside one of the 2 screens now produce:
|
|
623
648
|
|
|
624
|
-
|
|
649
|
+
```json
|
|
650
|
+
"ui_element.id": ".../User Profile/..."
|
|
625
651
|
```
|
|
626
652
|
|
|
627
|
-
|
|
653
|
+
> **Note:** The static property applies to *all* uses of the component. If you need a different name per usage, render the component as JSX and use the `dtActionName` prop (option 1) instead.
|
|
654
|
+
>
|
|
655
|
+
> **Note:** The static property has no effect when a component is rendered as JSX. In that case the name is taken from either the `dtActionName` prop passed to it (option 1) or the name of the JSX component.
|
|
628
656
|
|
|
629
|
-
|
|
630
|
-
* Passing to **iOS** only:
|
|
631
|
-
```ts
|
|
632
|
-
import { Dynatrace, Platform } from '@dynatrace/react-native-plugin';
|
|
657
|
+
### App start user action
|
|
633
658
|
|
|
634
|
-
|
|
635
|
-
//Perform the action and whatever else is needed.
|
|
636
|
-
myAction.leaveAction(Platform.Ios);
|
|
637
|
-
```
|
|
638
|
-
|
|
639
|
-
* Passing to **Android** only:
|
|
640
|
-
```ts
|
|
641
|
-
import { Dynatrace, Platform } from '@dynatrace/react-native-plugin';
|
|
659
|
+
OneAgent automatically creates a user action for each app start. The action starts at the first measured React Native startup phase (`runJsBundleStart`) and ends when `contentAppeared` fires — once the JavaScript bundle has loaded and the first content is displayed. The action groups all web requests, navigations, and errors that occur during startup.
|
|
642
660
|
|
|
643
|
-
|
|
644
|
-
//Perform the action and whatever else is needed.
|
|
645
|
-
myAction.leaveAction(Platform.Android);
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
* Passing to **both**:
|
|
649
|
-
```ts
|
|
650
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
661
|
+
**Startup phases captured (in order):**
|
|
651
662
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
663
|
+
| Phase | Android | iOS |
|
|
664
|
+
|---|---|---|
|
|
665
|
+
| `downloadStart` / `downloadEnd` | Dev mode only (Metro bundle download) | Not captured |
|
|
666
|
+
| `runJsBundleStart` / `runJsBundleEnd` | Yes | Yes |
|
|
667
|
+
| `contentAppeared` | Yes | Yes |
|
|
656
668
|
|
|
657
|
-
|
|
669
|
+
> **Note:** Unlike Android and iOS native agents, the React Native plugin does not distinguish cold, warm, and hot start types — the native SDK sets the start type when it receives the event.
|
|
658
670
|
|
|
659
|
-
|
|
671
|
+
**Controlling the app start user action**
|
|
660
672
|
|
|
661
|
-
|
|
673
|
+
The app start user action is part of automatic user action detection and is controlled at runtime with `setAutomaticUserActionDetection`:
|
|
662
674
|
|
|
663
675
|
```ts
|
|
664
676
|
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
665
677
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
"currency": "USD",
|
|
672
|
-
"reviewScore": 4.8,
|
|
673
|
-
"arrivalDate": "2022-11-05",
|
|
674
|
-
"departureDate": "2022-11-15",
|
|
675
|
-
"journeyDuration": 10,
|
|
676
|
-
"adultTravelers": 2,
|
|
677
|
-
"childrenTravelers": 0
|
|
678
|
-
});
|
|
678
|
+
// Disable all automatic user actions including the app start user action
|
|
679
|
+
Dynatrace.setAutomaticUserActionDetection(false);
|
|
680
|
+
|
|
681
|
+
// Re-enable
|
|
682
|
+
Dynatrace.setAutomaticUserActionDetection(true);
|
|
679
683
|
```
|
|
680
|
-

|
|
681
684
|
|
|
682
|
-
|
|
685
|
+
This call applies to all automatic user actions (app start, touch/press interactions). To disable only touch interactions while keeping the app start user action, use `react.userInteraction: false` in `dynatrace.config.js` instead.
|
|
683
686
|
|
|
684
|
-
|
|
687
|
+
For more details, see the [App start user action documentation](https://docs.dynatrace.com/docs/shortlink/react-native-app-performance#app-start-user-action).
|
|
685
688
|
|
|
686
|
-
|
|
689
|
+
### React Native Symbolication
|
|
687
690
|
|
|
688
|
-
|
|
689
|
-
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
691
|
+
Dynatrace can automatically symbolicate JavaScript stack traces captured by the plugin using sourcemaps. This allows you to view human-readable file names, line numbers, and column information in your crash reports.
|
|
690
692
|
|
|
691
|
-
|
|
692
|
-
beaconHeaders.set('headerName', 'headerValue');
|
|
693
|
-
Dynatrace.setBeaconHeaders(beaconHeaders);
|
|
694
|
-
```
|
|
693
|
+
#### Generating Sourcemaps
|
|
695
694
|
|
|
696
|
-
|
|
695
|
+
Sourcemaps are generated during release builds and map bytecode offsets (Hermes) and locations in the minified JavaScript bundle (JavaScriptCore) back to your original source code. We support sourcemaps for both Hermes and JavaScriptCore. For detailed instructions on generating sourcemaps, see the [React Native debugging release builds guide](https://reactnative.dev/docs/debugging-release-builds).
|
|
697
696
|
|
|
698
|
-
|
|
697
|
+
To generate a sourcemap:
|
|
699
698
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
699
|
+
**Android:**
|
|
700
|
+
* Run `npx react-native run-android --mode release` in your project root, or
|
|
701
|
+
* Run `gradlew assembleRelease` in the `/android` directory
|
|
703
702
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
<Text>TouchableHighlight that will be monitored</Text>
|
|
709
|
-
</TouchableHighlight>
|
|
710
|
-
<TouchableHighlight onPress={onPress} dtActionIgnore="true">
|
|
711
|
-
<Text>TouchableHighlight that will be ignored</Text>
|
|
712
|
-
</TouchableHighlight>
|
|
713
|
-
</View>
|
|
714
|
-
);
|
|
715
|
-
};
|
|
703
|
+
**iOS:**
|
|
704
|
+
* First, enable sourcemaps according to the [React Native debugging release builds guide](https://reactnative.dev/docs/debugging-release-builds)
|
|
705
|
+
* Then run `npx react-native run-ios --mode Release`, or
|
|
706
|
+
* Build for release in Xcode
|
|
716
707
|
|
|
717
|
-
|
|
718
|
-
console.log("TouchableHighlight Pressed!");
|
|
719
|
-
};
|
|
708
|
+
#### Uploading Sourcemaps
|
|
720
709
|
|
|
721
|
-
|
|
722
|
-
```
|
|
710
|
+
Once generated, upload your sourcemaps to Dynatrace. For detailed instructions, see the [symbol file management documentation](https://docs.dynatrace.com/docs/observe/digital-experience/mobile-applications/analyze-and-use/upload-and-manage-symbol-files).
|
|
723
711
|
|
|
724
|
-
|
|
712
|
+
## RUM Classic
|
|
725
713
|
|
|
726
|
-
|
|
714
|
+
### Monitor a Component
|
|
727
715
|
|
|
728
|
-
|
|
716
|
+
A component can be either monitored automatically or manually. The auto instrumentation is handled via the dynatrace.config.js file. If you want to manually instrument a component you can use the API call `withMonitoring`.
|
|
729
717
|
|
|
730
|
-
|
|
718
|
+
* Example with Functional Component:
|
|
731
719
|
|
|
732
|
-
|
|
720
|
+
```ts
|
|
721
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
722
|
+
import { FunctionComponent } from 'react';
|
|
733
723
|
|
|
734
|
-
|
|
724
|
+
export const MyFunctionalComponent: FunctionComponent<{}> = () => {
|
|
725
|
+
return null;
|
|
726
|
+
}
|
|
735
727
|
|
|
736
|
-
|
|
728
|
+
Dynatrace.withMonitoring(MyFunctionalComponent, "MyFunctionalComponent");
|
|
729
|
+
```
|
|
730
|
+

|
|
737
731
|
|
|
738
|
-
|
|
739
|
-
import { Dynatrace, EventData } from '@dynatrace/react-native-plugin';
|
|
732
|
+
The String "MyFunctionalComponent" is optional as the name of the component can be retrieved through [different properties](#how-does-dynatrace-determine-the-user-action-name).
|
|
740
733
|
|
|
741
|
-
|
|
742
|
-
Dynatrace.sendEvent(new EventData()
|
|
743
|
-
.addEventProperty("event_properties.button_clicked", "login_button")
|
|
744
|
-
.addEventProperty("event_properties.user_type", "premium")
|
|
745
|
-
.addEventProperty("event_properties.attempt_count", 3)
|
|
746
|
-
.withDuration(250)
|
|
747
|
-
);
|
|
748
|
-
```
|
|
734
|
+
Combining manual and auto instrumentation should not be a problem. As they're running the same execution, the manual instrumentation will only override the content of auto instrumentation happening through the transformer.
|
|
749
735
|
|
|
750
|
-
|
|
751
|
-
* Only properties prefixed with `event_properties.*` are allowed
|
|
752
|
-
* Additionally, the `duration` property is allowed
|
|
753
|
-
* Maximum of 50 custom properties per event
|
|
754
|
-
* If the limit is exceeded, properties are sorted alphabetically by key and excess properties are dropped deterministically
|
|
755
|
-
* String properties are limited to 5000 characters (exceeding characters are truncated)
|
|
756
|
-
* Field names must contain only alphabetic characters, numbers, underscores, and dots
|
|
757
|
-
* Each dot must be followed by an alphabetic character
|
|
758
|
-
* Each underscore must be followed by an alphabetic character or number
|
|
759
|
-
* Values must be primitive types (string, number, boolean)
|
|
760
|
-
* Cannot contain functions, undefined, Infinity, or NaN as values (they will be replaced with null)
|
|
736
|
+
### Create custom actions
|
|
761
737
|
|
|
762
|
-
|
|
738
|
+
There are two options to create an action. Either using `enterAutoAction` (the previous `enterAction`) or `enterManualAction`:
|
|
763
739
|
|
|
764
|
-
|
|
740
|
+
**Important:** Action names are limited to 250 characters and will be truncated if they exceed this limit.
|
|
741
|
+
|
|
742
|
+
* `enterAutoAction` - Creates an Action which will be automatically handled by the plugin (This is the type of action which is internally used by the plugin when monitoring components and touchables). This means that the plugin decides about the hierarchy of this action. If there is no open action, the following action will be a root action. All other actions created by this method, while a root action is open, will be automatically inserted as a child action. Furthermore the plugin will automatically link webrequest (if they are not tagged manually) to the open root action. Be aware that the timeout/wait time for sub actions or web requests cannot be modified on the Android side for React Native Auto actions. The timeout is fixed to a 1000ms.
|
|
765
743
|
|
|
766
744
|
```ts
|
|
767
|
-
import { Dynatrace
|
|
745
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
768
746
|
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
.addSessionProperty("session_properties.app_version", "2.1.0")
|
|
773
|
-
.addSessionProperty("session_properties.feature_flag_enabled", true)
|
|
774
|
-
);
|
|
747
|
+
const myAction = Dynatrace.enterAutoAction("MyButton tapped");
|
|
748
|
+
//Perform the action and whatever else is needed.
|
|
749
|
+
myAction.leaveAction();
|
|
775
750
|
```
|
|
751
|
+

|
|
776
752
|
|
|
777
|
-
|
|
778
|
-
* Session properties persist throughout the entire session
|
|
779
|
-
* If you send the same property multiple times, only one value will be kept (first or last)
|
|
780
|
-
* Use session properties for data that applies to the entire user session
|
|
781
|
-
* Field naming follows the same rules as events, but with `session_properties.` prefix
|
|
782
|
-
* Maximum of 50 custom properties per event
|
|
783
|
-
* If the limit is exceeded, properties are sorted alphabetically by key and excess properties are dropped deterministically
|
|
753
|
+
* `enterManualAction` - Creates an Action which will NOT be handled by the plugin. This means that you have full control about the hierarchy of your actions. This function will create a root action for you, which has the ability to create child actions via `enterAction`. Be aware, because of the full manual approach the plugin will not link webrequest automatically. Webrequest have to be manually tagged by using the tag provided by the action via `getRequestTag`.
|
|
784
754
|
|
|
785
|
-
|
|
755
|
+
```ts
|
|
756
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
786
757
|
|
|
787
|
-
|
|
758
|
+
const myAction = Dynatrace.enterManualAction("MyButton tapped");
|
|
759
|
+
//Perform the action and whatever else is needed.
|
|
760
|
+
myAction.leaveAction();
|
|
761
|
+
```
|
|
788
762
|
|
|
789
|
-
|
|
763
|
+
To create a custom action named `"MyButton tapped"`, use the following code. The *leaveAction* closes the action again. To report values for this action before closing, see [Report Values](#report-values).
|
|
790
764
|
|
|
791
|
-
|
|
765
|
+
```ts
|
|
766
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
792
767
|
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
768
|
+
const myAction = Dynatrace.enterAutoAction("MyButton tapped");
|
|
769
|
+
//Perform the action and whatever else is needed.
|
|
770
|
+
myAction.leaveAction();
|
|
771
|
+
```
|
|
796
772
|
|
|
797
|
-
|
|
773
|
+
### Create custom sub actions
|
|
798
774
|
|
|
799
|
-
|
|
800
|
-
- `url.full`
|
|
801
|
-
- `exception.stack_trace`
|
|
775
|
+
You can create a single custom action as well as sub actions. The `MyButton Sub Action` is automatically put under the `MyButton tapped`. As long as `MyButton tapped` is open, it gathers all the web requests.
|
|
802
776
|
|
|
803
|
-
|
|
777
|
+
**Important:** Action names are limited to 250 characters and will be truncated if they exceed this limit.
|
|
804
778
|
|
|
805
779
|
```ts
|
|
806
|
-
import { Dynatrace
|
|
780
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
807
781
|
|
|
808
|
-
|
|
809
|
-
const
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
// Return null to discard the event entirely
|
|
816
|
-
if (event["event_properties.ignore"] === true) {
|
|
817
|
-
return null;
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
return event;
|
|
821
|
-
}
|
|
822
|
-
};
|
|
782
|
+
const myAction = Dynatrace.enterManualAction("MyButton tapped");
|
|
783
|
+
const mySubAction = myAction.enterAction("MyButton Sub Action");
|
|
784
|
+
//Perform the action and whatever else is needed.
|
|
785
|
+
mySubAction.leaveAction();
|
|
786
|
+
myAction.leaveAction();
|
|
787
|
+
```
|
|
788
|
+

|
|
823
789
|
|
|
824
|
-
|
|
825
|
-
Dynatrace.addEventModifier(myModifier);
|
|
790
|
+
### Cancel actions
|
|
826
791
|
|
|
827
|
-
|
|
828
|
-
Dynatrace.removeEventModifier(myModifier);
|
|
829
|
-
```
|
|
792
|
+
Actions can be canceled. That means they will not be sent and discarded fully. This also means that any values and sub actions attached to the action will be removed.
|
|
830
793
|
|
|
831
|
-
|
|
794
|
+
```ts
|
|
795
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
832
796
|
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
- **Field naming**: Custom properties must follow the `event_properties.*` or `session_properties.*` prefix naming convention
|
|
837
|
-
- **Reserved fields**: Certain reserved fields and namespaces cannot be modified. Attempts to modify them will be ignored
|
|
838
|
-
- **Error handling**: If a modifier throws an exception, it will be logged but won't prevent other modifiers from executing
|
|
839
|
-
- **Primitive values**: Event fields can only contain primitive values (String, int, double, bool)
|
|
840
|
-
- **Invalid argument**: In case you pass an invalid argument to `addEventModifier`, we return a no-op placeholder modifier.
|
|
797
|
+
const myAction = Dynatrace.enterAutoAction("MyButton tapped");
|
|
798
|
+
// Action will be canceled
|
|
799
|
+
myAction.cancel();
|
|
841
800
|
|
|
842
|
-
|
|
801
|
+
// Has no impact as the action is already canceled
|
|
802
|
+
myAction.leaveAction();
|
|
803
|
+
```
|
|
843
804
|
|
|
844
|
-
|
|
805
|
+
### Manual Web Request Tagging
|
|
806
|
+
|
|
807
|
+
You can manually tag and time your web requests. With the API shown below, you are able to manually capture the web requests of an http framework/library.
|
|
808
|
+
|
|
809
|
+
**Note:**
|
|
810
|
+
Using this API will force the request to be added to the action that is manually created.
|
|
845
811
|
|
|
846
812
|
```ts
|
|
847
|
-
import { Dynatrace,
|
|
813
|
+
import { Dynatrace, DynatraceWebRequestTiming } from '@dynatrace/react-native-plugin';
|
|
814
|
+
|
|
815
|
+
const action = Dynatrace.enterManualAction('API Data Fetch');
|
|
816
|
+
const url = 'https://api.example.com/data';
|
|
817
|
+
const tag = await action.getRequestTag(url);
|
|
818
|
+
const timing = new DynatraceWebRequestTiming(tag, url);
|
|
848
819
|
|
|
849
820
|
try {
|
|
850
|
-
|
|
851
|
-
|
|
821
|
+
timing.startWebRequestTiming();
|
|
822
|
+
const response = await fetch(url, {
|
|
823
|
+
headers: {
|
|
824
|
+
[timing.getRequestTagHeader()]: tag
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
timing.stopWebRequestTiming(response.status, response.statusText);
|
|
852
828
|
} catch (error) {
|
|
853
829
|
if (error instanceof Error) {
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
);
|
|
830
|
+
timing.stopWebRequestTiming(-1, error.message);
|
|
831
|
+
} else {
|
|
832
|
+
timing.stopWebRequestTiming(-1, (error as any).toString());
|
|
858
833
|
}
|
|
834
|
+
} finally {
|
|
835
|
+
action.leaveAction();
|
|
859
836
|
}
|
|
860
837
|
```
|
|
838
|
+

|
|
861
839
|
|
|
862
|
-
|
|
863
|
-
* `error`: The Error object containing exception information (required)
|
|
840
|
+
There is also the option to report values for request and response size:
|
|
864
841
|
|
|
865
|
-
|
|
842
|
+
```ts
|
|
843
|
+
import { Dynatrace, DynatraceWebRequestTiming } from '@dynatrace/react-native-plugin';
|
|
866
844
|
|
|
867
|
-
|
|
845
|
+
const action = Dynatrace.enterManualAction('API Data Upload');
|
|
846
|
+
const url = 'https://api.example.com/upload';
|
|
847
|
+
const tag = await action.getRequestTag(url);
|
|
848
|
+
const timing = new DynatraceWebRequestTiming(tag, url);
|
|
849
|
+
const requestData = JSON.stringify({ key: 'value' });
|
|
868
850
|
|
|
869
|
-
|
|
870
|
-
|
|
851
|
+
try {
|
|
852
|
+
timing.startWebRequestTiming();
|
|
853
|
+
const response = await fetch(url, {
|
|
854
|
+
method: 'POST',
|
|
855
|
+
headers: {
|
|
856
|
+
[timing.getRequestTagHeader()]: tag,
|
|
857
|
+
'Content-Type': 'application/json'
|
|
858
|
+
},
|
|
859
|
+
body: requestData
|
|
860
|
+
});
|
|
861
|
+
const responseData = await response.text();
|
|
862
|
+
timing.stopWebRequestTimingWithSize(
|
|
863
|
+
response.status,
|
|
864
|
+
response.statusText,
|
|
865
|
+
requestData.length,
|
|
866
|
+
responseData.length
|
|
867
|
+
);
|
|
868
|
+
} catch (error) {
|
|
869
|
+
if (error instanceof Error) {
|
|
870
|
+
timing.stopWebRequestTiming(-1, error.message);
|
|
871
|
+
} else {
|
|
872
|
+
timing.stopWebRequestTiming(-1, (error as any).toString());
|
|
873
|
+
}
|
|
874
|
+
} finally {
|
|
875
|
+
action.leaveAction();
|
|
876
|
+
}
|
|
877
|
+
```
|
|
878
|
+

|
|
871
879
|
|
|
872
|
-
|
|
873
|
-
const requestEventData = new HttpRequestEventData('https://api.example.com/users', 'GET');
|
|
874
|
-
Dynatrace.sendHttpRequestEvent(requestEventData);
|
|
880
|
+
### Report values
|
|
875
881
|
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
882
|
+
For any open action you can report certain values. The following API is available for action:
|
|
883
|
+
|
|
884
|
+
```ts
|
|
885
|
+
import { Platform } from '@dynatrace/react-native-plugin';
|
|
886
|
+
|
|
887
|
+
interface IDynatraceAction {
|
|
888
|
+
reportDoubleValue(valueName: string, value: number, platform?: Platform): void;
|
|
889
|
+
reportError(errorName: string, errorCode: number, platform?: Platform): void;
|
|
890
|
+
reportEvent(eventName: string, platform?: Platform): void;
|
|
891
|
+
reportIntValue(valueName: string, value: number, platform?: Platform): void;
|
|
892
|
+
reportStringValue(valueName: string, value: string, platform?: Platform): void;
|
|
893
|
+
}
|
|
881
894
|
```
|
|
882
895
|
|
|
883
|
-
**
|
|
884
|
-
* `url`: The URL of the HTTP request (required)
|
|
885
|
-
* `method`: The HTTP method (e.g., 'GET', 'POST', 'PUT', 'DELETE') (required)
|
|
896
|
+
**Important:** All string parameters (errorName, eventName, valueName, value) are limited to 250 characters and will be truncated if they exceed this limit.
|
|
886
897
|
|
|
887
|
-
|
|
898
|
+
To report a string value, use the following:
|
|
888
899
|
|
|
889
|
-
|
|
900
|
+
```ts
|
|
901
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
890
902
|
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
903
|
+
const myAction = Dynatrace.enterAutoAction("MyButton tapped");
|
|
904
|
+
myAction.reportStringValue("ValueName", "ImportantValue");
|
|
905
|
+
myAction.leaveAction();
|
|
906
|
+
```
|
|
907
|
+

|
|
894
908
|
|
|
895
|
-
|
|
909
|
+
If you look at the API calls, you will see the optional parameter `platform?: Platform`. This parameter offers the possibility to report values only for a specific platform. to know more, see [Platform independent reporting](#platform-independent-reporting).
|
|
896
910
|
|
|
897
|
-
#### Automatic Navigation tracking
|
|
898
911
|
|
|
899
|
-
|
|
912
|
+
### Report an error stacktrace
|
|
900
913
|
|
|
901
|
-
|
|
914
|
+
To manually report an error stacktrace, use the following API call:
|
|
902
915
|
|
|
903
|
-
```
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
916
|
+
```ts
|
|
917
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
918
|
+
|
|
919
|
+
try {
|
|
920
|
+
throw new Error('Database connection failed');
|
|
921
|
+
} catch (error) {
|
|
922
|
+
if (error instanceof Error) {
|
|
923
|
+
Dynatrace.reportErrorStacktrace(
|
|
924
|
+
'DatabaseError',
|
|
925
|
+
error.message,
|
|
926
|
+
'Failed to connect to remote database',
|
|
927
|
+
error.stack || 'No stack trace available'
|
|
928
|
+
);
|
|
907
929
|
}
|
|
908
930
|
}
|
|
909
931
|
```
|
|
932
|
+

|
|
910
933
|
|
|
911
|
-
|
|
934
|
+
**Note:**
|
|
935
|
+
The previous API without *errorValue* is deprecated and will be removed in the future. Please use the new API with errorValue if possible.
|
|
912
936
|
|
|
913
|
-
|
|
914
|
-
```js
|
|
915
|
-
const Drawer = createDrawerNavigator();
|
|
937
|
+
### Manually report a crash
|
|
916
938
|
|
|
917
|
-
|
|
918
|
-
return (
|
|
919
|
-
<NavigationContainer>
|
|
920
|
-
<Drawer.Navigator initialRouteName="Home">
|
|
921
|
-
<Drawer.Screen name="Home" component={HomeScreen} />
|
|
922
|
-
<Drawer.Screen name="Feature" component={FeatureScreen}/>
|
|
923
|
-
</Drawer.Navigator>
|
|
924
|
-
</NavigationContainer>
|
|
925
|
-
);
|
|
926
|
-
}
|
|
939
|
+
You can manually report a crash via the following API calls:
|
|
927
940
|
|
|
928
|
-
|
|
941
|
+
```ts
|
|
942
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
929
943
|
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
944
|
+
try {
|
|
945
|
+
throw new Error('Fatal memory allocation failure');
|
|
946
|
+
} catch (error) {
|
|
947
|
+
if (error instanceof Error) {
|
|
948
|
+
Dynatrace.reportCrash(
|
|
949
|
+
'MemoryError',
|
|
950
|
+
error.message,
|
|
951
|
+
error.stack || 'No stack trace available'
|
|
952
|
+
);
|
|
953
|
+
|
|
954
|
+
// or directly via the full error
|
|
955
|
+
Dynatrace.reportCrashWithException('MemoryError', error);
|
|
956
|
+
}
|
|
937
957
|
}
|
|
938
958
|
```
|
|
959
|
+

|
|
939
960
|
|
|
940
|
-
|
|
961
|
+
> **Note**: If you use this API call to report a crash manually, it will force the session to be completed. Any new actions that are captured afterwards will be added into a new session.
|
|
941
962
|
|
|
942
|
-
|
|
963
|
+
*reportCrashWithException* will use the crashName as name for the crash. It will only report the crash if there is also a stacktrace available.
|
|
943
964
|
|
|
944
|
-
|
|
965
|
+
### Report GPS Location
|
|
966
|
+
|
|
967
|
+
You can report latitude and longitude and specify an optional platform.
|
|
945
968
|
|
|
946
969
|
```ts
|
|
947
970
|
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
948
971
|
|
|
949
|
-
|
|
950
|
-
Dynatrace.startView("HomeScreen");
|
|
972
|
+
Dynatrace.setGPSLocation(48.31518732698596, 14.305245274594471);
|
|
951
973
|
```
|
|
952
974
|
|
|
953
|
-
|
|
954
|
-
* Only one view can be active at a time
|
|
955
|
-
* Starting a new view will automatically stop the previous one
|
|
956
|
-
* View names should be meaningful and consistent across your application
|
|
957
|
-
* All events captured after starting a view will include the view context
|
|
958
|
-
|
|
959
|
-
**Complete Example:**
|
|
975
|
+
### Platform independent reporting
|
|
960
976
|
|
|
977
|
+
You probably noticed that each method has an additional *optional* parameter named `platform` of type `Platform`. You can use this to only trigger manual instrumentation for a specific OS. The available values are: `Platform.Ios` and `Platform.Android`. Default is that it will work on any platform. Otherwise it is passed *only* to the relevant OS. For example:
|
|
978
|
+
* Passing to **iOS** only:
|
|
961
979
|
```ts
|
|
962
|
-
import { Dynatrace,
|
|
980
|
+
import { Dynatrace, Platform } from '@dynatrace/react-native-plugin';
|
|
963
981
|
|
|
964
|
-
|
|
965
|
-
|
|
982
|
+
const myAction = Dynatrace.enterAutoAction("MyButton tapped", Platform.Ios);
|
|
983
|
+
//Perform the action and whatever else is needed.
|
|
984
|
+
myAction.leaveAction(Platform.Ios);
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
* Passing to **Android** only:
|
|
988
|
+
```ts
|
|
989
|
+
import { Dynatrace, Platform } from '@dynatrace/react-native-plugin';
|
|
966
990
|
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
991
|
+
const myAction = Dynatrace.enterAutoAction("MyButton tapped", Platform.Android);
|
|
992
|
+
//Perform the action and whatever else is needed.
|
|
993
|
+
myAction.leaveAction(Platform.Android);
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
* Passing to **both**:
|
|
997
|
+
```ts
|
|
998
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
972
999
|
|
|
973
|
-
|
|
974
|
-
|
|
1000
|
+
const myAction = Dynatrace.enterAutoAction("MyButton tapped");
|
|
1001
|
+
//Perform the action and whatever else is needed.
|
|
1002
|
+
myAction.leaveAction();
|
|
975
1003
|
```
|
|
976
1004
|
|
|
977
|
-
###
|
|
1005
|
+
### Business event capturing
|
|
978
1006
|
|
|
979
|
-
|
|
1007
|
+
With `sendBizEvent`, you can report business events. These events are standalone events, as OneAgent sends them detached from user actions or user sessions.
|
|
980
1008
|
|
|
981
|
-
|
|
1009
|
+
For more information on business events, see [dynatrace documentation](https://docs.dynatrace.com/docs/observe/business-observability/explore-business-events).
|
|
982
1010
|
|
|
983
|
-
```
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
1011
|
+
```ts
|
|
1012
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
1013
|
+
|
|
1014
|
+
Dynatrace.sendBizEvent("com.easytravel.funnel.booking-finished", {
|
|
1015
|
+
"event.name" : "Confirmed Booking",
|
|
1016
|
+
"screen": "booking-confirmation",
|
|
1017
|
+
"product": "Danube Anna Hotel",
|
|
1018
|
+
"amount": 358.35,
|
|
1019
|
+
"currency": "USD",
|
|
1020
|
+
"reviewScore": 4.8,
|
|
1021
|
+
"arrivalDate": "2022-11-05",
|
|
1022
|
+
"departureDate": "2022-11-15",
|
|
1023
|
+
"journeyDuration": 10,
|
|
1024
|
+
"adultTravelers": 2,
|
|
1025
|
+
"childrenTravelers": 0
|
|
1026
|
+
});
|
|
987
1027
|
```
|
|
1028
|
+

|
|
988
1029
|
|
|
989
|
-
|
|
1030
|
+
### Setting beacon headers
|
|
990
1031
|
|
|
991
|
-
|
|
992
|
-
- `react.userInteraction: true|false` controls whether the UI Interaction instrumentation feature is applied.
|
|
1032
|
+
This allows you to put a set of http headers on every agent http request (i.e. Authorization header etc.). It will also triggers the agent to reconnect to the beacon endpoint with the new headers.
|
|
993
1033
|
|
|
994
|
-
|
|
995
|
-
- Runtime emission checks the remote flag `touch_interaction_enabled`.
|
|
996
|
-
- If remote flag is present, it is used as the source of truth.
|
|
997
|
-
- If remote flag is temporarily unavailable, the plugin falls back to the last known good remote value.
|
|
998
|
-
- If no remote value was received yet, runtime defaults to enabled behavior.
|
|
1034
|
+
**Note:** To clear the previously set headers, call the method without the headers parameter or with a null value for the headers parameter.
|
|
999
1035
|
|
|
1000
|
-
|
|
1036
|
+
```ts
|
|
1037
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
1001
1038
|
|
|
1002
|
-
|
|
1039
|
+
const beaconHeaders = new Map<string, string>();
|
|
1040
|
+
beaconHeaders.set('headerName', 'headerValue');
|
|
1041
|
+
Dynatrace.setBeaconHeaders(beaconHeaders);
|
|
1042
|
+
```
|
|
1003
1043
|
|
|
1004
|
-
|
|
1044
|
+
### Exclude Individual JSX Elements
|
|
1005
1045
|
|
|
1006
|
-
|
|
1007
|
-
* the runtime masking rules classify the detected text as sensitive
|
|
1008
|
-
* the runtime masking rules classify the element `testID` as sensitive
|
|
1046
|
+
If you want to instrument a functional component or class component but want to exclude a certain button or element, you can do this via the `dtActionIgnore` property. Example:
|
|
1009
1047
|
|
|
1010
|
-
|
|
1048
|
+
```tsx
|
|
1049
|
+
import React from 'react';
|
|
1050
|
+
import { TouchableHighlight, Text, View } from 'react-native';
|
|
1011
1051
|
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1052
|
+
const TouchableHighlightScreen = () => {
|
|
1053
|
+
return (
|
|
1054
|
+
<View>
|
|
1055
|
+
<TouchableHighlight onPress={onPress}>
|
|
1056
|
+
<Text>TouchableHighlight that will be monitored</Text>
|
|
1057
|
+
</TouchableHighlight>
|
|
1058
|
+
<TouchableHighlight onPress={onPress} dtActionIgnore="true">
|
|
1059
|
+
<Text>TouchableHighlight that will be ignored</Text>
|
|
1060
|
+
</TouchableHighlight>
|
|
1061
|
+
</View>
|
|
1062
|
+
);
|
|
1063
|
+
};
|
|
1015
1064
|
|
|
1016
|
-
|
|
1065
|
+
const onPress = () => {
|
|
1066
|
+
console.log("TouchableHighlight Pressed!");
|
|
1067
|
+
};
|
|
1017
1068
|
|
|
1018
|
-
|
|
1019
|
-
<View dtMask>
|
|
1020
|
-
<Pressable onPress={onPress}>
|
|
1021
|
-
<Text>john.doe@example.com</Text>
|
|
1022
|
-
</Pressable>
|
|
1023
|
-
</View>
|
|
1069
|
+
export default TouchableHighlightScreen;
|
|
1024
1070
|
```
|
|
1025
1071
|
|
|
1026
|
-
This
|
|
1027
|
-
|
|
1072
|
+
This example shows two *TouchableHighlight*, which will fire the *onPress()* function when pressed. The property `dtActionIgnore="true"` will prevent the monitoring of one of them. This means that the onPress will still be executed but we will no longer create a user action which is wrapping the button click.
|
|
1028
1073
|
|
|
1029
|
-
|
|
1074
|
+
>*Attention:* If you are using Typescript and want to set this property with type-safety, look [here](#typescript-setup-for-dtactionignore-and-dtactionname).
|
|
1030
1075
|
|
|
1031
|
-
|
|
1076
|
+
## Extended topics
|
|
1032
1077
|
|
|
1033
|
-
|
|
1034
|
-
- **Component** — the type of the UI component that was touched (e.g. `Pressable`).
|
|
1035
|
-
- **Component Path** — a stable path through the component tree that uniquely identifies the element (e.g. `App/View[1]/Pressable[1]`).
|
|
1036
|
-
- **Interaction type** — how the user interacted (e.g. `touch`).
|
|
1037
|
-
- **Position** — the screen coordinates where the touch occurred.
|
|
1078
|
+
### Identify a user
|
|
1038
1079
|
|
|
1039
|
-
|
|
1080
|
+
You can identify a user and tag the current session with a name by making the following call:
|
|
1040
1081
|
|
|
1041
|
-
|
|
1082
|
+
**Important:** The user identifier is limited to 250 characters and will be truncated if it exceeds this limit.
|
|
1042
1083
|
|
|
1043
|
-
|
|
1084
|
+
```ts
|
|
1085
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
1044
1086
|
|
|
1045
|
-
|
|
1046
|
-
{
|
|
1047
|
-
"characteristics.has_user_interaction": true,
|
|
1048
|
-
"ui_element.detected_name": "LoginButton",
|
|
1049
|
-
"ui_element.components": ["Pressable"],
|
|
1050
|
-
"ui_element.id": "App/View/Pressable",
|
|
1051
|
-
"ui_element.name_origin": "component",
|
|
1052
|
-
"interaction.type": "touch",
|
|
1053
|
-
"positions": [{ "x": 120, "y": 460 }],
|
|
1054
|
-
"ui_element.responder.detected_name": "Pressable",
|
|
1055
|
-
"ui_element.responder.components": ["Pressable"],
|
|
1056
|
-
"ui_element.responder.id": "App/View[/Pressable",
|
|
1057
|
-
"ui_element.responder.name_origin": "component"
|
|
1058
|
-
}
|
|
1087
|
+
Dynatrace.identifyUser("User XY");
|
|
1059
1088
|
```
|
|
1089
|
+

|
|
1060
1090
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
You can assign custom names to your components. A custom name affects both the **Component** and the **Component Path** described above. There are two ways to do this, depending on how the component is used.
|
|
1091
|
+
### End the current user session
|
|
1064
1092
|
|
|
1065
|
-
|
|
1093
|
+
To end the current user session, use the following API call:
|
|
1066
1094
|
|
|
1067
|
-
|
|
1095
|
+
```ts
|
|
1096
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
1068
1097
|
|
|
1069
|
-
|
|
1070
|
-
<TouchableOpacity dtActionName="Checkout Button" onPress={onCheckout}>
|
|
1071
|
-
<Text dtActionName="Checkout Text">Buy now</Text>
|
|
1072
|
-
</TouchableOpacity>
|
|
1098
|
+
Dynatrace.endSession();
|
|
1073
1099
|
```
|
|
1074
1100
|
|
|
1075
|
-
|
|
1101
|
+
**Note:** The user tagging will not carry over to the new user session that is started after using this API. If user tagging is desired in the new user session, please ensure that you call the [user tagging](#identify-a-user) API.
|
|
1076
1102
|
|
|
1077
|
-
|
|
1078
|
-
"ui_element.components": ["Checkout Text"],
|
|
1079
|
-
"ui_element.id": ".../Checkout Button/Checkout Text"
|
|
1080
|
-
```
|
|
1103
|
+
### User Privacy Options
|
|
1081
1104
|
|
|
1082
|
-
|
|
1105
|
+
The privacy API methods allow you to dynamically change the data-collection level based on the individual preferences of your end users. Each end user can select from three data-privacy levels:
|
|
1083
1106
|
|
|
1084
|
-
|
|
1107
|
+
```ts
|
|
1108
|
+
export enum DataCollectionLevel {
|
|
1109
|
+
Off, Performance, UserBehavior
|
|
1110
|
+
}
|
|
1111
|
+
```
|
|
1085
1112
|
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1113
|
+
1. Off: Native Agent doesn't capture any monitoring data.
|
|
1114
|
+
2. Performance: Native Agent captures only anonymous performance data. Monitoring data that can be used to identify individual users, such as user tags and custom values, aren't captured.
|
|
1115
|
+
3. UserBehavior: Native Agent captures both performance and user data. In this mode, Native Agent recognizes and reports users who re-visit in future sessions.
|
|
1089
1116
|
|
|
1090
|
-
|
|
1117
|
+
Crash reporting is enabled by default. The Mobile agent captures all unhandled exceptions/errors and immediately sends the crash report to the server. With this API you can activate or deactivate crash reporting. To change this behaviour via the API, enable/activate [`userOptIn`](#user-opt-in-mode) and set the User Privacy Options.
|
|
1091
1118
|
|
|
1092
|
-
|
|
1093
|
-
return (/* ... */);
|
|
1094
|
-
}
|
|
1119
|
+
The API to get and set the current privacy level looks like this:
|
|
1095
1120
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1121
|
+
```ts
|
|
1122
|
+
import { Platform, UserPrivacyOptions } from '@dynatrace/react-native-plugin';
|
|
1098
1123
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
<Drawer.Navigator>
|
|
1103
|
-
{/* Both screens reference the same component,
|
|
1104
|
-
so both pick up the 'User Profile' name */}
|
|
1105
|
-
<Drawer.Screen name="Me" component={ProfileScreen} />
|
|
1106
|
-
<Drawer.Screen name="Account" component={ProfileScreen} />
|
|
1107
|
-
</Drawer.Navigator>
|
|
1108
|
-
</NavigationContainer>
|
|
1109
|
-
);
|
|
1124
|
+
interface IDynatrace {
|
|
1125
|
+
getUserPrivacyOptions(platform?: Platform): Promise<UserPrivacyOptions>;
|
|
1126
|
+
applyUserPrivacyOptions(userPrivacyOptions: UserPrivacyOptions, platform?: Platform): void;
|
|
1110
1127
|
}
|
|
1111
1128
|
```
|
|
1112
1129
|
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
```json
|
|
1116
|
-
"ui_element.id": ".../User Profile/..."
|
|
1117
|
-
```
|
|
1118
|
-
|
|
1119
|
-
> **Note:** The static property applies to *all* uses of the component. If you need a different name per usage, render the component as JSX and use the `dtActionName` prop (option 1) instead.
|
|
1120
|
-
>
|
|
1121
|
-
> **Note:** The static property has no effect when a component is rendered as JSX. In that case the name is taken from either the `dtActionName` prop passed to it (option 1) or the name of the JSX component.
|
|
1122
|
-
|
|
1123
|
-
### React Native Symbolication
|
|
1130
|
+
To check the current privacy options that are set:
|
|
1124
1131
|
|
|
1125
|
-
|
|
1132
|
+
```ts
|
|
1133
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
1126
1134
|
|
|
1127
|
-
|
|
1135
|
+
const privacyOptions = await Dynatrace.getUserPrivacyOptions();
|
|
1136
|
+
```
|
|
1128
1137
|
|
|
1129
|
-
|
|
1138
|
+
If you want to create a new `UserPrivacyOptions` object and pass it to Dynatrace:
|
|
1130
1139
|
|
|
1131
|
-
|
|
1140
|
+
```ts
|
|
1141
|
+
import { Dynatrace, DataCollectionLevel, UserPrivacyOptions } from '@dynatrace/react-native-plugin';
|
|
1132
1142
|
|
|
1133
|
-
|
|
1134
|
-
* Run `npx react-native run-android --mode release` in your project root, or
|
|
1135
|
-
* Run `gradlew assembleRelease` in the `/android` directory
|
|
1143
|
+
const privacyConfig = new UserPrivacyOptions(DataCollectionLevel.UserBehavior, true);
|
|
1136
1144
|
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
* Build for release in Xcode
|
|
1145
|
+
// Getter and setter available for UserPrivacyOptions
|
|
1146
|
+
privacyConfig.crashReportingOptedIn = false;
|
|
1147
|
+
privacyConfig.dataCollectionLevel = DataCollectionLevel.Performance;
|
|
1141
1148
|
|
|
1142
|
-
|
|
1149
|
+
const level = privacyConfig.dataCollectionLevel;
|
|
1150
|
+
const crashReporting = privacyConfig.crashReportingOptedIn;
|
|
1143
1151
|
|
|
1144
|
-
|
|
1152
|
+
Dynatrace.applyUserPrivacyOptions(privacyConfig);
|
|
1153
|
+
```
|
|
1145
1154
|
|
|
1146
1155
|
## NPX Commands
|
|
1147
1156
|
|
|
@@ -1149,7 +1158,6 @@ The following npx commands are available for the plugin:
|
|
|
1149
1158
|
|
|
1150
1159
|
* npx instrumentDynatrace - Is triggering the configuration process and will insert the configuration into the Android and iOS application. This is mandatory and should usually happen automatically when doing `react-native run-android` or `react-native run-ios` command.
|
|
1151
1160
|
* npx configDynatrace - Is checking the current configuration and is creating a default configuration if there is none.
|
|
1152
|
-
* npx lineOffsetDynatrace - ...
|
|
1153
1161
|
|
|
1154
1162
|
### npx instrumentDynatrace
|
|
1155
1163
|
|
|
@@ -1520,18 +1528,6 @@ The changes our auto-instrumentation is making now get dumped into the `node_mod
|
|
|
1520
1528
|
|
|
1521
1529
|
> **Note:** This feature increases the time it takes to build the Javascript bundle. Only use it for debugging purposes. Deactivate it otherwise, especially when fast build times are important.
|
|
1522
1530
|
|
|
1523
|
-
#### Using our legacy jscodeshift auto-instrumentation
|
|
1524
|
-
|
|
1525
|
-
We recently moved our auto-instrumentation to a babel plugin. In case you need to, you can still switch to the old jscodeshift auto-instrumentation with this flag:
|
|
1526
|
-
|
|
1527
|
-
```js
|
|
1528
|
-
react: {
|
|
1529
|
-
useLegacyJscodeshift: true
|
|
1530
|
-
}
|
|
1531
|
-
```
|
|
1532
|
-
|
|
1533
|
-
> **Note:** When we moved our auto-instrumentation to a babel plugin, we removed documentation that was only relevant for the jscodeshift auto-instrumentation. Most notably, we removed documentation concerning registering a custom metro transformer and patching sourcemaps. If you use the `useLegacyJscodeshift` flag, please refer to the [legacy documentation (v2.333.1)](https://www.npmjs.com/package/@dynatrace/react-native-plugin/v/2.333.1) for details on custom metro transformers and sourcemap patching.
|
|
1534
|
-
|
|
1535
1531
|
### Android block
|
|
1536
1532
|
|
|
1537
1533
|
The Android block is a wrapper for the Android configuration you find in the WebUI (in the Mobile Application Settings). Copy the content into the following block:
|
|
@@ -1701,7 +1697,7 @@ ios: {
|
|
|
1701
1697
|
* class name: If the display name is not available, the class name is used by taking the property name from the constructor
|
|
1702
1698
|
* Touchables, Buttons, Pressable
|
|
1703
1699
|
* dtActionName: Use a custom property called dtActionName
|
|
1704
|
-
* If [actionNamePrivacy](#
|
|
1700
|
+
* If [actionNamePrivacy](#manual-oneagent-startup) is activated anything below will not be detected
|
|
1705
1701
|
* title property
|
|
1706
1702
|
* accessibilityLabel property
|
|
1707
1703
|
* If none of the above exist, we recursively traverse `children` to find a name. We consider text, the source property of any `ReactNative.Image` and the name property of any functional component called `Icon`.
|
|
@@ -1751,7 +1747,7 @@ import { Text } from 'react-native';
|
|
|
1751
1747
|
</TouchableHighlight>
|
|
1752
1748
|
```
|
|
1753
1749
|
|
|
1754
|
-
*Note:* [actionNamePrivacy](#
|
|
1750
|
+
*Note:* [actionNamePrivacy](#manual-oneagent-startup) has no impact on using dtActionName. dtActionName will always be used.
|
|
1755
1751
|
|
|
1756
1752
|
>*Attention:* If you are using Typescript and want to set this property with type-safety, look [here](#typescript-setup-for-dtactionignore-and-dtactionname).
|
|
1757
1753
|
|
|
@@ -1765,7 +1761,7 @@ In general, Dynatrace always closes the session when a crash occurs. Usually a c
|
|
|
1765
1761
|
* Fatal error: If the error is considered as fatal by the React Native crash handler, it will be treated as crash.
|
|
1766
1762
|
* Native crashes: If a crash appears solely on the native side and is not noticed by the internal React Native crash handler, it will be reported directly by the Android or iOS agent.
|
|
1767
1763
|
* Exception: Some JavaScript crashes will result in Native crashes. Therefore, they are filtered on the native side as normally the crash would be reported twice. On the JavaScript side, these crashes are already reported by us before they hit the native side resulting in no lost information.
|
|
1768
|
-
Additionally, you can use our crash and error reporting APIs which are available with [
|
|
1764
|
+
Additionally, you can use our crash and error reporting APIs which are available with [RUM Classic](#rum-classic).
|
|
1769
1765
|
|
|
1770
1766
|
|
|
1771
1767
|
## React Automatic Runtime
|
|
@@ -2088,6 +2084,27 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
|
|
|
2088
2084
|
<br/><br/>
|
|
2089
2085
|
## Changelog
|
|
2090
2086
|
|
|
2087
|
+
In Progress
|
|
2088
|
+
|
|
2089
|
+
2.347.1
|
|
2090
|
+
* Updated Android (8.347.1.1003) & iOS Agent (8.347.1.1004)
|
|
2091
|
+
* Renamed `registerEventTrigger` to `registerNavigationEventTrigger` for clarity
|
|
2092
|
+
* Fixed re-configure failure to properly clear the table reload trigger
|
|
2093
|
+
* Updated `xmldom` dependency in Session Replay to a non-vulnerable version (DEM-32539)
|
|
2094
|
+
|
|
2095
|
+
|
|
2096
|
+
2.345.1
|
|
2097
|
+
* Updated Android (8.345.1.1003) & iOS Agent (8.345.1.1003)
|
|
2098
|
+
* Renamed `monitorNavigation` to `useNavigationMonitor`; React Navigation screen changes are now detected automatically, stamped with `start_time` and `duration`, and trigger Session Replay capture after the incoming screen settles
|
|
2099
|
+
* Added React Navigation support: settle detection on both Android and iOS bridges, UI-change capture toggling restored
|
|
2100
|
+
* Removed the bridge-side settle helper — the native agent now owns coalescing on both platforms
|
|
2101
|
+
* Added a runtime deprecation warning system
|
|
2102
|
+
* Removed the option to use the legacy jscodeshift auto-instrumentation by removing the `useLegacyJscodeshift` flag from `dynatrace.config.js`
|
|
2103
|
+
* Removed leading slash from reported view names
|
|
2104
|
+
* Discard user interaction actions when 3rd-gen instrumentation is disabled, even without an `onPress` callback
|
|
2105
|
+
* Android: compatibility fixes for AGP 9 and Kotlin 2.2 (React Native 0.87)
|
|
2106
|
+
* iOS: app-start measurement fixes for the new architecture
|
|
2107
|
+
|
|
2091
2108
|
2.343.1
|
|
2092
2109
|
* Updated Android (8.343.1.1038) & iOS Agent (8.343.1.1007)
|
|
2093
2110
|
* Added User Actions feature
|
|
@@ -2101,6 +2118,7 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
|
|
|
2101
2118
|
* Added `DYNATRACE_CONFIG` environment variable as an alternative way to specify the config file path for the Metro/Babel transformer.
|
|
2102
2119
|
* Added `npx instrumentDynatrace --reset` flag to clear a previously-persisted custom config path and revert the Metro/Babel transformer to the default `dynatrace.config.js` lookup. Useful after switching between build flavors that each use a different config file.
|
|
2103
2120
|
* Fixed incorrect `start_time` on Android app start events when `3rd_gen_enabled` is false. The `EventPipeline` was suppressing the `forwardAppStartEvent` timing-correction call along with all other 3rd-gen events, causing the native Dynatrace SDK to report its own stale process-creation timestamp instead of the actual JS bundle load time.
|
|
2121
|
+
* CP now always forwards User Interaction Actions (UIA) to the native agent unconditionally, regardless of the `touch_interaction_enabled` server configuration flag. The native agent is responsible for deciding whether to record or discard each UIA. This applies to both the Babel-instrumented (`AnalyticsRoot`/`TouchCapture`) and the legacy JSX-wrapped Touchables UIA paths.
|
|
2104
2122
|
|
|
2105
2123
|
2.341.1
|
|
2106
2124
|
* Updated Android (8.341.1.1004) & iOS Agent (8.341.1.1010)
|
|
@@ -2128,7 +2146,7 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
|
|
|
2128
2146
|
* Updated Android (8.337.2.1010) & iOS Agent (8.337.1.1003)
|
|
2129
2147
|
* Fixed gradle path derivation for custom `--gradle` arguments: the plugin now correctly probes the filesystem to auto-detect `app/build.gradle(.kts)` with proper Kotlin DSL support, and validates that only `build.gradle` or `build.gradle.kts` files are accepted (not `settings.gradle`).
|
|
2130
2148
|
* Enables [pnpm monorepo instrumentation](#pnpm-monorexpo-setup) by allowing explicit `config=`, `gradle=`, and `plist=` arguments in root `package.json` scripts, supporting shared native project layouts where `android/` and `ios/` are not co-located with each app.
|
|
2131
|
-
* Added [actionNamePreference](#
|
|
2149
|
+
* Added [actionNamePreference](#manual-oneagent-startup) and [actionNameAlgorithm](#manual-oneagent-startup) configuration flags.
|
|
2132
2150
|
|
|
2133
2151
|
2.335.1
|
|
2134
2152
|
* Updated Android (8.335.1.1001) & iOS Agent (8.335.1.1009)
|
|
@@ -2152,12 +2170,12 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
|
|
|
2152
2170
|
|
|
2153
2171
|
2.329.1
|
|
2154
2172
|
* Updated Android (8.329.1.1014) & iOS Agent (8.329.1.1017)
|
|
2155
|
-
* [New RUM experience](#
|
|
2156
|
-
* [New RUM experience](#
|
|
2157
|
-
* [New RUM experience](#
|
|
2173
|
+
* [New RUM experience](#real-user-monitoring-rum) Removed Dynatrace.stopView() API
|
|
2174
|
+
* [New RUM experience](#real-user-monitoring-rum) Enforcing length limitation of 5000 characters for user input values
|
|
2175
|
+
* [New RUM experience](#real-user-monitoring-rum) React Native Deobfuscation service via sourcemaps
|
|
2158
2176
|
* Adding [`npx lineOffsetDynatrace`](#npx-lineoffsetdynatrace) command
|
|
2159
|
-
* [New RUM experience](#
|
|
2160
|
-
* [New RUM experience](#
|
|
2177
|
+
* [New RUM experience](#real-user-monitoring-rum) Added automated view tracking via [navigation](#automatic-navigation-tracking)
|
|
2178
|
+
* [New RUM experience](#real-user-monitoring-rum) Event and session properties are now sorted alphabetically when the limit of 50 is exceeded, ensuring deterministic property dropping
|
|
2161
2179
|
|
|
2162
2180
|
2.327.2
|
|
2163
2181
|
* Fixed iOS startup time calculation issues for React Native 0.72 and lower
|
|
@@ -2166,7 +2184,7 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
|
|
|
2166
2184
|
|
|
2167
2185
|
2.327.1
|
|
2168
2186
|
* Added [Compose Compatibility Note](#compose-compatibility-note)
|
|
2169
|
-
* Added [New RUM experience preview](#
|
|
2187
|
+
* Added [New RUM experience preview](#real-user-monitoring-rum) documentation
|
|
2170
2188
|
* Fixed iOS crash reporting by delaying the crash by 200ms on iOS to give the Agent enough time to report it
|
|
2171
2189
|
* Updated Android (8.327.2.1004) & iOS Agent (8.327.1.1020)
|
|
2172
2190
|
|
|
@@ -2175,8 +2193,8 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
|
|
|
2175
2193
|
|
|
2176
2194
|
2.325.1
|
|
2177
2195
|
* Updated Android (8.325.1.1007) & iOS Agent (8.325.1.1012)
|
|
2178
|
-
* [New RUM experience preview](#
|
|
2179
|
-
* [New RUM experience preview](#
|
|
2196
|
+
* [New RUM experience preview](#real-user-monitoring-rum) ReactNative version now added to RUM on Grail event base data
|
|
2197
|
+
* [New RUM experience preview](#real-user-monitoring-rum) Added API documentation for RUM on Grail API
|
|
2180
2198
|
|
|
2181
2199
|
2.323.2
|
|
2182
2200
|
* Fixed error "Execution failed for task ':app:mergeReleaseAssets'. A problem occured starting process 'command 'npx''" when building for release on Windows.
|
|
@@ -2362,7 +2380,7 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
|
|
|
2362
2380
|
2.247.1
|
|
2363
2381
|
* Updated Android Agent (8.247.1.1003) & iOS Agent (8.247.1.1007)
|
|
2364
2382
|
* Minimum supported Android SDK version raised to 21
|
|
2365
|
-
* Added [actionNamePrivacy](#
|
|
2383
|
+
* Added [actionNamePrivacy](#manual-oneagent-startup) configuration flag
|
|
2366
2384
|
* Removed `instrumentDynatrace` from package.json
|
|
2367
2385
|
* Adding [`npx instrumentDynatrace`](#npx-instrumentdynatrace) and [`npx configDynatrace`](#npx-configdynatrace) command
|
|
2368
2386
|
|