@dynatrace/react-native-plugin 2.325.2 → 2.327.2
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 +259 -10
- package/android/build.gradle +1 -1
- package/files/plugin.gradle +1 -1
- package/instrumentation/DynatraceInstrumentation.js +1 -1
- package/instrumentation/libs/react-native/Touchables.js +9 -0
- package/ios/DynatraceRNBridge.mm +99 -8
- package/lib/core/ErrorHandler.js +3 -1
- package/lib/next/appstart/AppStartObserver.js +11 -14
- package/lib/next/events/HttpRequestEventBuilder.js +7 -7
- package/package.json +1 -1
- package/react-native-dynatrace.podspec +1 -1
- package/types.d.ts +74 -69
package/README.md
CHANGED
|
@@ -26,15 +26,16 @@ If you want to start using this plugin and are not a Dynatrace customer yet, hea
|
|
|
26
26
|
* Gradle version 7.0+ ([How to update?](#updating-to-gradle-7))
|
|
27
27
|
* Android Gradle plugin version 7.0+
|
|
28
28
|
* Java 11
|
|
29
|
-
* Kotlin 2.0.21
|
|
29
|
+
* Kotlin 2.0.21 - see [Kotlin Compatibility Note](#kotlin-compatibility-note)
|
|
30
|
+
* Jetpack Compose 1.4 - 1.9 - see [Compose Compatibility Note](#compose-compatibility-note)
|
|
30
31
|
* For iOS users: Minimum iOS 12
|
|
31
32
|
* NodeJS 16.0.0+ since our dependencies require NodeJS 16.0.0
|
|
32
33
|
|
|
33
34
|
## Agent Versions
|
|
34
35
|
This agent versions are configured in this plugin:
|
|
35
36
|
|
|
36
|
-
* Android Agent: 8.
|
|
37
|
-
* iOS Agent: 8.
|
|
37
|
+
* Android Agent: 8.327.3.1006
|
|
38
|
+
* iOS Agent: 8.327.2.1022
|
|
38
39
|
|
|
39
40
|
## Quick Setup
|
|
40
41
|
|
|
@@ -63,6 +64,13 @@ This agent versions are configured in this plugin:
|
|
|
63
64
|
* [Platform independent reporting](#platform-independent-reporting)
|
|
64
65
|
* [Set beacon headers](#setting-beacon-headers)
|
|
65
66
|
* [Exclude Individual JSX Elements](#exclude-individual-jsx-elements)
|
|
67
|
+
* [New RUM experience preview](#new-rum-experience-preview)
|
|
68
|
+
* [Send Event](#send-event)
|
|
69
|
+
* [Send Session Property Event](#send-session-property-event)
|
|
70
|
+
* [Event Modifier](#event-modifier)
|
|
71
|
+
* [Send Exception Event](#send-exception-event)
|
|
72
|
+
* [Send HTTP Request Event](#send-http-request-event)
|
|
73
|
+
* [View Monitoring](#view-monitoring)
|
|
66
74
|
* [NPX Commands](#npx-commands)
|
|
67
75
|
* [npx instrumentDynatrace](#npx-instrumentdynatrace)
|
|
68
76
|
* [npx configDynatrace](#npx-configdynatrace)
|
|
@@ -81,7 +89,8 @@ This agent versions are configured in this plugin:
|
|
|
81
89
|
* [React Automatic Runtime](#react-automatic-runtime)
|
|
82
90
|
* [Using a second transformer besides the dynatrace transformer](#using-a-second-transformer-besides-the-dynatrace-transformer)
|
|
83
91
|
* [Upgrading project to Gradle 7](#updating-to-gradle-7)
|
|
84
|
-
* [Kotlin Compatibility Note](
|
|
92
|
+
* [Kotlin Compatibility Note](#kotlin-compatibility-note)
|
|
93
|
+
* [Compose Compatibility Note](#compose-compatibility-note)
|
|
85
94
|
* [Maven Central in top-level gradle file](#maven-central-in-top-level-gradle-file)
|
|
86
95
|
* [Configuration of standalone React Native project](#configuration-of-standalone-react-native-project)
|
|
87
96
|
* [Instrumentation Overhead](#instrumentation-overhead)
|
|
@@ -328,6 +337,8 @@ Combining manual and auto instrumentation should not be a problem. As they're ru
|
|
|
328
337
|
|
|
329
338
|
There are two options to create an action. Either using `enterAutoAction` (the previous `enterAction`) or `enterManualAction`:
|
|
330
339
|
|
|
340
|
+
**Important:** Action names are limited to 250 characters and will be truncated if they exceed this limit.
|
|
341
|
+
|
|
331
342
|
* `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.
|
|
332
343
|
|
|
333
344
|
```ts
|
|
@@ -363,6 +374,8 @@ myAction.leaveAction();
|
|
|
363
374
|
|
|
364
375
|
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.
|
|
365
376
|
|
|
377
|
+
**Important:** Action names are limited to 250 characters and will be truncated if they exceed this limit.
|
|
378
|
+
|
|
366
379
|
```ts
|
|
367
380
|
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
368
381
|
|
|
@@ -460,6 +473,8 @@ reportIntValue(valueName: string, value: number, platform?: Platform): void
|
|
|
460
473
|
reportStringValue(valueName: string, value: string, platform?: Platform): void
|
|
461
474
|
```
|
|
462
475
|
|
|
476
|
+
**Important:** All string parameters (errorName, eventName, valueName, value) are limited to 250 characters and will be truncated if they exceed this limit.
|
|
477
|
+
|
|
463
478
|
To report a string value, use the following:
|
|
464
479
|
|
|
465
480
|
```ts
|
|
@@ -490,6 +505,8 @@ The previous API without *errorValue* is deprecated and will be removed in the f
|
|
|
490
505
|
|
|
491
506
|
You can identify a user and tag the current session with a name by making the following call:
|
|
492
507
|
|
|
508
|
+
**Important:** The user identifier is limited to 250 characters and will be truncated if it exceeds this limit.
|
|
509
|
+
|
|
493
510
|
```ts
|
|
494
511
|
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
495
512
|
|
|
@@ -685,6 +702,192 @@ export default TouchableHighlightScreen;
|
|
|
685
702
|
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.
|
|
686
703
|
|
|
687
704
|
>*Attention:* If you are using Typescript and want to set this property with type-safety, look [here](#typescript-setup-for-dtactionignore-and-dtactionname).
|
|
705
|
+
|
|
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.
|
|
709
|
+
|
|
710
|
+
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
|
+
|
|
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).
|
|
713
|
+
|
|
714
|
+
### Send Event
|
|
715
|
+
|
|
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.
|
|
717
|
+
|
|
718
|
+
```ts
|
|
719
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
720
|
+
|
|
721
|
+
// 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
|
+
});
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
**Property Requirements:**
|
|
731
|
+
* Only properties prefixed with `event_properties.*` are allowed
|
|
732
|
+
* Additionally, the `duration` property is allowed
|
|
733
|
+
* Maximum of 50 custom properties per event
|
|
734
|
+
* String properties are limited to 5000 characters (exceeding characters are truncated)
|
|
735
|
+
* Field names must contain only alphabetic characters, numbers, underscores, and dots
|
|
736
|
+
* Each dot must be followed by an alphabetic character
|
|
737
|
+
* Each underscore must be followed by an alphabetic character or number
|
|
738
|
+
* Values must be primitive types (string, number, boolean)
|
|
739
|
+
* Cannot contain functions, undefined, Infinity, or NaN as values (they will be replaced with null)
|
|
740
|
+
|
|
741
|
+
### Send Session Property Event
|
|
742
|
+
|
|
743
|
+
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
|
+
|
|
745
|
+
```ts
|
|
746
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
747
|
+
|
|
748
|
+
// 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
|
+
});
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
**Important Notes:**
|
|
757
|
+
* Session properties persist throughout the entire session
|
|
758
|
+
* If you send the same property multiple times, only one value will be kept (first or last)
|
|
759
|
+
* Use session properties for data that applies to the entire user session
|
|
760
|
+
* Field naming follows the same rules as events, but with `session_properties.` prefix
|
|
761
|
+
* Additionally, the `duration` property is allowed
|
|
762
|
+
* Maximum of 50 custom properties per event
|
|
763
|
+
|
|
764
|
+
### Event Modifier
|
|
765
|
+
|
|
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.
|
|
767
|
+
|
|
768
|
+
```ts
|
|
769
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
770
|
+
|
|
771
|
+
// Create an event modifier
|
|
772
|
+
const myModifier = {
|
|
773
|
+
modifyEvent(event) {
|
|
774
|
+
// Add common properties to all events
|
|
775
|
+
event["event_properties.app_build"] = "1.2.3";
|
|
776
|
+
event["event_properties.environment"] = "production";
|
|
777
|
+
|
|
778
|
+
// Return null to discard the event entirely
|
|
779
|
+
if (event["event_properties.ignore"] === true) {
|
|
780
|
+
return null;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
return event;
|
|
784
|
+
}
|
|
785
|
+
};
|
|
786
|
+
|
|
787
|
+
// Add the modifier
|
|
788
|
+
Dynatrace.addEventModifier(myModifier);
|
|
789
|
+
|
|
790
|
+
// Remove the modifier when no longer needed
|
|
791
|
+
Dynatrace.removeEventModifier(myModifier);
|
|
792
|
+
```
|
|
793
|
+
|
|
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
|
|
799
|
+
|
|
800
|
+
### Send Exception Event
|
|
801
|
+
|
|
802
|
+
The `sendExceptionEvent()` method provides a structured way to report exceptions with additional context and custom properties.
|
|
803
|
+
|
|
804
|
+
```ts
|
|
805
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
806
|
+
|
|
807
|
+
try {
|
|
808
|
+
// Code that might throw an error
|
|
809
|
+
await riskyOperation();
|
|
810
|
+
} 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
|
+
});
|
|
816
|
+
}
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
**Parameters:**
|
|
820
|
+
* `error`: The Error object containing exception information (required)
|
|
821
|
+
* `fields`: Optional custom properties following the same naming rules as [sendEvent()](#send-event)
|
|
822
|
+
|
|
823
|
+
### Send HTTP Request Event
|
|
824
|
+
|
|
825
|
+
The `sendHttpRequestEvent()` method allows you to manually report HTTP request events with detailed information about the request and response.
|
|
826
|
+
|
|
827
|
+
```ts
|
|
828
|
+
import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
|
|
829
|
+
|
|
830
|
+
// Basic HTTP request event
|
|
831
|
+
const requestBuilder = new HttpRequestEventBuilder('https://api.example.com/users', 'GET');
|
|
832
|
+
Dynatrace.sendHttpRequestEvent(requestBuilder);
|
|
833
|
+
|
|
834
|
+
// 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);
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
### View Monitoring
|
|
842
|
+
|
|
843
|
+
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
|
+
|
|
845
|
+
#### Start View
|
|
846
|
+
|
|
847
|
+
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.
|
|
848
|
+
|
|
849
|
+
```ts
|
|
850
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
851
|
+
|
|
852
|
+
// Start monitoring a view
|
|
853
|
+
Dynatrace.startView("HomeScreen");
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
**Important Considerations:**
|
|
857
|
+
* Only one view can be active at a time
|
|
858
|
+
* Starting a new view will automatically stop the previous one
|
|
859
|
+
* View names should be meaningful and consistent across your application
|
|
860
|
+
* All events captured after starting a view will include the view context
|
|
861
|
+
|
|
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
|
+
**Complete Example:**
|
|
874
|
+
|
|
875
|
+
```ts
|
|
876
|
+
import { Dynatrace } from '@dynatrace/react-native-plugin';
|
|
877
|
+
|
|
878
|
+
// User navigates to profile screen
|
|
879
|
+
Dynatrace.startView("UserProfile");
|
|
880
|
+
|
|
881
|
+
// Send custom event within the view
|
|
882
|
+
Dynatrace.sendEvent({
|
|
883
|
+
"event_properties.profile_action": "edit_profile",
|
|
884
|
+
"event_properties.changes_made": true
|
|
885
|
+
});
|
|
886
|
+
|
|
887
|
+
// User navigates away
|
|
888
|
+
Dynatrace.stopView();
|
|
889
|
+
```
|
|
890
|
+
|
|
688
891
|
## NPX Commands
|
|
689
892
|
|
|
690
893
|
The following npx commands are available for the plugin:
|
|
@@ -757,7 +960,7 @@ pod 'react-native-dynatrace', :path => '../node_modules/@dynatrace/react-native-
|
|
|
757
960
|
5. Under Build Phases expand the Link Binary With Libraries header.
|
|
758
961
|
6. Scroll down and click + to add a library.
|
|
759
962
|
7. Find and add `libRNDynatrace.a` under the Workspace group.
|
|
760
|
-
8.
|
|
963
|
+
8. â+B
|
|
761
964
|
|
|
762
965
|
## Setup for tvOS
|
|
763
966
|
|
|
@@ -1380,9 +1583,9 @@ dependencies {
|
|
|
1380
1583
|
|
|
1381
1584
|
```
|
|
1382
1585
|
|
|
1383
|
-
##
|
|
1586
|
+
## Kotlin Compatibility Note
|
|
1384
1587
|
|
|
1385
|
-
Our Android Agent currently
|
|
1588
|
+
Our Android Agent currently requires **Kotlin 2.0.21**. However, it should be noted that using this version may cause compatibility issues with older versions of React Native and the corresponding `react-native-gradle-plugin` due to, for instance, differences in Kotlin metadata:
|
|
1386
1589
|
|
|
1387
1590
|
Kotlin embeds language-specific features that Java doesn't natively support (like nullability and extension functions) into bytecode using `@Metadata` annotations. These annotations include a `metadataVersion`.
|
|
1388
1591
|
|
|
@@ -1392,6 +1595,40 @@ Kotlin embeds language-specific features that Java doesn't natively support (lik
|
|
|
1392
1595
|
|
|
1393
1596
|
In summary, ensure your build fulfills our Kotlin 2.0.21 requirement while simultaneously fulfilling the requirements of your React Native version and its `react-native-gradle-plugin`.
|
|
1394
1597
|
|
|
1598
|
+
## Compose Compatibility Note
|
|
1599
|
+
|
|
1600
|
+
Our Android Agent currently supports **Jetpack Compose 1.4 - 1.9**. If you are using an incompatible version of Jetpack Compose, you may encounter the following error message during build:
|
|
1601
|
+
|
|
1602
|
+
```
|
|
1603
|
+
Could not resolve all dependencies for configuration ':app:debugCompileClasspath'.
|
|
1604
|
+
Version '1.0.0' of artifact 'androidx.compose.material:material' is not supported.
|
|
1605
|
+
Please use the latest version of the Dynatrace Android Gradle plugin.
|
|
1606
|
+
```
|
|
1607
|
+
|
|
1608
|
+
If you encounter compatibility issues or want to disable Jetpack Compose instrumentation, you can configure this in your `dynatrace.config.js` file. **Note: Disabling Jetpack Compose instrumentation will skip the compatibility check, allowing you to build with any version of Jetpack Compose without triggering version validation errors.**
|
|
1609
|
+
|
|
1610
|
+
**Important**: The configuration example below shows **only the Compose-specific setting**. You must ensure that your complete `dynatrace.config.js` file includes all other required configuration settings (such as `beaconUrl`, `applicationId`, etc.) as described in the [Android block](#android-block) section of this documentation.
|
|
1611
|
+
|
|
1612
|
+
```js
|
|
1613
|
+
module.exports = {
|
|
1614
|
+
...
|
|
1615
|
+
android: {
|
|
1616
|
+
config: `
|
|
1617
|
+
dynatrace {
|
|
1618
|
+
configurations {
|
|
1619
|
+
defaultConfig {
|
|
1620
|
+
userActions {
|
|
1621
|
+
composeEnabled false
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
`
|
|
1627
|
+
},
|
|
1628
|
+
```
|
|
1629
|
+
|
|
1630
|
+
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).
|
|
1631
|
+
|
|
1395
1632
|
## Configuration of standalone React Native project
|
|
1396
1633
|
|
|
1397
1634
|
This section explains the configuration of a standalone React Native project. This means you have a React Native project, but don't use the typical `iOS` and `android` folders. Instead you have a separate native `iOS` or `android` project which is embedding your React Native project.
|
|
@@ -1491,13 +1728,25 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
|
|
|
1491
1728
|
<br/><br/>
|
|
1492
1729
|
## Changelog
|
|
1493
1730
|
|
|
1731
|
+
2.327.2
|
|
1732
|
+
* Fixed iOS startup time calculation issues for React Native 0.72 and lower
|
|
1733
|
+
* Fixed static properties during auto instrumentation of Touchables
|
|
1734
|
+
* Updated Android (8.327.3.1006) & iOS Agent (8.327.2.1022)
|
|
1735
|
+
|
|
1736
|
+
|
|
1737
|
+
2.327.1
|
|
1738
|
+
* Added [Compose Compatibility Note](#compose-compatibility-note)
|
|
1739
|
+
* Added [New RUM experience preview](#new-rum-experience-preview) documentation
|
|
1740
|
+
* Fixed iOS crash reporting by delaying the crash by 200ms on iOS to give the Agent enough time to report it
|
|
1741
|
+
* Updated Android (8.327.2.1004) & iOS Agent (8.327.1.1020)
|
|
1742
|
+
|
|
1494
1743
|
2.325.2
|
|
1495
1744
|
* Fixed incombatability with Metro 0.83.2 and newer
|
|
1496
1745
|
|
|
1497
1746
|
2.325.1
|
|
1498
1747
|
* Updated Android (8.325.1.1007) & iOS Agent (8.325.1.1012)
|
|
1499
|
-
* [New RUM experience preview] ReactNative version now added to RUM on Grail event base data
|
|
1500
|
-
* [New RUM experience preview] Added API documentation for RUM on Grail API
|
|
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
|
|
1501
1750
|
|
|
1502
1751
|
2.323.2
|
|
1503
1752
|
* Fixed error "Execution failed for task ':app:mergeReleaseAssets'. A problem occured starting process 'command 'npx''" when building for release on Windows.
|
|
@@ -1801,4 +2050,4 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
|
|
|
1801
2050
|
* Added auto instrumentation for React classes
|
|
1802
2051
|
|
|
1803
2052
|
0.168.0
|
|
1804
|
-
* Initial Beta Release
|
|
2053
|
+
* Initial Beta Release
|
package/android/build.gradle
CHANGED
|
@@ -72,7 +72,7 @@ repositories {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
dependencies {
|
|
75
|
-
implementation 'com.dynatrace.agent:agent-android:8.
|
|
75
|
+
implementation 'com.dynatrace.agent:agent-android:8.327.3.1006'
|
|
76
76
|
implementation "com.facebook.react:react-native:${safeExtGet('reactNative', '+')}"
|
|
77
77
|
}
|
|
78
78
|
|
package/files/plugin.gradle
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var o,n=require("@babel/runtime/helpers/interopRequireDefault"),e=n(require("@babel/runtime/helpers/toConsumableArray")),c=(Object.defineProperty(exports,"t",{value:!0}),exports.instrument=void 0,require("path")),u=require("jscodeshift"),i=require("jscodeshift/src/Collection"),r=require("../scripts/FileOperationHelper"),l=require("../scripts/PathsConstants"),f=require("../lib/core/util/GetValuesFromPackage"),t=require("../scripts/util/InstrumentUtil"),a=require("./libs/react-native/Touchables.InstrInfo"),s=require("./libs/react-native/RefreshControl.InstrInfo"),v=require("./libs/react-native/Switch.InstrInfo"),d=require("./libs/community/gesture-handler/Touchables.InstrInfo"),p=require("./libs/community/Picker.InstrInfo"),m=require("./model/Types"),y=require("./parser/ParserUtil"),g=((n=>{n[n.i=-1]="Filtered",n[n.u=0]="Normal",n[n.o=1]="ReactNative",n[n.l=2]="React",n[n.v=3]="ReactNativeCssInterop"})(o=o||{}),[]),q=(g.push.apply(g,(0,e.default)(a.instrumentationInfo)),g.push.apply(g,(0,e.default)(s.instrumentationInfo)),g.push.apply(g,(0,e.default)(v.instrumentationInfo)),g.push.apply(g,(0,e.default)(d.instrumentationInfo)),g.push.apply(g,(0,e.default)(p.instrumentationInfo)),["AppRegistry","AppRegistryImpl","renderApplication","ExceptionsManager"]),b="@dynatrace/react-native-plugin/instrumentation/libs",instrument=function(n,e,r){e=T(e);var t=z(e);if(t!==o.i){var i=!1,u=I(e,n);if(t===o.l)k(u),i=!0;else if(t===o.o)e.endsWith("AppRegistryImpl.js")?null!=r&&r.autoStart&&U(u)&&(i=!0):e.endsWith("AppRegistry.js")?null!=r&&r.autoStart&&w(u)&&(i=!0):e.endsWith("renderApplication.js")?(A(u),i=!0):e.endsWith("ExceptionsManager.js")&&(a=void 0!==r&&r.autoStart&&r.errorHandler.enabled,J(u,r.errorHandler.reportFatalErrorAsCrash,a),i=!0);else if(t===o.v)i=G(u)||i;else{var a=V(e,r);if(r.custom.reactnavigation&&B(e,u))i=!0;else{if(!a.input&&!a.lifecycle)return null!=r&&r.debug&&console.log("Dynatrace - Filtered All: ".concat(e)),h(e),n;a.lifecycle&&A(u)&&(i=!0),a.input&&g.forEach(function(n){n=X(u,n);u=n.root,i=i||n.p})}}i?(n=u.toSource({quote:"single"}),N(n,e)):h(e),null!=r&&r.debug&&i&&console.log("Dynatrace - Modified Filename: "+e)}else e.includes(c.join("@dynatrace","react-native-plugin"))&&e.endsWith(c.join("lib","core","configuration","ConfigurationPreset.js"))&&void 0!==r&&(t=(0,f.getHostAppBundleInfo)(l.default.getPackageJsonFile()),a=I(e,n),void 0!==r.lifecycle&&j(a,"getLifecycleUpdate",r.lifecycle.includeUpdate),void 0!==r.debug&&j(a,"getLogLevel",r.debug?0:1),void 0!==r.bundleName?j(a,"getBundleName",r.bundleName):null!==t&&j(a,"getBundleName",null==t?void 0:t.name),void 0!==r.bundleVersion?j(a,"getBundleVersion",r.bundleVersion):null!==t&&j(a,"getBundleVersion",null==t?void 0:t.version),void 0!==r.input&&void 0!==r.input.actionNamePrivacy&&j(a,"getActionNamePrivacy",r.input.actionNamePrivacy),void 0!==r.errorHandler&&(j(a,"isErrorHandlerEnabled",r.errorHandler.enabled),j(a,"isReportFatalErrorAsCrash",r.errorHandler.reportFatalErrorAsCrash)),r.autoStart&&j(a,"isAutoStartupEnabled",r.autoStart),n=a.toSource({quote:"single"}),N(n,e));return n},B=(exports.instrument=instrument,function(n,e){return!!M(n,e)&&(n="import { registerListener } from '".concat(b,"/react-navigation/ReactNavigation';"),e.find(u.ImportDeclaration).at(0).insertBefore(n),!0)}),M=function(n,e){var r=!1;return n.includes("react-navigation")&&n.includes("NavigationContainer.tsx")&&e.find(u.VariableDeclarator).forEach(function(n){r||null==n.value||null==n.value.id||"refContainer"!==n.value.id.name||null!=n.parent&&null!=n.parent.value&&null!=n.parent.value.type&&"VariableDeclaration"===n.parent.value.type&&(n.parent.insertAfter("registerListener(refContainer);"),r=!0)}),r},A=function(n){var e=n.findJSXElements(),t=!1;return 0<e.length&&(n.find(u.FunctionDeclaration).forEach(function(n){var e,r=(0,i.fromPaths)([n]);0<r.findJSXElements().length&&null!=n&&null!=n.value&&null!=n.value.id&&n.value.id.name.toString()&&(e=r.find(u.ClassDeclaration),r=r.find(u.ClassExpression),0===e.length)&&0===r.length&&(x(n,m.Types.FunctionalComponent,n.value.id.name.toString()),t=!0)}),n.find(u.ClassDeclaration).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n&&null!=n.value&&n.value.id&&n.value.id.name.toString()&&(x(n,m.Types.ClassComponent,n.value.id.name.toString()),t=!0)}),n.find(u.ArrowFunctionExpression).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n.parent&&null!=n.parent.value&&null!=n.parent.value.id&&null!=n.parent.value.id.name&&(x(n,m.Types.FunctionalComponent,n.parent.value.id.name),t=!0)})),t},x=function(n,e,r){for(e=u.expressionStatement(u.assignmentExpression("=",u.memberExpression(u.identifier(r),u.identifier("_dtInfo")),O(e,r)));"body"!==(null==n?void 0:n.parentPath.name);)n=n.parentPath;void 0!==n.parentPath&&n.insertAfter(e)},O=function(n,e){return u.objectExpression([u.objectProperty(u.identifier("type"),u.numericLiteral(n)),u.objectProperty(u.identifier("name"),u.stringLiteral(e))])},j=function(n,e,r){var n=n.find(u.Identifier).filter(function(n){return n.node.name===e});1===n.length&&"ReturnStatement"===(n=n.paths()[0].parent.value.body.body[0]).type&&("boolean"==typeof r&&(n.argument=u.booleanLiteral(r)),"string"==typeof r&&(n.argument=u.stringLiteral(r)),"number"==typeof r)&&(n.argument=u.numericLiteral(r))},I=function(n,e){return u.withParser((0,y.chooseParser)(n,e))(e)},T=function(n){return c.isAbsolute(n)?n.replace(l.default.getApplicationPath()+c.sep,""):n},h=function(n){try{var e=c.join(l.default.getBuildPath(),n+t.INSTRUMENTED_FILE_EXTENSION);r.default.checkIfFileExistsSync(e),r.default.deleteFileSync(e)}catch(n){}},N=function(n,e){e=c.join(l.default.getBuildPath(),e);try{r.default.checkIfFileExistsSync(c.dirname(e))}catch(n){r.default.createDirectorySync(c.dirname(e))}r.default.writeTextToFileSync(e+t.INSTRUMENTED_FILE_EXTENSION,n)},V=function(n,e){var r={input:!1,lifecycle:!1};return void 0!==e&&(void 0!==e.lifecycle&&void 0!==e.lifecycle.instrument&&e.lifecycle.instrument(n)&&(r.lifecycle=!0),void 0!==e.input)&&void 0!==e.input.instrument&&e.input.instrument(n)&&(r.input=!0),r},k=function(n){var e,n=n.find(u.Program);1===n.length&&(e=u.expressionStatement(u.callExpression(u.memberExpression(u.callExpression(u.identifier("require"),[u.stringLiteral("@dynatrace/react-native-plugin/instrumentation/jsx/ElementHelper")]),u.identifier("instrumentCreateElement")),[u.memberExpression(u.identifier("module"),u.identifier("exports"))])),n.paths()[0].node.body.push(e))},U=function(n){var e=n.find(u.FunctionDeclaration,{id:{name:"runApplication"}});return 1===e.length&&(_(n,{m:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),R(e.get().value.body.body,0,F("_DynatraceApplicationHandler","startup",[])),!0)},w=function(n){var e=n.find(u.ObjectMethod,{key:{name:"runApplication"}});return 1===e.length&&(_(n,{m:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),R(e.get().value.body.body,0,F("_DynatraceApplicationHandler","startup",[])),!0)},J=function(n,r,t){var i=u;n.find(i.FunctionDeclaration,{id:{name:"handleException"}}).forEach(function(n){var e=i.expressionStatement(i.callExpression(i.memberExpression(i.callExpression(i.identifier("require"),[i.literal("@dynatrace/react-native-plugin/lib/core/ErrorHandler")]),i.identifier("reportErrorToDynatrace")),[i.identifier("e"),i.identifier("isFatal"),i.literal(r),i.literal(t)]));n.node.body.body.unshift(e)})},G=function(n){var e=!1,n=n.find(u.CallExpression,{callee:{name:"require"}});return n.find(u.Literal,{value:"react/jsx-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-runtime",e=!0,n}),n.find(u.Literal,{value:"react/jsx-dev-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-dev-runtime",e=!0,n}),e},R=function(n,e){for(var r=arguments.length,t=new Array(2<r?r-2:0),i=2;i<r;i++)t[i-2]=arguments[i];return n.splice.apply(n,[e,0].concat(t))},z=function(n){if(n.includes("@dynatrace"))return o.i;var e=c.extname(n);if(".js"!==e&&".ts"!==e&&".tsx"!==e&&".jsx"!==e)return o.i;for(var r=c.parse(n),t=r.dir.split(c.sep),i=0;i<t.length;i++)if("node_modules"===t[i]){if("react-native"===t[i+1]||"create-react-class"===t[i+1]||"react-clone-referenced-element"===t[i+1])return q.includes(r.name)?o.o:o.i;if("react"===t[i+1]&&"index"===r.name)return o.l;if("react-native-css-interop"===t[i+1]&&("jsx-runtime"===r.name||"jsx-dev-runtime"===r.name))return o.v}return o.u},K=function(n,e,r){var t=Q(n,e,r);return W(n,e,r)||t},Q=function(n,e,r){var t=Y(n,e);return 0<t.length&&(void 0!==(t=H(t,e.reference,!1))&&(r.m=t.localName),tn(n,r),!0)},W=function(n,e,r){var t=E(n,e.module);if(1===t.length){t=H(t,e.reference,!0);if(void 0!==t)return un(n,r.defaultImport,t.localName,"ImportNamespaceSpecifier"===t.type),!0}return!1},X=function(n,e){var r=JSON.parse(JSON.stringify(e.new));return{root:n,p:K(n,e.old,r)||Z(n,e.old,e.new.defaultImport)}},Y=function(n,e){return n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e.module&&null!=n.node.specifiers&&n.node.specifiers.some(function(n){return C(n)&&n.imported.name===e.reference||n.local&&n.local.name===e.reference})})},C=function(n){return void 0!==n.imported},Z=function(n,e,r){var t=!1;return n.find(u.CallExpression).filter(function(n){return $(n.node.callee)&&nn(n.node.arguments[0])&&n.node.arguments[0].value===e.module&&void 0!==n.parent}).forEach(function(n){(void 0===n.parent.value.property||void 0!==n.parent.value.property&&void 0!==n.parent.value.property.name&&n.parent.value.property.name===e.reference)&&(n.node.arguments[0].value=r,t=t||!0)}),t},$=function(n){return"require"===n.name},nn=function(n){return"StringLiteral"===n.type||"Literal"===n.type},E=function(n,e){return n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e})},H=function(n,r,t){var i;return n.forEach(function(n){void 0!==n.node.specifiers&&(n.node.specifiers=n.node.specifiers.filter(function(n){var e;return C(n)&&!t?((e=n.imported.name!==r)||null==n.local||n.imported.name===n.local.name||(i={localName:n.local.name.toString(),type:n.type}),e):!(!C(n)&&t&&(null!=n.local&&(i={localName:n.local.name.toString(),type:n.type}),1))}),0===n.node.specifiers.length)&&n.prune()}),i},en=function(n,e){n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e.module}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(P(e))})},rn=function(n,e,r){n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(r)})},D=function(n,e,r){var t=n.find(u.ImportDeclaration);0<t.length?u(t.paths()[0]).insertAfter(S(e,r)):1===(t=n.find(u.Program)).length&&t.paths()[0].node.body.unshift(S(e,r))},tn=function(n,e){0<E(n,e.module).length?en(n,e):D(n,e.module,[P(e)])},un=function(n,e,r,t){var i=E(n,e),t=(t?vn:sn)(r);0<i.length?rn(n,e,t):D(n,e,[t])},_=function(n,e){n=n.find(u.VariableDeclaration);0<n.length&&u(n.paths()[0]).insertAfter(on(e))},F=function(n,e,r){return u.expressionStatement(an(n,e,r))},an=function(n,e,r){return u.callExpression(fn(n,e),r)},on=function(n){return u.variableDeclaration("var",[cn(n)])},cn=function(n){return u.variableDeclarator(void 0!==n.m?u.identifier(n.m):u.identifier(n.reference),(0<n.reference.length?ln:L)(n))},ln=function(n){return u.memberExpression(L(n),u.identifier(n.reference))},fn=function(n,e){return u.memberExpression(u.identifier(n),u.identifier(e))},L=function(n){return u.callExpression(u.identifier("require"),[u.literal(n.module)])},S=function(n,e){return u.importDeclaration(e,u.literal(n))},P=function(n){return void 0!==n.m?u.importSpecifier(u.identifier(n.reference),u.identifier(n.m)):u.importSpecifier(u.identifier(n.reference))},sn=function(n){return u.importDefaultSpecifier(u.identifier(n))},vn=function(n){return u.importNamespaceSpecifier(u.identifier(n))};
|
|
1
|
+
var o,n=require("@babel/runtime/helpers/interopRequireDefault"),e=n(require("@babel/runtime/helpers/toConsumableArray")),c=(Object.defineProperty(exports,"t",{value:!0}),exports.instrument=void 0,require("path")),u=require("jscodeshift"),i=require("jscodeshift/src/Collection"),r=require("../scripts/FileOperationHelper"),l=require("../scripts/PathsConstants"),f=require("../lib/core/util/GetValuesFromPackage"),t=require("../scripts/util/InstrumentUtil"),a=require("./libs/react-native/Touchables.InstrInfo"),s=require("./libs/react-native/RefreshControl.InstrInfo"),v=require("./libs/react-native/Switch.InstrInfo"),d=require("./libs/community/gesture-handler/Touchables.InstrInfo"),p=require("./libs/community/Picker.InstrInfo"),m=require("./model/Types"),y=require("./parser/ParserUtil"),g=((n=>{n[n.i=-1]="Filtered",n[n.u=0]="Normal",n[n.o=1]="ReactNative",n[n.l=2]="React",n[n.v=3]="ReactNativeCssInterop"})(o=o||{}),[]),q=(g.push.apply(g,(0,e.default)(a.instrumentationInfo)),g.push.apply(g,(0,e.default)(s.instrumentationInfo)),g.push.apply(g,(0,e.default)(v.instrumentationInfo)),g.push.apply(g,(0,e.default)(d.instrumentationInfo)),g.push.apply(g,(0,e.default)(p.instrumentationInfo)),["AppRegistry","AppRegistryImpl","renderApplication","ExceptionsManager"]),b="@dynatrace/react-native-plugin/instrumentation/libs",instrument=function(n,e,r){e=O(e);var t=z(e);if(t!==o.i){var i=!1,u=I(e,n);if(t===o.l)k(u),i=!0;else if(t===o.o)e.endsWith("AppRegistryImpl.js")?null!=r&&r.autoStart&&U(u)&&(i=!0):e.endsWith("AppRegistry.js")?null!=r&&r.autoStart&&w(u)&&(i=!0):e.endsWith("renderApplication.js")?(A(u),i=!0):e.endsWith("ExceptionsManager.js")&&(a=void 0!==r&&r.autoStart&&r.errorHandler.enabled,J(u,r.errorHandler.reportFatalErrorAsCrash,a),i=!0);else if(t===o.v)i=G(u)||i;else{var a=V(e,r);if(r.custom.reactnavigation&&T(e,u))i=!0;else{if(!a.input&&!a.lifecycle)return null!=r&&r.debug&&console.log("Dynatrace - Filtered All: ".concat(e)),h(e),n;a.lifecycle&&A(u)&&(i=!0),a.input&&g.forEach(function(n){n=X(u,n);u=n.root,i=i||n.p})}}i?(n=u.toSource({quote:"single"}),N(n,e)):h(e),null!=r&&r.debug&&i&&console.log("Dynatrace - Modified Filename: "+e)}else e.includes(c.join("@dynatrace","react-native-plugin"))&&e.endsWith(c.join("lib","core","configuration","ConfigurationPreset.js"))&&void 0!==r&&(t=(0,f.getHostAppBundleInfo)(l.default.getPackageJsonFile()),a=I(e,n),void 0!==r.lifecycle&&j(a,"getLifecycleUpdate",r.lifecycle.includeUpdate),void 0!==r.debug&&j(a,"getLogLevel",r.debug?0:1),void 0!==r.bundleName?j(a,"getBundleName",r.bundleName):null!==t&&j(a,"getBundleName",null==t?void 0:t.name),void 0!==r.bundleVersion?j(a,"getBundleVersion",r.bundleVersion):null!==t&&j(a,"getBundleVersion",null==t?void 0:t.version),void 0!==r.input&&void 0!==r.input.actionNamePrivacy&&j(a,"getActionNamePrivacy",r.input.actionNamePrivacy),void 0!==r.errorHandler&&(j(a,"isErrorHandlerEnabled",r.errorHandler.enabled),j(a,"isReportFatalErrorAsCrash",r.errorHandler.reportFatalErrorAsCrash)),r.autoStart&&j(a,"isAutoStartupEnabled",r.autoStart),n=a.toSource({quote:"single"}),N(n,e));return n},T=(exports.instrument=instrument,function(n,e){return!!B(n,e)&&(n="import { registerListener } from '".concat(b,"/react-navigation/ReactNavigation';"),e.find(u.ImportDeclaration).at(0).insertBefore(n),!0)}),B=function(n,e){var r=!1;return n.includes("react-navigation")&&n.includes("NavigationContainer.tsx")&&e.find(u.VariableDeclarator).forEach(function(n){r||null==n.value||null==n.value.id||"refContainer"!==n.value.id.name||null!=n.parent&&null!=n.parent.value&&null!=n.parent.value.type&&"VariableDeclaration"===n.parent.value.type&&(n.parent.insertAfter("registerListener(refContainer);"),r=!0)}),r},A=function(n){var e=n.findJSXElements(),t=!1;return 0<e.length&&(n.find(u.FunctionDeclaration).forEach(function(n){var e,r=(0,i.fromPaths)([n]);0<r.findJSXElements().length&&null!=n&&null!=n.value&&null!=n.value.id&&n.value.id.name.toString()&&(e=r.find(u.ClassDeclaration),r=r.find(u.ClassExpression),0===e.length)&&0===r.length&&(x(n,m.Types.FunctionalComponent,n.value.id.name.toString()),t=!0)}),n.find(u.ClassDeclaration).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n&&null!=n.value&&n.value.id&&n.value.id.name.toString()&&(x(n,m.Types.ClassComponent,n.value.id.name.toString()),t=!0)}),n.find(u.ArrowFunctionExpression).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n.parent&&null!=n.parent.value&&null!=n.parent.value.id&&null!=n.parent.value.id.name&&(x(n,m.Types.FunctionalComponent,n.parent.value.id.name),t=!0)})),t},x=function(n,e,r){for(e=u.expressionStatement(u.assignmentExpression("=",u.memberExpression(u.identifier(r),u.identifier("_dtInfo")),M(e,r)));"body"!==(null==n?void 0:n.parentPath.name);)n=n.parentPath;void 0!==n.parentPath&&n.insertAfter(e)},M=function(n,e){return u.objectExpression([u.objectProperty(u.identifier("type"),u.numericLiteral(n)),u.objectProperty(u.identifier("name"),u.stringLiteral(e))])},j=function(n,e,r){var n=n.find(u.Identifier).filter(function(n){return n.node.name===e});1===n.length&&"ReturnStatement"===(n=n.paths()[0].parent.value.body.body[0]).type&&("boolean"==typeof r&&(n.argument=u.booleanLiteral(r)),"string"==typeof r&&(n.argument=u.stringLiteral(r)),"number"==typeof r)&&(n.argument=u.numericLiteral(r))},I=function(n,e){return u.withParser((0,y.chooseParser)(n,e))(e)},O=function(n){return c.isAbsolute(n)?n.replace(l.default.getApplicationPath()+c.sep,""):n},h=function(n){try{var e=c.join(l.default.getBuildPath(),n+t.INSTRUMENTED_FILE_EXTENSION);r.default.checkIfFileExistsSync(e),r.default.deleteFileSync(e)}catch(n){}},N=function(n,e){e=c.join(l.default.getBuildPath(),e);try{r.default.checkIfFileExistsSync(c.dirname(e))}catch(n){r.default.createDirectorySync(c.dirname(e))}r.default.writeTextToFileSync(e+t.INSTRUMENTED_FILE_EXTENSION,n)},V=function(n,e){var r={input:!1,lifecycle:!1};return void 0!==e&&(void 0!==e.lifecycle&&void 0!==e.lifecycle.instrument&&e.lifecycle.instrument(n)&&(r.lifecycle=!0),void 0!==e.input)&&void 0!==e.input.instrument&&e.input.instrument(n)&&(r.input=!0),r},k=function(n){var e,n=n.find(u.Program);1===n.length&&(e=u.expressionStatement(u.callExpression(u.memberExpression(u.callExpression(u.identifier("require"),[u.stringLiteral("@dynatrace/react-native-plugin/instrumentation/jsx/ElementHelper")]),u.identifier("instrumentCreateElement")),[u.memberExpression(u.identifier("module"),u.identifier("exports"))])),n.paths()[0].node.body.push(e))},U=function(n){var e=n.find(u.FunctionDeclaration,{id:{name:"runApplication"}});return 1===e.length&&(_(n,{m:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),R(e.get().value.body.body,0,F("_DynatraceApplicationHandler","startup",[])),!0)},w=function(n){var e=n.find(u.ObjectMethod,{key:{name:"runApplication"}});return 1===e.length&&(_(n,{m:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),R(e.get().value.body.body,0,F("_DynatraceApplicationHandler","startup",[])),!0)},J=function(n,r,t){var i=u;n.find(i.FunctionDeclaration,{id:{name:"handleException"}}).forEach(function(n){var e=i.callExpression(i.memberExpression(i.callExpression(i.identifier("require"),[i.literal("@dynatrace/react-native-plugin/lib/core/ErrorHandler")]),i.identifier("reportErrorToDynatrace")),[i.identifier("e"),i.identifier("isFatal"),i.literal(r),i.literal(t)]),e=i.expressionStatement(i.callExpression(i.identifier("setTimeout"),[i.arrowFunctionExpression([],i.blockStatement(n.node.body.body)),e]));n.node.body.body=[e]})},G=function(n){var e=!1,n=n.find(u.CallExpression,{callee:{name:"require"}});return n.find(u.Literal,{value:"react/jsx-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-runtime",e=!0,n}),n.find(u.Literal,{value:"react/jsx-dev-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-dev-runtime",e=!0,n}),e},R=function(n,e){for(var r=arguments.length,t=new Array(2<r?r-2:0),i=2;i<r;i++)t[i-2]=arguments[i];return n.splice.apply(n,[e,0].concat(t))},z=function(n){if(n.includes("@dynatrace"))return o.i;var e=c.extname(n);if(".js"!==e&&".ts"!==e&&".tsx"!==e&&".jsx"!==e)return o.i;for(var r=c.parse(n),t=r.dir.split(c.sep),i=0;i<t.length;i++)if("node_modules"===t[i]){if("react-native"===t[i+1]||"create-react-class"===t[i+1]||"react-clone-referenced-element"===t[i+1])return q.includes(r.name)?o.o:o.i;if("react"===t[i+1]&&"index"===r.name)return o.l;if("react-native-css-interop"===t[i+1]&&("jsx-runtime"===r.name||"jsx-dev-runtime"===r.name))return o.v}return o.u},K=function(n,e,r){var t=Q(n,e,r);return W(n,e,r)||t},Q=function(n,e,r){var t=Y(n,e);return 0<t.length&&(void 0!==(t=H(t,e.reference,!1))&&(r.m=t.localName),tn(n,r),!0)},W=function(n,e,r){var t=E(n,e.module);if(1===t.length){t=H(t,e.reference,!0);if(void 0!==t)return un(n,r.defaultImport,t.localName,"ImportNamespaceSpecifier"===t.type),!0}return!1},X=function(n,e){var r=JSON.parse(JSON.stringify(e.new));return{root:n,p:K(n,e.old,r)||Z(n,e.old,e.new.defaultImport)}},Y=function(n,e){return n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e.module&&null!=n.node.specifiers&&n.node.specifiers.some(function(n){return C(n)&&n.imported.name===e.reference||n.local&&n.local.name===e.reference})})},C=function(n){return void 0!==n.imported},Z=function(n,e,r){var t=!1;return n.find(u.CallExpression).filter(function(n){return $(n.node.callee)&&nn(n.node.arguments[0])&&n.node.arguments[0].value===e.module&&void 0!==n.parent}).forEach(function(n){(void 0===n.parent.value.property||void 0!==n.parent.value.property&&void 0!==n.parent.value.property.name&&n.parent.value.property.name===e.reference)&&(n.node.arguments[0].value=r,t=t||!0)}),t},$=function(n){return"require"===n.name},nn=function(n){return"StringLiteral"===n.type||"Literal"===n.type},E=function(n,e){return n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e})},H=function(n,r,t){var i;return n.forEach(function(n){void 0!==n.node.specifiers&&(n.node.specifiers=n.node.specifiers.filter(function(n){var e;return C(n)&&!t?((e=n.imported.name!==r)||null==n.local||n.imported.name===n.local.name||(i={localName:n.local.name.toString(),type:n.type}),e):!(!C(n)&&t&&(null!=n.local&&(i={localName:n.local.name.toString(),type:n.type}),1))}),0===n.node.specifiers.length)&&n.prune()}),i},en=function(n,e){n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e.module}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(P(e))})},rn=function(n,e,r){n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(r)})},D=function(n,e,r){var t=n.find(u.ImportDeclaration);0<t.length?u(t.paths()[0]).insertAfter(S(e,r)):1===(t=n.find(u.Program)).length&&t.paths()[0].node.body.unshift(S(e,r))},tn=function(n,e){0<E(n,e.module).length?en(n,e):D(n,e.module,[P(e)])},un=function(n,e,r,t){var i=E(n,e),t=(t?vn:sn)(r);0<i.length?rn(n,e,t):D(n,e,[t])},_=function(n,e){n=n.find(u.VariableDeclaration);0<n.length&&u(n.paths()[0]).insertAfter(on(e))},F=function(n,e,r){return u.expressionStatement(an(n,e,r))},an=function(n,e,r){return u.callExpression(fn(n,e),r)},on=function(n){return u.variableDeclaration("var",[cn(n)])},cn=function(n){return u.variableDeclarator(void 0!==n.m?u.identifier(n.m):u.identifier(n.reference),(0<n.reference.length?ln:L)(n))},ln=function(n){return u.memberExpression(L(n),u.identifier(n.reference))},fn=function(n,e){return u.memberExpression(u.identifier(n),u.identifier(e))},L=function(n){return u.callExpression(u.identifier("require"),[u.literal(n.module)])},S=function(n,e){return u.importDeclaration(e,u.literal(n))},P=function(n){return void 0!==n.m?u.importSpecifier(u.identifier(n.reference),u.identifier(n.m)):u.importSpecifier(u.identifier(n.reference))},sn=function(n){return u.importDefaultSpecifier(u.identifier(n))},vn=function(n){return u.importNamespaceSpecifier(u.identifier(n))};
|
|
@@ -7,6 +7,15 @@ exports.Button = (0, withOnPressMonitoring_1.withOnPressMonitoring)(ReactNative.
|
|
|
7
7
|
exports.TouchableOpacity = (0, withOnPressMonitoring_1.withOnPressMonitoring)(ReactNative.TouchableOpacity, 'Touchable');
|
|
8
8
|
exports.TouchableHighlight = (0, withOnPressMonitoring_1.withOnPressMonitoring)(ReactNative.TouchableHighlight, 'Touchable');
|
|
9
9
|
exports.TouchableNativeFeedback = (0, withOnPressMonitoring_1.withOnPressMonitoring)(ReactNative.TouchableNativeFeedback, 'Touchable');
|
|
10
|
+
[
|
|
11
|
+
'Ripple',
|
|
12
|
+
'SelectableBackground',
|
|
13
|
+
'SelectableBackgroundBorderless',
|
|
14
|
+
'canUseNativeForeground',
|
|
15
|
+
].forEach((prop) => {
|
|
16
|
+
exports.TouchableNativeFeedback[prop] =
|
|
17
|
+
ReactNative.TouchableNativeFeedback[prop];
|
|
18
|
+
});
|
|
10
19
|
exports.TouchableWithoutFeedback = (0, withOnPressMonitoring_1.withOnPressMonitoring)(ReactNative.TouchableWithoutFeedback, 'Touchable');
|
|
11
20
|
exports.Text = (0, withOnPressMonitoring_1.withOnPressMonitoring)(ReactNative.Text, 'Text');
|
|
12
21
|
exports.Pressable = (0, withOnPressMonitoring_1.withOnPressMonitoring)(ReactNative.Pressable, 'Pressable');
|
package/ios/DynatraceRNBridge.mm
CHANGED
|
@@ -14,8 +14,10 @@
|
|
|
14
14
|
#import <React/RCTPerformanceLogger.h>
|
|
15
15
|
#import <React/RCTRootView.h>
|
|
16
16
|
#import <cxxreact/ReactMarker.h>
|
|
17
|
+
#import <cxxreact/ReactNativeVersion.h>
|
|
17
18
|
|
|
18
19
|
#include <chrono>
|
|
20
|
+
#include <type_traits>
|
|
19
21
|
|
|
20
22
|
@implementation DynatraceRNBridge
|
|
21
23
|
|
|
@@ -59,6 +61,16 @@ bool didEmit;
|
|
|
59
61
|
*/
|
|
60
62
|
int64_t contentAppeared;
|
|
61
63
|
|
|
64
|
+
/**
|
|
65
|
+
* When the JavaScript bundle started running
|
|
66
|
+
*/
|
|
67
|
+
int64_t runJSBundleStartTime;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* When the JavaScript bundle stopped running
|
|
71
|
+
*/
|
|
72
|
+
int64_t runJSBundleEndTime;
|
|
73
|
+
|
|
62
74
|
RCT_EXPORT_MODULE(DynatraceBridge);
|
|
63
75
|
|
|
64
76
|
- (instancetype) init
|
|
@@ -69,10 +81,51 @@ RCT_EXPORT_MODULE(DynatraceBridge);
|
|
|
69
81
|
hasListeners = NO;
|
|
70
82
|
didEmit = NO;
|
|
71
83
|
contentAppeared = -1;
|
|
84
|
+
runJSBundleStartTime = -1;
|
|
85
|
+
runJSBundleEndTime = -1;
|
|
86
|
+
registerLogTaggedMarkerCallbacks();
|
|
72
87
|
}
|
|
73
88
|
return self;
|
|
74
89
|
}
|
|
75
90
|
|
|
91
|
+
// We have to make sure facebook::react::ReactMarker::StartupLogger::getInstance().getRunJSBundleEndTime() is always available even for the RN < 72s cases.
|
|
92
|
+
// Relying on the if constexpr else does not work since namespaces get resolved before the if branch in the if constexpr gets discarded.
|
|
93
|
+
// SFINAE does not work for top level symbols in namespaces (because it actually is an error).
|
|
94
|
+
// We cannot use preprocessor directives since we don't have the React Native version as preprocessor macro.
|
|
95
|
+
// We cannot use C++ concepts since C++20 is not available.
|
|
96
|
+
// Thus we provide a fallback definition for StartupLogger.
|
|
97
|
+
// Calling the class methods without a definition cannot happen and won't result in a linker error since the if branch in the if constexpr does not get compiled.
|
|
98
|
+
namespace fallback {
|
|
99
|
+
class StartupLogger {
|
|
100
|
+
public:
|
|
101
|
+
static StartupLogger& getInstance();
|
|
102
|
+
double getRunJSBundleStartTime();
|
|
103
|
+
double getRunJSBundleEndTime();
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
namespace facebook::react::ReactMarker {
|
|
108
|
+
using namespace fallback;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
int64_t getRunJSBundleStartTime() {
|
|
112
|
+
if constexpr(facebook::react::ReactNativeVersion.Minor >= 72) {
|
|
113
|
+
auto time = facebook::react::ReactMarker::StartupLogger::getInstance().getRunJSBundleStartTime();
|
|
114
|
+
return std::isnan(time) ? -1 : time;
|
|
115
|
+
} else {
|
|
116
|
+
return runJSBundleStartTime;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
int64_t getRunJSBundleEndTime() {
|
|
121
|
+
if constexpr(facebook::react::ReactNativeVersion.Minor >= 72) {
|
|
122
|
+
auto time = facebook::react::ReactMarker::StartupLogger::getInstance().getRunJSBundleEndTime();
|
|
123
|
+
return std::isnan(time) ? -1 : time;
|
|
124
|
+
} else {
|
|
125
|
+
return runJSBundleEndTime;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
76
129
|
- (NSArray<NSString *> *)supportedEvents {
|
|
77
130
|
return @[EmitAppMeasurementsIdentifier];
|
|
78
131
|
}
|
|
@@ -83,21 +136,53 @@ int64_t GetTimestampUnix()
|
|
|
83
136
|
return millisecondsUTC;
|
|
84
137
|
}
|
|
85
138
|
|
|
139
|
+
/*
|
|
140
|
+
In RN < 72, logTaggedMarker and logTaggedMarkerBridgeless are lambdas. In RN >= 72, these symbols are functions.
|
|
141
|
+
Relying on an if constexpr else does not work since types get checked before one branch in an if constexpr else gets discarded.
|
|
142
|
+
We cannot use a fallback declaration since since the symbol is declared as a function in RN >=72.
|
|
143
|
+
We cannot use preprocessor directives since we don't have the React Native version as preprocessor macro.
|
|
144
|
+
We cannot use C++ concepts since C++20 is not available.
|
|
145
|
+
Thus we use SFINAE. This works since types only get checked after template resolution.
|
|
146
|
+
*/
|
|
147
|
+
template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersion.Minor < 72), T> registerLogTaggedMarkerCallbacks() {
|
|
148
|
+
using namespace facebook::react::ReactMarker;
|
|
149
|
+
auto logTaggedMarkerCommon = [](const ReactMarkerId markerId, const char* tag, auto previousLogTaggedMarker) {
|
|
150
|
+
if (previousLogTaggedMarker) {
|
|
151
|
+
previousLogTaggedMarker(markerId, tag);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (markerId == RUN_JS_BUNDLE_START) {
|
|
155
|
+
runJSBundleStartTime = GetTimestampUnix();
|
|
156
|
+
} else if (markerId == RUN_JS_BUNDLE_STOP) {
|
|
157
|
+
runJSBundleEndTime = GetTimestampUnix();
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
auto previousLogTaggedMarker = logTaggedMarker;
|
|
162
|
+
logTaggedMarker = [=](const ReactMarkerId markerId, const char* tag) {
|
|
163
|
+
logTaggedMarkerCommon(markerId, tag, previousLogTaggedMarker);
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
auto previousLogTaggedMarkerBridgeless = logTaggedMarkerBridgeless;
|
|
167
|
+
logTaggedMarkerBridgeless = [=](const ReactMarkerId markerId, const char* tag) {
|
|
168
|
+
logTaggedMarkerCommon(markerId, tag, previousLogTaggedMarkerBridgeless);
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersion.Minor >= 72), T> registerLogTaggedMarkerCallbacks() {}
|
|
173
|
+
|
|
86
174
|
/**
|
|
87
175
|
* When bridge is starting we will add an observer for content did appear so we can emit our app start measurements
|
|
88
176
|
*/
|
|
89
177
|
- (void)setBridge:(RCTBridge *)bridge
|
|
90
178
|
{
|
|
91
179
|
[super setBridge:bridge];
|
|
92
|
-
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
93
|
-
selector:@selector(contentAppeared)
|
|
94
|
-
name:RCTContentDidAppearNotification
|
|
95
|
-
object:nil];
|
|
180
|
+
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentAppeared) name:RCTContentDidAppearNotification object:nil];
|
|
96
181
|
}
|
|
97
182
|
|
|
98
183
|
- (BOOL)isReady
|
|
99
184
|
{
|
|
100
|
-
return contentAppeared != -1 &&
|
|
185
|
+
return contentAppeared != -1 && getRunJSBundleEndTime() != -1;
|
|
101
186
|
}
|
|
102
187
|
|
|
103
188
|
- (void) contentAppeared
|
|
@@ -116,8 +201,8 @@ int64_t GetTimestampUnix()
|
|
|
116
201
|
|
|
117
202
|
NSMutableDictionary<NSString*, NSNumber*> *appStartMeasurements = [[NSMutableDictionary alloc] init];
|
|
118
203
|
|
|
119
|
-
[appStartMeasurements setObject:[self correctionOfTimestamp:
|
|
120
|
-
[appStartMeasurements setObject:[self correctionOfTimestamp:
|
|
204
|
+
[appStartMeasurements setObject:[self correctionOfTimestamp:getRunJSBundleStartTime()] forKey:RunJSBundleStart];
|
|
205
|
+
[appStartMeasurements setObject:[self correctionOfTimestamp:getRunJSBundleEndTime()] forKey:RunJSBundleEnd];
|
|
121
206
|
[appStartMeasurements setObject:[NSNumber numberWithLongLong:contentAppeared] forKey:ContentAppeared];
|
|
122
207
|
|
|
123
208
|
if (hasListeners) {
|
|
@@ -128,7 +213,13 @@ int64_t GetTimestampUnix()
|
|
|
128
213
|
|
|
129
214
|
- (NSNumber* )correctionOfTimestamp:(int64_t) timestamp
|
|
130
215
|
{
|
|
131
|
-
|
|
216
|
+
if constexpr (facebook::react::ReactNativeVersion.Minor < 72) {
|
|
217
|
+
// In RN < 72, timestamps are unix timestamps
|
|
218
|
+
return [NSNumber numberWithLongLong:timestamp];
|
|
219
|
+
} else {
|
|
220
|
+
// IN RN >= 72, timestamps are relative to the system start, which is we we add the unix timestamp of the system start
|
|
221
|
+
return [NSNumber numberWithLongLong:timestamp + GetTimestampUnix() - (CACurrentMediaTime() * 1000)];
|
|
222
|
+
}
|
|
132
223
|
}
|
|
133
224
|
|
|
134
225
|
/**
|
package/lib/core/ErrorHandler.js
CHANGED
|
@@ -5,6 +5,7 @@ const DynatraceInternal_1 = require("./DynatraceInternal");
|
|
|
5
5
|
const Dynatrace_1 = require("./Dynatrace");
|
|
6
6
|
const StringUtils_1 = require("./util/StringUtils");
|
|
7
7
|
const ConsoleLogger_1 = require("./logging/ConsoleLogger");
|
|
8
|
+
const react_native_1 = require("react-native");
|
|
8
9
|
const logger = new ConsoleLogger_1.ConsoleLogger('ErrorHandler');
|
|
9
10
|
let manualStart = { enabled: false };
|
|
10
11
|
const startErrorHandler = (reportFatalErrorAsCrash) => {
|
|
@@ -16,7 +17,7 @@ const startErrorHandler = (reportFatalErrorAsCrash) => {
|
|
|
16
17
|
exports.startErrorHandler = startErrorHandler;
|
|
17
18
|
const reportErrorToDynatrace = (exception, isFatal, reportFatalErrorAsCrashFromConfig, autoStart) => {
|
|
18
19
|
if (!autoStart && !manualStart)
|
|
19
|
-
return;
|
|
20
|
+
return 0;
|
|
20
21
|
const reportFatalErrorAsCrash = manualStart.enabled
|
|
21
22
|
? manualStart.reportFatalErrorAsCrash
|
|
22
23
|
: reportFatalErrorAsCrashFromConfig;
|
|
@@ -33,6 +34,7 @@ const reportErrorToDynatrace = (exception, isFatal, reportFatalErrorAsCrashFromC
|
|
|
33
34
|
Dynatrace_1.Dynatrace.reportError(String(exception), -1);
|
|
34
35
|
logger.debug(`reportErrorToDynatrace(${exception}, -1)`);
|
|
35
36
|
}
|
|
37
|
+
return react_native_1.Platform.OS === 'ios' ? 200 : 0;
|
|
36
38
|
};
|
|
37
39
|
exports.reportErrorToDynatrace = reportErrorToDynatrace;
|
|
38
40
|
const adjustedReason = (reason) => {
|
|
@@ -15,20 +15,17 @@ class AppStartObserverImpl {
|
|
|
15
15
|
call() {
|
|
16
16
|
}
|
|
17
17
|
setupNativeEventEmitter() {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
}
|
|
18
|
+
const emitter = new react_native_1.NativeEventEmitter(DynatraceBridge_1.DynatraceNative);
|
|
19
|
+
emitter.addListener(this.EMIT_APP_START, (data) => {
|
|
20
|
+
this.logger.debug(`emitter(${JSON.stringify(data)}})`);
|
|
21
|
+
const appStartEvent = (0, EventCreator_1.createAppStartEvent)(data);
|
|
22
|
+
if (appStartEvent != null) {
|
|
23
|
+
EventPipeline_1.EventPipeline.insertEvent(Object.assign({}, appStartEvent));
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
this.logger.debug(`emitter(${JSON.stringify(data)}}): App Start event ignored!`);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
32
29
|
}
|
|
33
30
|
}
|
|
34
31
|
exports.AppStartObserver = new AppStartObserverImpl();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const ConsoleLogger_1 = require("../../core/logging/ConsoleLogger");
|
|
4
|
-
const SendEventValidation_1 = require("./modifier/SendEventValidation");
|
|
5
4
|
const TimestampProvider_1 = require("../provider/TimestampProvider");
|
|
5
|
+
const SendEventValidation_1 = require("./modifier/SendEventValidation");
|
|
6
6
|
const logger = new ConsoleLogger_1.ConsoleLogger('Dynatrace');
|
|
7
7
|
class HttpRequestEventBuilder {
|
|
8
8
|
constructor(url, requestMethod) {
|
|
@@ -10,7 +10,7 @@ class HttpRequestEventBuilder {
|
|
|
10
10
|
this.requestMethod = requestMethod;
|
|
11
11
|
this.duration = 0;
|
|
12
12
|
this.rawEventProperties = {};
|
|
13
|
-
this.
|
|
13
|
+
this.traceContextHint = "api_unused";
|
|
14
14
|
this.hasDroppedCustomProperties = false;
|
|
15
15
|
this.hasNfnValues = false;
|
|
16
16
|
this.triedToOverwriteDuration = false;
|
|
@@ -44,6 +44,7 @@ class HttpRequestEventBuilder {
|
|
|
44
44
|
}
|
|
45
45
|
withTraceparentHeader(traceparentHeader) {
|
|
46
46
|
this.traceparentHeader = traceparentHeader;
|
|
47
|
+
this.traceContextHint = "api_set";
|
|
47
48
|
return this;
|
|
48
49
|
}
|
|
49
50
|
addEventProperty(key, value) {
|
|
@@ -62,20 +63,19 @@ class HttpRequestEventBuilder {
|
|
|
62
63
|
this.sanitizeBytesSent();
|
|
63
64
|
const parsedTraceparentHeader = this.traceparentHeader &&
|
|
64
65
|
this.parseTraceparent(this.traceparentHeader);
|
|
65
|
-
this.
|
|
66
|
-
|
|
66
|
+
if (!!this.traceparentHeader && !parsedTraceparentHeader) {
|
|
67
|
+
this.traceContextHint = "invalid";
|
|
68
|
+
}
|
|
67
69
|
const hasFailedRequest = this.isStatusCodeError() || !!this.error;
|
|
68
70
|
const filteredEventProperties = Object.fromEntries(Object.entries(this.rawEventProperties).filter(this.isEventPropertyKey, this));
|
|
69
71
|
const sanitizedEventProperties = SendEventValidation_1.SendEventValidation.modifyEvent(filteredEventProperties);
|
|
70
|
-
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(
|
|
72
|
+
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, sanitizedEventProperties), { ["url.full"]: this.url, ["network.protocol.name"]: 'http', ["http.request.method"]: this.requestMethod, ["request.trace_context_hint"]: this.traceContextHint, ["duration"]: this.duration, ["start_time"]: TimestampProvider_1.defaultTimestampProvider.getCurrentTimestamp() - this.duration }), (this.triedToOverwriteDuration && {
|
|
71
73
|
["dt.support.api.overridden_fields"]: [
|
|
72
74
|
'duration',
|
|
73
75
|
],
|
|
74
76
|
})), this.includeIfDefined("http.response.status_code", this.statusCode)), this.includeIfDefined("http.response.reason_phrase", this.reasonPhrase)), this.includeIfDefined("request.bytes_sent", this.bytesSent)), this.includeIfDefined("request.bytes_received", this.bytesReceived)), { ["characteristics.has_request"]: true, ["characteristics.is_api_reported"]: true }), this.includeIfTrue("characteristics.has_failed_request", hasFailedRequest)), this.includeIfTrue("characteristics.has_error", hasFailedRequest)), (this.error !== undefined && Object.assign({ ["characteristics.has_exception"]: true, ["exception.type"]: this.error.name, ["exception.message"]: this.error.message }, this.includeIfDefined("exception.stack_trace", this.error.stack)))), (parsedTraceparentHeader && {
|
|
75
77
|
["trace.id"]: parsedTraceparentHeader.traceId,
|
|
76
78
|
["span.id"]: parsedTraceparentHeader.spanId,
|
|
77
|
-
})), (this.hasDroppedTraceparent && {
|
|
78
|
-
["request.trace_context_hint"]: 'invalid_header',
|
|
79
79
|
})), this.includeIfTrue("dt.support.api.has_dropped_custom_properties", this.hasDroppedCustomProperties)), this.includeIfTrue("dt.support.has_nfn_values", this.hasNfnValues));
|
|
80
80
|
}
|
|
81
81
|
hasValidMandatoryAttriutes() {
|
package/package.json
CHANGED
|
@@ -111,7 +111,7 @@ Pod::Spec.new do |s|
|
|
|
111
111
|
#
|
|
112
112
|
|
|
113
113
|
s.dependency "React"
|
|
114
|
-
s.dependency 'Dynatrace', '~> 8.
|
|
114
|
+
s.dependency 'Dynatrace', '~> 8.327.2.1022'
|
|
115
115
|
|
|
116
116
|
# Allows for better compatibility for older and newer versions
|
|
117
117
|
if defined?(install_modules_dependencies)
|
package/types.d.ts
CHANGED
|
@@ -226,9 +226,10 @@ interface IDynatraceAction {
|
|
|
226
226
|
* Reports an error event with an error code. The key-value pair is marked as an error type.
|
|
227
227
|
*
|
|
228
228
|
* **Note:** The error will not be reported if the action is already closed or if the errorName
|
|
229
|
-
* is null or empty.
|
|
229
|
+
* is null or empty. String values are limited to 250 characters and will be truncated if they
|
|
230
|
+
* exceed this limit.
|
|
230
231
|
*
|
|
231
|
-
* @param {string} errorName Name of the error event
|
|
232
|
+
* @param {string} errorName Name of the error event (limited to 250 characters)
|
|
232
233
|
* @param {number} errorCode The error code to report
|
|
233
234
|
* @param {Platform} platform Optional platform filter. Defaults to both Android and iOS.
|
|
234
235
|
*
|
|
@@ -254,9 +255,10 @@ interface IDynatraceAction {
|
|
|
254
255
|
* This method provides a simple way to monitor user behavior and application flow.
|
|
255
256
|
*
|
|
256
257
|
* **Note:** The event will not be reported if the action is already closed or if the eventName
|
|
257
|
-
* is null or empty.
|
|
258
|
+
* is null or empty. String values are limited to 250 characters and will be truncated if they
|
|
259
|
+
* exceed this limit.
|
|
258
260
|
*
|
|
259
|
-
* @param eventName Name of the event to report
|
|
261
|
+
* @param eventName Name of the event to report (limited to 250 characters)
|
|
260
262
|
* @param platform Optional platform filter. Defaults to both Android and iOS.
|
|
261
263
|
*
|
|
262
264
|
* @example
|
|
@@ -276,10 +278,11 @@ interface IDynatraceAction {
|
|
|
276
278
|
* Reports a timestamped string key-value pair for tracking important measurement data.
|
|
277
279
|
*
|
|
278
280
|
* **Note:** The event will not be reported if the action is already closed, or if either
|
|
279
|
-
* valueName or value is null or empty.
|
|
281
|
+
* valueName or value is null or empty. String values are limited to 250 characters and will
|
|
282
|
+
* be truncated if they exceed this limit.
|
|
280
283
|
*
|
|
281
|
-
* @param valueName Name of the value being reported
|
|
282
|
-
* @param value String value to report
|
|
284
|
+
* @param valueName Name of the value being reported (limited to 250 characters)
|
|
285
|
+
* @param value String value to report (limited to 250 characters)
|
|
283
286
|
* @param platform Optional platform filter. Defaults to both Android and iOS.
|
|
284
287
|
*
|
|
285
288
|
* @example
|
|
@@ -299,9 +302,10 @@ interface IDynatraceAction {
|
|
|
299
302
|
* Reports a timestamped integer key-value pair for tracking important measurement data.
|
|
300
303
|
*
|
|
301
304
|
* **Note:** The event will not be reported if the action is already closed or if
|
|
302
|
-
* valueName is null or empty.
|
|
305
|
+
* valueName is null or empty. The valueName is limited to 250 characters and will be
|
|
306
|
+
* truncated if it exceeds this limit.
|
|
303
307
|
*
|
|
304
|
-
* @param valueName Name of the value being reported
|
|
308
|
+
* @param valueName Name of the value being reported (limited to 250 characters)
|
|
305
309
|
* @param value Integer value to report
|
|
306
310
|
* @param platform Optional platform filter. Defaults to both Android and iOS.
|
|
307
311
|
*
|
|
@@ -322,9 +326,10 @@ interface IDynatraceAction {
|
|
|
322
326
|
* Reports a timestamped double (floating-point) key-value pair for tracking important measurement data.
|
|
323
327
|
*
|
|
324
328
|
* **Note:** The event will not be reported if the action is already closed or if
|
|
325
|
-
* valueName is null or empty.
|
|
329
|
+
* valueName is null or empty. The valueName is limited to 250 characters and will be
|
|
330
|
+
* truncated if it exceeds this limit.
|
|
326
331
|
*
|
|
327
|
-
* @param valueName Name of the value being reported
|
|
332
|
+
* @param valueName Name of the value being reported (limited to 250 characters)
|
|
328
333
|
* @param value Double (floating-point) value to report
|
|
329
334
|
* @param platform Optional platform filter. Defaults to both Android and iOS.
|
|
330
335
|
*
|
|
@@ -682,26 +687,26 @@ interface IHttpRequestEventBuilder {
|
|
|
682
687
|
*/
|
|
683
688
|
withReasonPhrase(reasonPhrase: string): this;
|
|
684
689
|
/**
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
690
|
+
* Associates an error with the HTTP request event.
|
|
691
|
+
*
|
|
692
|
+
* @param error A standard JavaScript Error object representing the request failure
|
|
693
|
+
* @returns The builder instance for method chaining
|
|
694
|
+
*
|
|
695
|
+
* @example
|
|
696
|
+
* ```ts
|
|
697
|
+
* import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
|
|
698
|
+
*
|
|
699
|
+
* try {
|
|
700
|
+
* // Request code
|
|
701
|
+
* } catch (error) {
|
|
702
|
+
* const requestEvent = new HttpRequestEventBuilder('https://api.example.com/data', 'GET')
|
|
703
|
+
* .withError(error);
|
|
704
|
+
* Dynatrace.sendHttpRequestEvent(requestEvent);
|
|
705
|
+
* }
|
|
706
|
+
* ```
|
|
707
|
+
*
|
|
708
|
+
* @see https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/api
|
|
709
|
+
*/
|
|
705
710
|
withError(error: Error): this;
|
|
706
711
|
/**
|
|
707
712
|
* Sets the number of bytes sent in the request.
|
|
@@ -759,32 +764,32 @@ interface IHttpRequestEventBuilder {
|
|
|
759
764
|
*/
|
|
760
765
|
withTraceparentHeader(traceparentHeader: TraceparentHeader): this;
|
|
761
766
|
/**
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
767
|
+
* Adds a custom event property to the request event.
|
|
768
|
+
* @param key The property key. See property requirements below.
|
|
769
|
+
* @param value The property value. Cannot contain functions, undefined, Infinity, or NaN (they will be replaced with null).
|
|
770
|
+
*
|
|
771
|
+
* **Property Requirements:**
|
|
772
|
+
* - Only properties prefixed with `event_properties.*` are allowed
|
|
773
|
+
* - Maximum of 50 custom properties per event
|
|
774
|
+
* - String properties are limited to 5000 characters (exceeding characters are truncated)
|
|
775
|
+
* - Field names must contain only alphabetic characters, numbers, underscores, and dots
|
|
776
|
+
* - Each dot must be followed by an alphabetic character
|
|
777
|
+
* - Each underscore must be followed by an alphabetic character or number
|
|
778
|
+
*
|
|
779
|
+
* @returns The builder instance for method chaining
|
|
780
|
+
*
|
|
781
|
+
* @example
|
|
782
|
+
* ```ts
|
|
783
|
+
* import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
|
|
784
|
+
*
|
|
785
|
+
* const requestEvent = new HttpRequestEventBuilder('https://api.example.com/data', 'GET')
|
|
786
|
+
* .addEventProperty('event_properties.user_id', '12345')
|
|
787
|
+
* .addEventProperty('event_properties.api_version', 'v2');
|
|
788
|
+
* Dynatrace.sendHttpRequestEvent(requestEvent);
|
|
789
|
+
* ```
|
|
790
|
+
*
|
|
791
|
+
* @see https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/api
|
|
792
|
+
*/
|
|
788
793
|
addEventProperty(key: `event_properties.${string}`, value: EventProperty): this;
|
|
789
794
|
}
|
|
790
795
|
|
|
@@ -906,7 +911,7 @@ interface IDynatrace$1 {
|
|
|
906
911
|
*
|
|
907
912
|
* **Property Requirements:**
|
|
908
913
|
* - Only properties prefixed with `event_properties.*` are allowed
|
|
909
|
-
* - Additionally, `duration`
|
|
914
|
+
* - Additionally, the `duration` property is allowed
|
|
910
915
|
* - Maximum of 50 custom properties per event
|
|
911
916
|
* - String properties are limited to 5000 characters (exceeding characters are truncated)
|
|
912
917
|
* - Field names must contain only alphabetic characters, numbers, underscores, and dots
|
|
@@ -939,7 +944,7 @@ interface IDynatrace$1 {
|
|
|
939
944
|
*
|
|
940
945
|
* **Property Requirements:**
|
|
941
946
|
* - Only properties prefixed with `event_properties.*` are allowed
|
|
942
|
-
* - Additionally, `duration`
|
|
947
|
+
* - Additionally, the `duration` property is allowed
|
|
943
948
|
* - Maximum of 50 custom properties per event
|
|
944
949
|
* - String properties are limited to 5000 characters (exceeding characters are truncated)
|
|
945
950
|
* - Field names must contain only alphabetic characters, numbers, underscores, and dots
|
|
@@ -1003,7 +1008,7 @@ interface IDynatrace$1 {
|
|
|
1003
1008
|
*
|
|
1004
1009
|
* **Property Requirements:**
|
|
1005
1010
|
* - Only properties prefixed with `session_properties.*` are allowed
|
|
1006
|
-
* - Additionally, `duration`
|
|
1011
|
+
* - Additionally, the `duration` property is allowed
|
|
1007
1012
|
* - Maximum of 50 custom properties per event
|
|
1008
1013
|
* - String properties are limited to 5000 characters (exceeding characters are truncated)
|
|
1009
1014
|
* - Field names must contain only alphabetic characters, numbers, underscores, and dots
|
|
@@ -1063,7 +1068,7 @@ interface IDynatraceRootAction extends IDynatraceAction {
|
|
|
1063
1068
|
* **Note:** When the parent action is closed with `leaveAction()` or `cancel()`, all
|
|
1064
1069
|
* child actions are automatically closed as well.
|
|
1065
1070
|
*
|
|
1066
|
-
* @param {string} name Name of the child action
|
|
1071
|
+
* @param {string} name Name of the child action (limited to 250 characters)
|
|
1067
1072
|
* @param {Platform} platform Optional platform filter. Defaults to both Android and iOS.
|
|
1068
1073
|
* @returns {IDynatraceAction} The created child action instance
|
|
1069
1074
|
*
|
|
@@ -1149,7 +1154,7 @@ interface IDynatrace extends IDynatrace$1 {
|
|
|
1149
1154
|
* is open, will be automatically inserted as a child action. Furthermore the plugin will automatically
|
|
1150
1155
|
* link webrequest (if they are not tagged manually) to the open root action.
|
|
1151
1156
|
*
|
|
1152
|
-
* @param {string} name Name of the action, which will be created. This name must not be empty.
|
|
1157
|
+
* @param {string} name Name of the action, which will be created. This name must not be empty. (limited to 250 characters)
|
|
1153
1158
|
* @param {Platform} platform Is optional, which means by default this call will be applied on both platforms (Android & iOS).
|
|
1154
1159
|
* @returns {IDynatraceAction} Action that is created. If name was empty a NullAction will be provided,
|
|
1155
1160
|
* which will act as normal action, but has no functionality.
|
|
@@ -1173,7 +1178,7 @@ interface IDynatrace extends IDynatrace$1 {
|
|
|
1173
1178
|
* because of the full manual approach the plugin will not link webrequest automatically. Webrequest
|
|
1174
1179
|
* have to be manually tagged by using the tag provided by the action via {@link IDynatraceAction.getRequestTag}.
|
|
1175
1180
|
*
|
|
1176
|
-
* @param {string} name Name of the action, which will be created. This name must not be empty.
|
|
1181
|
+
* @param {string} name Name of the action, which will be created. This name must not be empty. (limited to 250 characters)
|
|
1177
1182
|
* @param {Platform} platform Is optional, which means by default this call will be applied on both platforms (Android & iOS).
|
|
1178
1183
|
* @returns {IDynatraceRootAction} Action that is created. If name was empty a NullRootAction will be provided,
|
|
1179
1184
|
* which will act as normal root action, but has no functionality.
|
|
@@ -1193,7 +1198,7 @@ interface IDynatrace extends IDynatrace$1 {
|
|
|
1193
1198
|
/**
|
|
1194
1199
|
* Similar to {@link IDynatraceAction.reportError}. But the error event is reported as root action.
|
|
1195
1200
|
*
|
|
1196
|
-
* @param {string} errorName Name of the error event
|
|
1201
|
+
* @param {string} errorName Name of the error event (limited to 250 characters)
|
|
1197
1202
|
* @param {number} errorCode The code of the error
|
|
1198
1203
|
* @param {Platform} platform Is optional, which means by default this call will be applied on both platforms (Android & iOS).
|
|
1199
1204
|
*
|
|
@@ -1212,7 +1217,7 @@ interface IDynatrace extends IDynatrace$1 {
|
|
|
1212
1217
|
*
|
|
1213
1218
|
* @deprecated Please use {@link reportErrorStacktrace} instead.
|
|
1214
1219
|
*
|
|
1215
|
-
* @param {String} errorName Name of the Error - SyntaxError
|
|
1220
|
+
* @param {String} errorName Name of the Error - SyntaxError (limited to 250 characters)
|
|
1216
1221
|
* @param {String} reason Reason for the Error
|
|
1217
1222
|
* @param {String} stacktrace Whole Stacktrace
|
|
1218
1223
|
* @param {Platform} platform Is optional, which means by default this call will be applied on both platforms (Android & iOS).
|
|
@@ -1221,7 +1226,7 @@ interface IDynatrace extends IDynatrace$1 {
|
|
|
1221
1226
|
/**
|
|
1222
1227
|
* Reports a stacktrace
|
|
1223
1228
|
*
|
|
1224
|
-
* @param {string} errorName Name of the error
|
|
1229
|
+
* @param {string} errorName Name of the error (limited to 250 characters)
|
|
1225
1230
|
* @param {string} errorValue Value of the error
|
|
1226
1231
|
* @param {string} reason Reason for the error
|
|
1227
1232
|
* @param {string} stacktrace Whole stacktrace
|
|
@@ -1240,7 +1245,7 @@ interface IDynatrace extends IDynatrace$1 {
|
|
|
1240
1245
|
/**
|
|
1241
1246
|
* Reports a custom crash
|
|
1242
1247
|
*
|
|
1243
|
-
* @param {string} crashName Name of the crash
|
|
1248
|
+
* @param {string} crashName Name of the crash (limited to 250 characters)
|
|
1244
1249
|
* @param {string} reason Reason for the crash
|
|
1245
1250
|
* @param {string} stacktrace Whole stacktrace
|
|
1246
1251
|
* @param {Platform} platform Is optional, which means by default this call will be applied on both platforms (Android & iOS).
|
|
@@ -1258,7 +1263,7 @@ interface IDynatrace extends IDynatrace$1 {
|
|
|
1258
1263
|
/**
|
|
1259
1264
|
* Reports a crash with an error object (which needs to contain a stacktrace)
|
|
1260
1265
|
*
|
|
1261
|
-
* @param {string} crashName Name of the crash
|
|
1266
|
+
* @param {string} crashName Name of the crash (limited to 250 characters)
|
|
1262
1267
|
* @param {Error} crash error object
|
|
1263
1268
|
* @param {Platform} platform Is optional, which means by default this call will be applied on both platforms (Android & iOS).
|
|
1264
1269
|
*
|
|
@@ -1323,7 +1328,7 @@ interface IDynatrace extends IDynatrace$1 {
|
|
|
1323
1328
|
* The value will not be stored and has to be renewed for every new session.
|
|
1324
1329
|
*
|
|
1325
1330
|
* @param {string} user a unique id that allows you to identify the current user.
|
|
1326
|
-
* If user is null or empty, then the user tag will be removed from the session.
|
|
1331
|
+
* If user is null or empty, then the user tag will be removed from the session. (limited to 250 characters)
|
|
1327
1332
|
* @param {Platform} platform Is optional, which means by default this call will be applied on both platforms (Android & iOS).
|
|
1328
1333
|
*
|
|
1329
1334
|
* @example
|