@dynatrace/react-native-plugin 2.327.2 → 2.329.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.
Files changed (52) hide show
  1. package/README.md +414 -163
  2. package/android/build.gradle +1 -1
  3. package/android/src/main/java/com/dynatrace/android/agent/DynatraceConfigurationModule.kt +48 -0
  4. package/android/src/main/java/com/dynatrace/android/agent/DynatraceRNBridgeImpl.kt +41 -8
  5. package/android/src/main/java/com/dynatrace/android/agent/DynatraceReactPackage.kt +3 -0
  6. package/android/src/main/java/com/dynatrace/android/agent/DynatraceRuntimeConfigurationStore.kt +14 -0
  7. package/android/src/main/java/com/dynatrace/android/agent/DynatraceUtils.kt +103 -47
  8. package/android/src/new/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +12 -4
  9. package/android/src/old/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +15 -5
  10. package/files/default.config.js +7 -0
  11. package/files/plugin-runtime.gradle +7 -17
  12. package/files/plugin.gradle +1 -1
  13. package/instrumentation/DynatraceInstrumentation.js +1 -1
  14. package/instrumentation/libs/react-navigation/ReactNavigation.js +53 -18
  15. package/ios/ConfigurationSubscriber.h +15 -0
  16. package/ios/DynatraceRNBridge.h +4 -0
  17. package/ios/DynatraceRNBridge.mm +125 -29
  18. package/lib/core/Dynatrace.js +8 -11
  19. package/lib/core/configuration/ConfigurationHandler.js +3 -0
  20. package/lib/next/Dynatrace.js +14 -32
  21. package/lib/next/DynatraceEventBus.js +35 -0
  22. package/lib/next/appstart/AppStartObserver.js +2 -3
  23. package/lib/next/configuration/INativeRuntimeConfiguration.js +7 -0
  24. package/lib/next/configuration/RuntimeConfigurationObserver.js +40 -0
  25. package/lib/next/events/EventBuilderUtil.js +7 -0
  26. package/lib/next/events/EventData.js +28 -0
  27. package/lib/next/events/EventPipeline.js +5 -11
  28. package/lib/next/events/ExceptionEventData.js +26 -0
  29. package/lib/next/events/{HttpRequestEventBuilder.js → HttpRequestEventData.js} +28 -52
  30. package/lib/next/events/SessionPropertyEventData.js +22 -0
  31. package/lib/next/events/interface/IBaseEvent.js +2 -0
  32. package/lib/next/events/interface/IEventData.js +2 -0
  33. package/lib/next/events/interface/IExceptionEventData.js +2 -0
  34. package/lib/next/events/interface/IHttpRequestEventData.js +2 -0
  35. package/lib/next/events/interface/ISessionPropertyEventData.js +2 -0
  36. package/lib/next/events/modifier/BaseDataEventModifier.js +1 -3
  37. package/lib/next/events/modifier/EventModifierUtil.js +34 -41
  38. package/lib/next/events/modifier/ModifyEventValidation.js +118 -26
  39. package/lib/next/events/modifier/SendEventValidation.js +53 -22
  40. package/lib/next/events/modifier/StringLengthEventModifier.js +53 -0
  41. package/lib/next/events/spec/EventSpecContstants.js +9 -2
  42. package/package.json +8 -3
  43. package/public.js +9 -3
  44. package/react-native-dynatrace.podspec +1 -1
  45. package/scripts/Config.js +6 -2
  46. package/scripts/LineOffsetAnalyze.js +1 -4
  47. package/scripts/core/LineOffsetAnalyzeCall.js +39 -46
  48. package/src/lib/core/interface/NativeDynatraceBridge.ts +6 -2
  49. package/types.d.ts +388 -158
  50. package/lib/next/events/ViewInfoCreator.js +0 -27
  51. package/lib/next/events/modifier/EventLimitation.js +0 -69
  52. /package/lib/next/events/{IHttpRequestEventBuilder.js → interface/EventProperty.js} +0 -0
package/README.md CHANGED
@@ -16,7 +16,6 @@ If you want to start using this plugin and are not a Dynatrace customer yet, hea
16
16
  * Manual instrumentation
17
17
  * Typescript bindings to add manual instrumentation
18
18
  * New React-Native architecture
19
- >**Note:** With iOS specifically, we noticed that there are some features that are not working the same as when using the current default architecture. You may experience issues with crash reporting being captured and web requests being linked to specific user actions. Per react native, [the new architecture is experimental](https://reactnative.dev/docs/the-new-architecture/landing-page#should-i-use-the-new-architecture-today). We will keep an eye on new updates and will continue to improve our support for the new architecture on both platforms.
20
19
 
21
20
  ## Requirements
22
21
  * React v16.8 or newer
@@ -34,8 +33,8 @@ If you want to start using this plugin and are not a Dynatrace customer yet, hea
34
33
  ## Agent Versions
35
34
  This agent versions are configured in this plugin:
36
35
 
37
- * Android Agent: 8.327.3.1006
38
- * iOS Agent: 8.327.2.1022
36
+ * Android Agent: 8.329.1.1014
37
+ * iOS Agent: 8.329.1.1017
39
38
 
40
39
  ## Quick Setup
41
40
 
@@ -64,21 +63,34 @@ This agent versions are configured in this plugin:
64
63
  * [Platform independent reporting](#platform-independent-reporting)
65
64
  * [Set beacon headers](#setting-beacon-headers)
66
65
  * [Exclude Individual JSX Elements](#exclude-individual-jsx-elements)
67
- * [New RUM experience preview](#new-rum-experience-preview)
66
+ * [New RUM experience](#new-rum-experience)
68
67
  * [Send Event](#send-event)
69
68
  * [Send Session Property Event](#send-session-property-event)
70
69
  * [Event Modifier](#event-modifier)
71
70
  * [Send Exception Event](#send-exception-event)
72
71
  * [Send HTTP Request Event](#send-http-request-event)
73
72
  * [View Monitoring](#view-monitoring)
73
+ * [React Native Symbolication](#react-native-symbolication)
74
74
  * [NPX Commands](#npx-commands)
75
75
  * [npx instrumentDynatrace](#npx-instrumentdynatrace)
76
76
  * [npx configDynatrace](#npx-configdynatrace)
77
+ * [npx lineOffsetDynatrace](#npx-lineoffsetdynatrace)
77
78
  * [Customizing paths for configuration](#customizing-paths-for-configuration)
78
79
  * [Manual adding iOS Agent to project](#manually-adding-ios-oneagent-to-a-project)
79
80
  * [Setup for tvOS](#setup-for-tvos)
80
81
  * [Configuration structure](#structure-of-the-dynatracejs-file)
81
82
  * [Manual Startup Counterparts](#manual-startup-counterparts)
83
+ * [React block](#react-block)
84
+ * [Input](#input)
85
+ * [Lifecycle](#lifecycle)
86
+ * [Debug mode](#debug-mode)
87
+ * [Error Handler](#error-handler)
88
+ * [Autostart](#autostart)
89
+ * [Bundle Name and Version](#bundle-name-and-version)
90
+ * [Navigation](#navigation)
91
+ * [Source Map](#source-map)
92
+ * [Android block](#android-block)
93
+ * [iOS block](#ios-block)
82
94
  * [Lifecycle modes](#lifecycle)
83
95
  * [Define build stages](#define-build-stages-in-dynatraceconfigjs)
84
96
  * [User Opt In Mode](#user-opt-in-mode)
@@ -224,11 +236,11 @@ A manual startup requires the following two steps:
224
236
 
225
237
  1. Deactivate the automated startup in `dynatrace.config.js`:
226
238
 
227
- ```js
239
+ ```ts
228
240
  module.exports = {
229
241
  react: {
230
242
  autoStart: false,
231
- ...
243
+ // ...
232
244
  },
233
245
  android: {
234
246
  config: `
@@ -246,8 +258,8 @@ module.exports = {
246
258
  <key>DTXAutoStart</key>
247
259
  <false/>
248
260
  `
249
- }
250
- }
261
+ },
262
+ };
251
263
  ```
252
264
 
253
265
  2. Make the start-up call with at least `beaconUrl` and `applicationId`:
@@ -287,8 +299,7 @@ configurationBuilder.withCrashReporting(true)
287
299
  .withLogLevel(LogLevel.Info)
288
300
  .withLifecycleUpdate(false)
289
301
  .withUserOptIn(false)
290
- .withActionNamePrivacy(false)
291
- .withBundleName(undefined);
302
+ .withActionNamePrivacy(false);
292
303
 
293
304
  await Dynatrace.start(configurationBuilder.buildConfiguration());
294
305
  ```
@@ -320,9 +331,10 @@ A component can be either monitored automatically or manually. The auto instrume
320
331
 
321
332
  ```ts
322
333
  import { Dynatrace } from '@dynatrace/react-native-plugin';
334
+ import { FunctionComponent } from 'react';
323
335
 
324
- export function MyFunctionalComponent(){
325
- ...
336
+ export const MyFunctionalComponent: FunctionComponent<{}> = () => {
337
+ return null;
326
338
  }
327
339
 
328
340
  Dynatrace.withMonitoring(MyFunctionalComponent, "MyFunctionalComponent");
@@ -412,22 +424,25 @@ Using this API will force the request to be added to the action that is manually
412
424
  ```ts
413
425
  import { Dynatrace, DynatraceWebRequestTiming } from '@dynatrace/react-native-plugin';
414
426
 
415
- let url = 'https://www.dynatrace.com';
416
- // You can also use enterAutoAction if desired
417
- let action = Dynatrace.enterManualAction("Manual Web Request");
418
- let tag = await action.getRequestTag(url);
419
- let timing = new DynatraceWebRequestTiming(tag, url);
427
+ const action = Dynatrace.enterManualAction('API Data Fetch');
428
+ const url = 'https://api.example.com/data';
429
+ const tag = await action.getRequestTag(url);
430
+ const timing = new DynatraceWebRequestTiming(url, tag);
420
431
 
421
- try {
432
+ try {
422
433
  timing.startWebRequestTiming();
423
- let axiosResponse = await axios.get(url, {
434
+ const response = await fetch(url, {
424
435
  headers: {
425
- timing.getRequestTagHeader(): tag
436
+ [timing.getRequestTagHeader()]: tag
426
437
  }
427
438
  });
428
- timing.stopWebRequestTiming(axiosResponse.status, axiosResponse.data);
439
+ timing.stopWebRequestTiming(response.status, response.statusText);
429
440
  } catch (error) {
430
- timing.stopWebRequestTiming(-1, error);
441
+ if (error instanceof Error) {
442
+ timing.stopWebRequestTiming(-1, error.message);
443
+ } else {
444
+ timing.stopWebRequestTiming(-1, (error as any).toString());
445
+ }
431
446
  } finally {
432
447
  action.leaveAction();
433
448
  }
@@ -439,22 +454,35 @@ There is also the option to report values for request and response size:
439
454
  ```ts
440
455
  import { Dynatrace, DynatraceWebRequestTiming } from '@dynatrace/react-native-plugin';
441
456
 
442
- let url = 'https://www.dynatrace.com';
443
- // You can also use enterAutoAction if desired
444
- let action = Dynatrace.enterManualAction("Manual Web Request");
445
- let tag = await action.getRequestTag(url);
446
- let timing = new DynatraceWebRequestTiming(url, tag);
457
+ const action = Dynatrace.enterManualAction('API Data Upload');
458
+ const url = 'https://api.example.com/upload';
459
+ const tag = await action.getRequestTag(url);
460
+ const timing = new DynatraceWebRequestTiming(url, tag);
461
+ const requestData = JSON.stringify({ key: 'value' });
447
462
 
448
- try {
463
+ try {
449
464
  timing.startWebRequestTiming();
450
- let axiosResponse = await axios.get(url, {
465
+ const response = await fetch(url, {
466
+ method: 'POST',
451
467
  headers: {
452
- timing.getRequestTagHeader(): tag
453
- }
468
+ [timing.getRequestTagHeader()]: tag,
469
+ 'Content-Type': 'application/json'
470
+ },
471
+ body: requestData
454
472
  });
455
- timing.stopWebRequestTimingWithSize(axiosResponse.status, axiosResponse.data, 122, 63);
473
+ const responseData = await response.text();
474
+ timing.stopWebRequestTimingWithSize(
475
+ response.status,
476
+ response.statusText,
477
+ requestData.length,
478
+ responseData.length
479
+ );
456
480
  } catch (error) {
457
- timing.stopWebRequestTiming(-1, error);
481
+ if (error instanceof Error) {
482
+ timing.stopWebRequestTiming(-1, error.message);
483
+ } else {
484
+ timing.stopWebRequestTiming(-1, (error as any).toString());
485
+ }
458
486
  } finally {
459
487
  action.leaveAction();
460
488
  }
@@ -466,11 +494,15 @@ try {
466
494
  For any open action you can report certain values. The following API is available for action:
467
495
 
468
496
  ```ts
469
- reportDoubleValue(valueName: string, value: number, platform?: Platform): void
470
- reportError(errorName: string, errorCode: number, platform?: Platform): void
471
- reportEvent(eventName: string, platform?: Platform): void
472
- reportIntValue(valueName: string, value: number, platform?: Platform): void
473
- reportStringValue(valueName: string, value: string, platform?: Platform): void
497
+ import { Platform } from '@dynatrace/react-native-plugin';
498
+
499
+ interface IDynatraceAction {
500
+ reportDoubleValue(valueName: string, value: number, platform?: Platform): void;
501
+ reportError(errorName: string, errorCode: number, platform?: Platform): void;
502
+ reportEvent(eventName: string, platform?: Platform): void;
503
+ reportIntValue(valueName: string, value: number, platform?: Platform): void;
504
+ reportStringValue(valueName: string, value: string, platform?: Platform): void;
505
+ }
474
506
  ```
475
507
 
476
508
  **Important:** All string parameters (errorName, eventName, valueName, value) are limited to 250 characters and will be truncated if they exceed this limit.
@@ -494,7 +526,20 @@ If you look at the API calls, you will see the optional parameter `platform?: Pl
494
526
  To manually report an error stacktrace, use the following API call:
495
527
 
496
528
  ```ts
497
- reportErrorStacktrace(errorName: string, errorValue: string, reason: string, stacktrace: string, platform?: Platform): void;
529
+ import { Dynatrace } from '@dynatrace/react-native-plugin';
530
+
531
+ try {
532
+ throw new Error('Database connection failed');
533
+ } catch (error) {
534
+ if (error instanceof Error) {
535
+ Dynatrace.reportErrorStacktrace(
536
+ 'DatabaseError',
537
+ error.message,
538
+ 'Failed to connect to remote database',
539
+ error.stack || 'No stack trace available'
540
+ );
541
+ }
542
+ }
498
543
  ```
499
544
  ![rnStack](https://dt-cdn.net/images/rnstack-800-26c6ac7408.png)
500
545
 
@@ -528,11 +573,25 @@ Dynatrace.endSession();
528
573
 
529
574
  ### Manually report a crash
530
575
 
531
- You can manually report a crash via the following API call:
576
+ You can manually report a crash via the following API calls:
532
577
 
533
578
  ```ts
534
- reportCrash(crashName: string, reason: string, stacktrace: string, platform?: Platform): void;
535
- reportCrashWithException(crashName: string, crash: Error, platform?: Platform): void;
579
+ import { Dynatrace } from '@dynatrace/react-native-plugin';
580
+
581
+ try {
582
+ throw new Error('Fatal memory allocation failure');
583
+ } catch (error) {
584
+ if (error instanceof Error) {
585
+ Dynatrace.reportCrash(
586
+ 'MemoryError',
587
+ error.message,
588
+ error.stack || 'No stack trace available'
589
+ );
590
+
591
+ // or directly via the full error
592
+ Dynatrace.reportCrashWithException('MemoryError', error);
593
+ }
594
+ }
536
595
  ```
537
596
  ![rnCrash](https://dt-cdn.net/images/rncrash-800-3e7391140f.png)
538
597
 
@@ -559,8 +618,12 @@ Crash reporting is enabled by default. The Mobile agent captures all unhandled e
559
618
  The API to get and set the current privacy level looks like this:
560
619
 
561
620
  ```ts
562
- async getUserPrivacyOptions(platform?: Platform): Promise<UserPrivacyOptions>;
563
- applyUserPrivacyOptions(userPrivacyOptions: UserPrivacyOptions, platform?: Platform): void;
621
+ import { Platform, UserPrivacyOptions } from '@dynatrace/react-native-plugin';
622
+
623
+ interface IDynatrace {
624
+ getUserPrivacyOptions(platform?: Platform): Promise<UserPrivacyOptions>;
625
+ applyUserPrivacyOptions(userPrivacyOptions: UserPrivacyOptions, platform?: Platform): void;
626
+ }
564
627
  ```
565
628
 
566
629
  To check the current privacy options that are set:
@@ -571,32 +634,19 @@ import { Dynatrace } from '@dynatrace/react-native-plugin';
571
634
  const privacyOptions = await Dynatrace.getUserPrivacyOptions();
572
635
  ```
573
636
 
574
- If you want to create a new `UserPrivacyOptions` object:
637
+ If you want to create a new `UserPrivacyOptions` object and pass it to Dynatrace:
575
638
 
576
639
  ```ts
577
- import { DataCollectionLevel, UserPrivacyOptions } from '@dynatrace/react-native-plugin';
578
-
579
- let privacyConfig = new UserPrivacyOptions(DataCollectionLevel.UserBehavior, true);
580
- ```
640
+ import { Dynatrace, DataCollectionLevel, UserPrivacyOptions } from '@dynatrace/react-native-plugin';
581
641
 
582
- To set new values to this object:
642
+ const privacyConfig = new UserPrivacyOptions(DataCollectionLevel.UserBehavior, true);
583
643
 
584
- ```ts
644
+ // Getter and setter available for UserPrivacyOptions
585
645
  privacyConfig.crashReportingOptedIn = false;
586
646
  privacyConfig.dataCollectionLevel = DataCollectionLevel.Performance;
587
- ```
588
-
589
- The properties that are used to set the privacy options can also be used to fetch the options:
590
647
 
591
- ```ts
592
- let level = privacyConfig.dataCollectionLevel;
593
- let crashReporting = privacyConfig.crashReportingOptedIn;
594
- ```
595
-
596
- To apply the values that were set on the object:
597
-
598
- ```ts
599
- import { Dynatrace } from '@dynatrace/react-native-plugin';
648
+ const level = privacyConfig.dataCollectionLevel;
649
+ const crashReporting = privacyConfig.crashReportingOptedIn;
600
650
 
601
651
  Dynatrace.applyUserPrivacyOptions(privacyConfig);
602
652
  ```
@@ -606,7 +656,9 @@ Dynatrace.applyUserPrivacyOptions(privacyConfig);
606
656
  You can report latitude and longitude and specify an optional platform.
607
657
 
608
658
  ```ts
609
- setGPSLocation(latitude: number, longitude: number, platform?: Platform): void
659
+ import { Dynatrace } from '@dynatrace/react-native-plugin';
660
+
661
+ Dynatrace.setGPSLocation(48.31518732698596, 14.305245274594471);
610
662
  ```
611
663
 
612
664
  ### Platform independent reporting
@@ -618,7 +670,7 @@ import { Dynatrace, Platform } from '@dynatrace/react-native-plugin';
618
670
 
619
671
  const myAction = Dynatrace.enterAutoAction("MyButton tapped", Platform.Ios);
620
672
  //Perform the action and whatever else is needed.
621
- myAction.leaveAction("ios");
673
+ myAction.leaveAction(Platform.Ios);
622
674
  ```
623
675
 
624
676
  * Passing to **Android** only:
@@ -627,7 +679,7 @@ import { Dynatrace, Platform } from '@dynatrace/react-native-plugin';
627
679
 
628
680
  const myAction = Dynatrace.enterAutoAction("MyButton tapped", Platform.Android);
629
681
  //Perform the action and whatever else is needed.
630
- myAction.leaveAction("android");
682
+ myAction.leaveAction(Platform.Android);
631
683
  ```
632
684
 
633
685
  * Passing to **both**:
@@ -671,15 +723,22 @@ This allows you to put a set of http headers on every agent http request (i.e. A
671
723
  **Note:** To clear the previously set headers, call the method without the headers parameter or with a null value for the headers parameter.
672
724
 
673
725
  ```ts
674
- setBeaconHeaders(headers?: Map<string, string> | null, platform?: Platform): void;
726
+ import { Dynatrace } from '@dynatrace/react-native-plugin';
727
+
728
+ const beaconHeaders = new Map<string, string>();
729
+ beaconHeaders.set('headerName', 'headerValue');
730
+ Dynatrace.setBeaconHeaders(beaconHeaders);
675
731
  ```
676
732
 
677
733
  ### Exclude Individual JSX Elements
678
734
 
679
735
  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:
680
736
 
681
- ```ts
682
- function TouchableHighlightScreen() {
737
+ ```tsx
738
+ import React from 'react';
739
+ import { TouchableHighlight, Text, View } from 'react-native';
740
+
741
+ const TouchableHighlightScreen = () => {
683
742
  return (
684
743
  <View>
685
744
  <TouchableHighlight onPress={onPress}>
@@ -690,11 +749,11 @@ function TouchableHighlightScreen() {
690
749
  </TouchableHighlight>
691
750
  </View>
692
751
  );
693
- }
752
+ };
694
753
 
695
- function onPress() {
696
- Logger.logDebug("TouchableHighlight Pressed!");
697
- }
754
+ const onPress = () => {
755
+ console.log("TouchableHighlight Pressed!");
756
+ };
698
757
 
699
758
  export default TouchableHighlightScreen;
700
759
  ```
@@ -703,34 +762,33 @@ This example shows two *TouchableHighlight*, which will fire the *onPress()* fun
703
762
 
704
763
  >*Attention:* If you are using Typescript and want to set this property with type-safety, look [here](#typescript-setup-for-dtactionignore-and-dtactionname).
705
764
 
706
- ## New RUM experience preview
707
-
708
- > **⚠️ Preview Feature**: The New RUM Experience APIs are currently in preview and may be subject to changes. These APIs provide enhanced event tracking capabilities with the new Dynatrace RUM on Grail feature.
765
+ ## New RUM experience
709
766
 
710
767
  The New RUM Experience 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.
711
768
 
712
- For more detailed information about the New RUM Experience, see the [official Dynatrace documentation](https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/api).
769
+ For more detailed information about the New RUM Experience, see the [official Dynatrace documentation](https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/mobile-frontends).
713
770
 
714
771
  ### Send Event
715
772
 
716
- The `sendEvent()` method allows you to send custom events with arbitrary properties in JSON format. This is useful for tracking specific user interactions or application state changes.
773
+ 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.
717
774
 
718
775
  ```ts
719
- import { Dynatrace } from '@dynatrace/react-native-plugin';
776
+ import { Dynatrace, EventData } from '@dynatrace/react-native-plugin';
720
777
 
721
778
  // Send a custom event with properties
722
- Dynatrace.sendEvent({
723
- "event_properties.button_clicked": "login_button",
724
- "event_properties.user_type": "premium",
725
- "event_properties.attempt_count": 3,
726
- "duration": 250
727
- });
779
+ Dynatrace.sendEvent(new EventData()
780
+ .addEventProperty("event_properties.button_clicked", "login_button")
781
+ .addEventProperty("event_properties.user_type", "premium")
782
+ .addEventProperty("event_properties.attempt_count", 3)
783
+ .withDuration(250)
784
+ );
728
785
  ```
729
786
 
730
787
  **Property Requirements:**
731
788
  * Only properties prefixed with `event_properties.*` are allowed
732
789
  * Additionally, the `duration` property is allowed
733
790
  * Maximum of 50 custom properties per event
791
+ * If the limit is exceeded, properties are sorted alphabetically by key and excess properties are dropped deterministically
734
792
  * String properties are limited to 5000 characters (exceeding characters are truncated)
735
793
  * Field names must contain only alphabetic characters, numbers, underscores, and dots
736
794
  * Each dot must be followed by an alphabetic character
@@ -743,14 +801,14 @@ Dynatrace.sendEvent({
743
801
  Session properties apply to all events within the current session. Use `sendSessionPropertyEvent()` to set properties that should be available across the entire user session.
744
802
 
745
803
  ```ts
746
- import { Dynatrace } from '@dynatrace/react-native-plugin';
804
+ import { Dynatrace, SessionPropertyEventData } from '@dynatrace/react-native-plugin';
747
805
 
748
806
  // Set session-wide properties
749
- Dynatrace.sendSessionPropertyEvent({
750
- "session_properties.user_tier": "premium",
751
- "session_properties.app_version": "2.1.0",
752
- "session_properties.feature_flag_enabled": true
753
- });
807
+ Dynatrace.sendSessionPropertyEvent(new SessionPropertyEventData()
808
+ .addSessionProperty("session_properties.user_tier", "premium")
809
+ .addSessionProperty("session_properties.app_version", "2.1.0")
810
+ .addSessionProperty("session_properties.feature_flag_enabled", true)
811
+ );
754
812
  ```
755
813
 
756
814
  **Important Notes:**
@@ -760,16 +818,33 @@ Dynatrace.sendSessionPropertyEvent({
760
818
  * Field naming follows the same rules as events, but with `session_properties.` prefix
761
819
  * Additionally, the `duration` property is allowed
762
820
  * Maximum of 50 custom properties per event
821
+ * If the limit is exceeded, properties are sorted alphabetically by key and excess properties are dropped deterministically
763
822
 
764
823
  ### Event Modifier
765
824
 
766
- 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.
825
+ 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.
826
+
827
+ If multiple event modifiers are added, they are executed in the order they were added.
828
+
829
+ Most fields and namespaces can't be modified in any way (added, removed or overridden), while others are open for modification.
830
+
831
+ **Open for modification and can be added:**
832
+ - `event_properties.*`
833
+ - `session_properties.*`
834
+
835
+ `session_properties.*` are only allowed to be on a session property event.
836
+
837
+ **Open for modification only:**
838
+ - `url.full`
839
+ - `exception.stack_trace`
840
+
841
+ #### Example
767
842
 
768
843
  ```ts
769
- import { Dynatrace } from '@dynatrace/react-native-plugin';
844
+ import { Dynatrace, IEventModifier } from '@dynatrace/react-native-plugin';
770
845
 
771
846
  // Create an event modifier
772
- const myModifier = {
847
+ const myModifier: IEventModifier = {
773
848
  modifyEvent(event) {
774
849
  // Add common properties to all events
775
850
  event["event_properties.app_build"] = "1.2.3";
@@ -791,57 +866,116 @@ Dynatrace.addEventModifier(myModifier);
791
866
  Dynatrace.removeEventModifier(myModifier);
792
867
  ```
793
868
 
794
- **Important Considerations:**
795
- * Modifiers are executed in the order they were added
796
- * Returning `null` from a modifier discards the event and prevents subsequent modifiers from executing
797
- * Certain reserved fields and namespaces cannot be modified (see [Dynatrace documentation](https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/api) for details)
798
- * Modifiers should be efficient as they are called for every event
869
+ #### Important Considerations
870
+
871
+ - **Execution order**: If multiple event modifiers are added, they are executed in the order they were added
872
+ - **Returning null**: Returning `null` discards the event and prevents future modifier functions from being executed
873
+ - **Performance**: Event modifiers should be efficient as they are called for every event
874
+ - **Field naming**: Custom properties must follow the `event_properties.*` or `session_properties.*` prefix naming convention
875
+ - **Reserved fields**: Certain reserved fields and namespaces cannot be modified. Attempts to modify them will be ignored
876
+ - **Error handling**: If a modifier throws an exception, it will be logged but won't prevent other modifiers from executing
877
+ - **Primitive values**: Event fields can only contain primitive values (String, int, double, bool)
799
878
 
800
879
  ### Send Exception Event
801
880
 
802
- The `sendExceptionEvent()` method provides a structured way to report exceptions with additional context and custom properties.
881
+ The `sendExceptionEvent()` method provides a structured way to report exceptions with additional context and custom properties using the ExceptionEventData class.
803
882
 
804
883
  ```ts
805
- import { Dynatrace } from '@dynatrace/react-native-plugin';
884
+ import { Dynatrace, ExceptionEventData } from '@dynatrace/react-native-plugin';
806
885
 
807
886
  try {
808
- // Code that might throw an error
809
- await riskyOperation();
887
+ // Code that may throw an error
888
+ throw new Error('Something went wrong');
810
889
  } catch (error) {
811
- Dynatrace.sendExceptionEvent(error, {
812
- "event_properties.operation_type": "data_sync",
813
- "event_properties.retry_count": 3,
814
- "event_properties.user_id": "user123"
815
- });
890
+ if (error instanceof Error) {
891
+ Dynatrace.sendExceptionEvent(new ExceptionEventData(error)
892
+ .addEventProperty('event_properties.custom_key', 'custom_value')
893
+ .addEventProperty('event_properties.error_context', 'user_action')
894
+ );
895
+ }
816
896
  }
817
897
  ```
818
898
 
819
899
  **Parameters:**
820
900
  * `error`: The Error object containing exception information (required)
821
- * `fields`: Optional custom properties following the same naming rules as [sendEvent()](#send-event)
822
901
 
823
902
  ### Send HTTP Request Event
824
903
 
825
904
  The `sendHttpRequestEvent()` method allows you to manually report HTTP request events with detailed information about the request and response.
826
905
 
827
906
  ```ts
828
- import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
907
+ import { Dynatrace, HttpRequestEventData } from '@dynatrace/react-native-plugin';
829
908
 
830
909
  // Basic HTTP request event
831
- const requestBuilder = new HttpRequestEventBuilder('https://api.example.com/users', 'GET');
832
- Dynatrace.sendHttpRequestEvent(requestBuilder);
910
+ const requestEventData = new HttpRequestEventData('https://api.example.com/users', 'GET');
911
+ Dynatrace.sendHttpRequestEvent(requestEventData);
833
912
 
834
913
  // HTTP request with additional details
835
- const detailedBuilder = new HttpRequestEventBuilder('https://api.example.com/data', 'POST')
836
- .setResponseCode(200)
837
- .setRequestHeaders({ 'Content-Type': 'application/json' });
838
- Dynatrace.sendHttpRequestEvent(detailedBuilder);
914
+ const detailedRequestEventData = new HttpRequestEventData('https://api.example.com/data', 'POST')
915
+ .withStatusCode(200)
916
+ .addEventProperty('event_properties.headers.content_type', 'application/json');
917
+ Dynatrace.sendHttpRequestEvent(detailedRequestEventData);
839
918
  ```
840
919
 
920
+ **Parameters:**
921
+ * `url`: The URL of the HTTP request (required)
922
+ * `method`: The HTTP method (e.g., 'GET', 'POST', 'PUT', 'DELETE') (required)
923
+
841
924
  ### View Monitoring
842
925
 
843
926
  The view monitoring APIs allow you to track different screens or views in your application, providing context for all events happening within those views.
844
927
 
928
+ There are two ways to monitor views:
929
+ 1. **Automatic view monitoring** - Enable navigation tracking in your configuration to automatically capture view changes through supported navigation libraries (enabled by default)
930
+ 2. **Manual view monitoring** - Use the `startView()` API to manually control when view contexts are created and updated
931
+
932
+ > **Important:** These approaches should not be mixed, as the outcome is unpredictable. Choose either automatic or manual view monitoring for your application.
933
+
934
+ #### Automatic Navigation tracking
935
+
936
+ > **Note:** This feature only works with `@react-navigation` versions 5.x through 7.x.
937
+
938
+ 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.
939
+
940
+ ```js
941
+ react: {
942
+ navigation: {
943
+ enabled: true
944
+ }
945
+ }
946
+ ```
947
+
948
+ 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.
949
+
950
+ For instance, assume the following setup:
951
+ ```js
952
+ const Drawer = createDrawerNavigator();
953
+
954
+ function App() {
955
+ return (
956
+ <NavigationContainer>
957
+ <Drawer.Navigator initialRouteName="Home">
958
+ <Drawer.Screen name="Home" component={HomeScreen} />
959
+ <Drawer.Screen name="Feature" component={FeatureScreen}/>
960
+ </Drawer.Navigator>
961
+ </NavigationContainer>
962
+ );
963
+ }
964
+
965
+ const Stack = createStackNavigator();
966
+
967
+ function FeatureScreen() {
968
+ return (
969
+ <Stack.Navigator initialRouteName="ScreenOne">
970
+ <Stack.Screen name="ScreenOne" component={NestedScreenOne} />
971
+ <Stack.Screen name="ScreenTwo" component={NestedScreenTwo} />
972
+ </Stack.Navigator>
973
+ );
974
+ }
975
+ ```
976
+
977
+ 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`.
978
+
845
979
  #### Start View
846
980
 
847
981
  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.
@@ -859,41 +993,61 @@ Dynatrace.startView("HomeScreen");
859
993
  * View names should be meaningful and consistent across your application
860
994
  * All events captured after starting a view will include the view context
861
995
 
862
- #### Stop View
863
-
864
- Use `stopView()` to stop monitoring the current view. After stopping, events will no longer include view information.
865
-
866
- ```ts
867
- import { Dynatrace } from '@dynatrace/react-native-plugin';
868
-
869
- // Stop the current view monitoring
870
- Dynatrace.stopView();
871
- ```
872
-
873
996
  **Complete Example:**
874
997
 
875
998
  ```ts
876
- import { Dynatrace } from '@dynatrace/react-native-plugin';
999
+ import { Dynatrace, EventData } from '@dynatrace/react-native-plugin';
877
1000
 
878
1001
  // User navigates to profile screen
879
1002
  Dynatrace.startView("UserProfile");
880
1003
 
881
1004
  // Send custom event within the view
882
- Dynatrace.sendEvent({
883
- "event_properties.profile_action": "edit_profile",
884
- "event_properties.changes_made": true
885
- });
1005
+ Dynatrace.sendEvent(new EventData()
1006
+ .addEventProperty("event_properties.profile_action", "edit_profile")
1007
+ .addEventProperty("event_properties.changes_made", true)
1008
+ );
886
1009
 
887
1010
  // User navigates away
888
- Dynatrace.stopView();
1011
+ Dynatrace.startView("UserProfileDetailed");
889
1012
  ```
890
1013
 
1014
+ ### React Native Symbolication
1015
+
1016
+ 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.
1017
+
1018
+ #### Generating Sourcemaps
1019
+
1020
+ 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).
1021
+
1022
+ To generate a sourcemap:
1023
+
1024
+ **Android:**
1025
+ * Run `npx react-native run-android --mode release` in your project root, or
1026
+ * Run `gradlew assembleRelease` in the `/android` directory
1027
+
1028
+ **iOS:**
1029
+ * First, enable sourcemaps according to the [React Native debugging release builds guide](https://reactnative.dev/docs/debugging-release-builds)
1030
+ * Then run `npx react-native run-ios --mode Release`, or
1031
+ * Build for release in Xcode
1032
+
1033
+ #### Accounting for Auto-Instrumentation
1034
+
1035
+ Since the plugin auto-instruments your code, sourcemap line numbers may be slightly offset. To ensure accurate symbolication:
1036
+
1037
+ * **Android**: Automatic patching is **enabled by default** and patches sourcemaps automatically at the end of every release build (see [Source Map](#source-map) configuration)
1038
+ * **iOS**: There is currently **no automation** available. You **must** execute [`npx lineOffsetDynatrace`](#npx-lineoffsetdynatrace) to patch your sourcemap files before uploading them to Dynatrace. Without this step, line numbers will be slightly off depending on instrumentation in iOS
1039
+
1040
+ #### Uploading Sourcemaps
1041
+
1042
+ Once generated and patched, 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).
1043
+
891
1044
  ## NPX Commands
892
1045
 
893
1046
  The following npx commands are available for the plugin:
894
1047
 
895
1048
  * 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.
896
1049
  * npx configDynatrace - Is checking the current configuration and is creating a default configuration if there is none.
1050
+ * npx lineOffsetDynatrace - ...
897
1051
 
898
1052
  ### npx instrumentDynatrace
899
1053
 
@@ -913,6 +1067,19 @@ npx configDynatrace [optional: config=...]
913
1067
 
914
1068
  * `config=C:\SpecialFolderForDynatrace\dynatrace.config.js`: If you have not got your config file in the root folder of the React Native project but somewhere else.
915
1069
 
1070
+ ## npx lineOffsetDynatrace
1071
+
1072
+ Our auto-instrumentation modifies your source code during the build process, which causes line numbers in your sourcemaps to become slightly offset from the original source. This can result in incorrect line numbers when viewing crash reports or stack traces in Dynatrace.
1073
+
1074
+ The `npx lineOffsetDynatrace` command patches your sourcemap file with offset information, allowing Dynatrace to accurately map instrumented line numbers back to the original source code. The patching process adds Dynatrace-specific metadata alongside the original sourcemap content without modifying any existing fields, ensuring your sourcemap continues to work as expected with all standard tooling.
1075
+
1076
+ **Usage:**
1077
+
1078
+ ```
1079
+ npx lineOffsetDynatrace sourcemapPath=/path/to/your/sourcemap.map
1080
+ ```
1081
+
1082
+ * `sourcemapPath=/path/to/your/sourcemap.map`: **(Required)** The path to the sourcemap file that should be patched.
916
1083
 
917
1084
  ## Customizing paths for configuration
918
1085
 
@@ -960,7 +1127,7 @@ pod 'react-native-dynatrace', :path => '../node_modules/@dynatrace/react-native-
960
1127
  5. Under Build Phases expand the Link Binary With Libraries header.
961
1128
  6. Scroll down and click + to add a library.
962
1129
  7. Find and add `libRNDynatrace.a` under the Workspace group.
963
- 8. ⌘+B
1130
+ 8. ⌘+B
964
1131
 
965
1132
  ## Setup for tvOS
966
1133
 
@@ -970,7 +1137,7 @@ To allow our plugin to work with tvOS, please follow the below steps:
970
1137
 
971
1138
  Before installing the plugin, add the following to your `package.json`:
972
1139
 
973
- ```js
1140
+ ```
974
1141
  "overrides": {
975
1142
  "@react-native-picker/picker": {
976
1143
  "react-native": "<insert-version-here>"
@@ -983,7 +1150,7 @@ Before installing the plugin, add the following to your `package.json`:
983
1150
 
984
1151
  If you are using the following `"react-native": "npm:react-native-tvos@0.69.8-2"`, use the below snippet:
985
1152
 
986
- ```js
1153
+ ```
987
1154
  "overrides": {
988
1155
  "@react-native-picker/picker": {
989
1156
  "react-native": "0.69.8-2"
@@ -1001,13 +1168,13 @@ Examples:
1001
1168
 
1002
1169
  Using React Native v0.69.x or lower and @react-native-community/cli v8.x or lower:
1003
1170
 
1004
- ```js
1171
+ ```
1005
1172
  npx react-native run-ios --simulator "Apple TV" --scheme "ApplicationName-tvOS" plist=/path/to/application/ios/ApplicationName-tvOS/Info.plist
1006
1173
  ```
1007
1174
 
1008
1175
  Using React Native v0.70 or higher or @react-native-community/cli v9.x or higher:
1009
1176
 
1010
- ```js
1177
+ ```
1011
1178
  // Update the Info.plist with the properties from the dynatrace.config.js file
1012
1179
  npx instrumentDynatrace plist=/path/to/application/ios/ApplicationName-tvOS/Info.plist
1013
1180
 
@@ -1022,7 +1189,7 @@ For more information regarding the differences in the react native versions, ple
1022
1189
  ## Structure of the `dynatrace.js` file
1023
1190
  The configuration is structured in the following way:
1024
1191
 
1025
- ```js
1192
+ ```ts
1026
1193
  module.exports = {
1027
1194
  react : {
1028
1195
  // Configuration for React Native instrumentation
@@ -1033,7 +1200,7 @@ module.exports = {
1033
1200
  ios : {
1034
1201
  // Configuration for iOS auto instrumentation
1035
1202
  }
1036
- }
1203
+ };
1037
1204
  ```
1038
1205
 
1039
1206
  ### Manual Startup Counterparts
@@ -1104,12 +1271,15 @@ This activates the debug mode. You will get more console output during instrumen
1104
1271
  #### Error Handler
1105
1272
 
1106
1273
  ```js
1107
- react: {
1108
- errorHandler: {
1109
- enabled: true,
1110
- reportFatalErrorAsCrash: true,
1111
- },
1112
- }
1274
+ module.exports = {
1275
+ // ...
1276
+ react: {
1277
+ errorHandler: {
1278
+ enabled: true,
1279
+ reportFatalErrorAsCrash: true,
1280
+ },
1281
+ }
1282
+ };
1113
1283
  ```
1114
1284
 
1115
1285
  The `enabled` property activates our Error/Crash handler which will insert our handler into your React Native application. This is true per default.
@@ -1130,13 +1300,67 @@ react: {
1130
1300
 
1131
1301
  This activates the AutoStart mode which will insert an auto start call in your React Native application. This is true per default. If you want to use a manual startup call, please have a look into the [manual startup section](#manual-oneagent-startup).
1132
1302
 
1133
- #### Bundle Name
1303
+ #### Bundle Name and Version
1304
+
1305
+ By default, the plugin automatically reads the `name` and `version` fields from your `package.json` file and uses them as `bundleName` and `bundleVersion`. These values are included with New RUM on Grail Events and are critical for crash symbolication.
1134
1306
 
1135
- 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.
1307
+ **Important for Crash Symbolication:**
1308
+ When uploading sourcemap files to Dynatrace, you must specify the same `bundleName` and `bundleVersion` values. The sourcemap desymbolication feature requires an exact match between:
1309
+
1310
+ * The `bundleName` and `bundleVersion` sent with the crash report
1311
+ * The `bundleName` and `bundleVersion` specified when uploading the sourcemap file
1312
+
1313
+ If these values don't match, the Error Inspector will not be able to use the sourcemap file to symbolicate the crash.
1314
+
1315
+ **Custom Configuration:**
1316
+ You can override the default values from `package.json` by explicitly setting them in `dynatrace.config.js`:
1317
+
1318
+ ```js
1319
+ react: {
1320
+ bundleName: "MyCustomBundle",
1321
+ bundleVersion: "1.0.0",
1322
+ }
1323
+ ```
1324
+
1325
+ **Multiple Bundle Setup:**
1326
+ If you have a multiple bundle setup where you load several `.bundle` files within your React Native application, ensure each bundle has a unique name. This prevents actions from different bundles from interfering with each other.
1327
+
1328
+ #### Navigation
1329
+
1330
+ This feature is for the New RUM on Grail experience only and is described in the [Automatic Navigation tracking](#automatic-navigation-tracking) section.
1331
+
1332
+ ```js
1333
+ react: {
1334
+ navigation: {
1335
+ enabled: true
1336
+ }
1337
+ }
1338
+ ```
1339
+
1340
+ #### Source Map
1341
+
1342
+ This feature is enabled by default and patches sourcemap files so that any modifications made through Dynatrace will result in correct line numbers. If this feature is not enabled, line numbers of symbolicated stacktraces in Dynatrace might not match with your original source.
1343
+
1344
+ The following is an example of how this feature can be configured in your `dynatrace.config.js` file:
1136
1345
 
1137
1346
  ```js
1138
1347
  react: {
1139
- bundleName: "MyCustomBundle"
1348
+ sourceMap: {
1349
+ enabled: true
1350
+ }
1351
+ }
1352
+ ```
1353
+
1354
+ > **Note:** This automatic patching only works for Android. For iOS, you need to manually call [lineOffsetDynatrace](#npx-lineoffsetdynatrace) after the creation of the sourcemap is finished or before uploading it to Dynatrace.
1355
+
1356
+ The automatic patching for Android can be customized using the `androidSourcemapLocation` property to specify a custom path to your sourcemap file, resolving from the `android/` directory since that is where the automation gets executed:
1357
+
1358
+ ```js
1359
+ react: {
1360
+ sourceMap: {
1361
+ enabled: true,
1362
+ androidSourcemapLocation: 'sourcemap.map'
1363
+ }
1140
1364
  }
1141
1365
  ```
1142
1366
 
@@ -1333,6 +1557,9 @@ ios: {
1333
1557
  We check for a property named `dtActionName` when creating an action. If `dtActionName` exists, this will be used for the action name above every other option listed in the previous section. Example:
1334
1558
 
1335
1559
  ```js
1560
+ import { TouchableHighlight } from '@dynatrace/react-native-plugin';
1561
+ import { Text } from 'react-native';
1562
+
1336
1563
  <TouchableHighlight dtActionName="CustomActionName">
1337
1564
  <Text>Custom Action Name</Text>
1338
1565
  </TouchableHighlight>
@@ -1448,10 +1675,10 @@ This can be done via a configuration value in the `dynatrace.config.js`. The fol
1448
1675
  module.exports = {
1449
1676
  react : {
1450
1677
  upstreamTransformer: require.resolve('react-native-svg-transformer/react-native'),
1451
- ...
1678
+ // ...
1452
1679
  },
1453
- ...
1454
- }
1680
+ // ...
1681
+ };
1455
1682
  ```
1456
1683
 
1457
1684
  #### metro.config.js for React Native v0.72.1 or newer
@@ -1474,7 +1701,7 @@ const config = {
1474
1701
  },
1475
1702
  reporter: require('@dynatrace/react-native-plugin/lib/dynatrace-reporter'),
1476
1703
  resolver: {
1477
- assetExts: assetExts.filter(ext => ext !== 'svg'),
1704
+ assetExts: assetExts.filter((ext) => ext !== 'svg'),
1478
1705
  sourceExts: [...sourceExts, 'cjs', 'svg'],
1479
1706
  },
1480
1707
  };
@@ -1611,7 +1838,7 @@ If you encounter compatibility issues or want to disable Jetpack Compose instrum
1611
1838
 
1612
1839
  ```js
1613
1840
  module.exports = {
1614
- ...
1841
+ // ...
1615
1842
  android: {
1616
1843
  config: `
1617
1844
  dynatrace {
@@ -1623,8 +1850,9 @@ module.exports = {
1623
1850
  }
1624
1851
  }
1625
1852
  }
1626
- `
1627
- },
1853
+ `,
1854
+ }
1855
+ };
1628
1856
  ```
1629
1857
 
1630
1858
  For more information about Jetpack Compose instrumentation and monitoring capabilities, please refer to the [official Dynatrace documentation for Android OneAgent](https://docs.dynatrace.com/docs/observe/digital-experience/mobile-applications/instrument-android-app/instrumentation-via-plugin/monitoring-capabilities#compose-enable).
@@ -1722,21 +1950,44 @@ In case you are using NativeWind, use 'nativewind' as the importSource for the J
1722
1950
  >**Attention:** If you think something is not working the way it should, ALWAYS try to reset the cache of metro first before starting a support case. You can do this via the CLI *react-native start --reset-cache*. If it still does not work feel free to open a support case.
1723
1951
 
1724
1952
  If you are struggling with a problem, submit a support ticket to Dynatrace (support.dynatrace.com) and provide the following details:
1725
- * Logs from the [native agent](#native-oneagent-debug-logs)
1726
- * Logs from `node_modules/@dynatrace/react-native-plugin/logs`
1727
- * Your dynatrace.config.js file
1953
+
1954
+ ### Files to gather:
1955
+
1956
+ 1. **Native agent logs** - Enable [native agent debug logs](#native-oneagent-debug-logs) and collect logs from:
1957
+ * **iOS**: Xcode console output
1958
+ * **Android**: Android Studio Logcat
1959
+
1960
+ 2. **Metro logs** - Enable [React debug mode](#debug-mode) in your `dynatrace.config.js` and collect Metro bundler logs:
1961
+ * Build logs showing instrumentation output
1962
+ * Runtime logs from Metro terminal/console
1963
+ * These logs show React Native side instrumentation and runtime behavior
1964
+
1965
+ 3. **Plugin logs** - Located in `node_modules/@dynatrace/react-native-plugin/logs`
1966
+
1967
+ 4. **Configuration** - Your `dynatrace.config.js` file
1968
+
1969
+ >**Tip:** Enable both native agent debug logs and React debug mode before reproducing the issue to capture comprehensive diagnostics from both native (iOS/Android) and JavaScript (React Native) layers.
1970
+
1728
1971
  <br/><br/>
1729
1972
  ## Changelog
1730
1973
 
1974
+ 2.329.1
1975
+ * Updated Android (8.329.1.1014) & iOS Agent (8.329.1.1017)
1976
+ * [New RUM experience](#new-rum-experience) Removed Dynatrace.stopView() API
1977
+ * [New RUM experience](#new-rum-experience) Enforcing length limitation of 5000 characters for user input values
1978
+ * [New RUM experience](#new-rum-experience) React Native Deobfuscation service via sourcemaps
1979
+ * Adding [`npx lineOffsetDynatrace`](#npx-lineoffsetdynatrace) command
1980
+ * [New RUM experience](#new-rum-experience) Added automated view tracking via [navigation](#automatic-navigation-tracking)
1981
+ * [New RUM experience](#new-rum-experience) Event and session properties are now sorted alphabetically when the limit of 50 is exceeded, ensuring deterministic property dropping
1982
+
1731
1983
  2.327.2
1732
1984
  * Fixed iOS startup time calculation issues for React Native 0.72 and lower
1733
1985
  * Fixed static properties during auto instrumentation of Touchables
1734
1986
  * Updated Android (8.327.3.1006) & iOS Agent (8.327.2.1022)
1735
1987
 
1736
-
1737
1988
  2.327.1
1738
1989
  * Added [Compose Compatibility Note](#compose-compatibility-note)
1739
- * Added [New RUM experience preview](#new-rum-experience-preview) documentation
1990
+ * Added [New RUM experience preview](#new-rum-experience) documentation
1740
1991
  * Fixed iOS crash reporting by delaying the crash by 200ms on iOS to give the Agent enough time to report it
1741
1992
  * Updated Android (8.327.2.1004) & iOS Agent (8.327.1.1020)
1742
1993
 
@@ -1745,8 +1996,8 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
1745
1996
 
1746
1997
  2.325.1
1747
1998
  * Updated Android (8.325.1.1007) & iOS Agent (8.325.1.1012)
1748
- * [New RUM experience preview](#new-rum-experience-preview) ReactNative version now added to RUM on Grail event base data
1749
- * [New RUM experience preview](#new-rum-experience-preview) Added API documentation for RUM on Grail API
1999
+ * [New RUM experience preview](#new-rum-experience) ReactNative version now added to RUM on Grail event base data
2000
+ * [New RUM experience preview](#new-rum-experience) Added API documentation for RUM on Grail API
1750
2001
 
1751
2002
  2.323.2
1752
2003
  * Fixed error "Execution failed for task ':app:mergeReleaseAssets'. A problem occured starting process 'command 'npx''" when building for release on Windows.