@dynatrace/react-native-plugin 2.327.2 → 2.331.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +419 -164
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/dynatrace/android/agent/DynatraceConfigurationModule.kt +48 -0
- package/android/src/main/java/com/dynatrace/android/agent/DynatraceRNBridgeImpl.kt +41 -8
- package/android/src/main/java/com/dynatrace/android/agent/DynatraceReactPackage.kt +3 -0
- package/android/src/main/java/com/dynatrace/android/agent/DynatraceRuntimeConfigurationStore.kt +14 -0
- package/android/src/main/java/com/dynatrace/android/agent/DynatraceUtils.kt +103 -47
- package/android/src/new/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +12 -4
- package/android/src/old/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +15 -5
- package/files/default.config.js +7 -0
- package/files/plugin-runtime.gradle +7 -17
- package/files/plugin.gradle +1 -1
- package/instrumentation/DynatraceInstrumentation.js +1 -1
- package/instrumentation/libs/react-navigation/ReactNavigation.js +53 -18
- package/ios/ConfigurationSubscriber.h +15 -0
- package/ios/DynatraceRNBridge.h +4 -0
- package/ios/DynatraceRNBridge.mm +125 -29
- package/lib/core/Dynatrace.js +8 -11
- package/lib/core/configuration/ConfigurationHandler.js +3 -0
- package/lib/next/Dynatrace.js +50 -33
- package/lib/next/DynatraceArgValidators.js +10 -0
- package/lib/next/DynatraceEventBus.js +35 -0
- package/lib/next/appstart/AppStartObserver.js +2 -3
- package/lib/next/configuration/INativeRuntimeConfiguration.js +7 -0
- package/lib/next/configuration/RuntimeConfigurationObserver.js +40 -0
- package/lib/next/events/EventBuilderUtil.js +7 -0
- package/lib/next/events/EventData.js +28 -0
- package/lib/next/events/EventPipeline.js +5 -11
- package/lib/next/events/ExceptionEventData.js +26 -0
- package/lib/next/events/HttpRequestEventData.js +174 -0
- package/lib/next/events/SessionPropertyEventData.js +22 -0
- package/lib/next/events/interface/IBaseEvent.js +2 -0
- package/lib/next/events/interface/IEventData.js +2 -0
- package/lib/next/events/interface/IExceptionEventData.js +2 -0
- package/lib/next/events/interface/IHttpRequestEventData.js +2 -0
- package/lib/next/events/interface/ISessionPropertyEventData.js +2 -0
- package/lib/next/events/modifier/BaseDataEventModifier.js +1 -3
- package/lib/next/events/modifier/EventModifierUtil.js +34 -41
- package/lib/next/events/modifier/ModifyEventValidation.js +117 -27
- package/lib/next/events/modifier/SendEventValidation.js +53 -22
- package/lib/next/events/modifier/StringLengthEventModifier.js +53 -0
- package/lib/next/events/spec/EventSpecContstants.js +9 -2
- package/package.json +11 -5
- package/public.js +9 -3
- package/react-native-dynatrace.podspec +1 -1
- package/scripts/Config.js +6 -2
- package/scripts/LineOffsetAnalyze.js +1 -4
- package/scripts/core/LineOffsetAnalyzeCall.js +39 -46
- package/src/lib/core/interface/NativeDynatraceBridge.ts +6 -2
- package/types.d.ts +408 -177
- package/lib/next/events/HttpRequestEventBuilder.js +0 -196
- package/lib/next/events/ViewInfoCreator.js +0 -27
- package/lib/next/events/modifier/EventLimitation.js +0 -69
- /package/lib/next/events/{IHttpRequestEventBuilder.js → interface/EventProperty.js} +0 -0
package/ios/DynatraceRNBridge.h
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#import <Dynatrace/Dynatrace.h>
|
|
9
9
|
#import <React/RCTBridgeModule.h>
|
|
10
10
|
#import <React/RCTEventEmitter.h>
|
|
11
|
+
#import "ConfigurationSubscriber.h"
|
|
11
12
|
|
|
12
13
|
@interface DynatraceRNBridge : RCTEventEmitter <RCTBridgeModule>
|
|
13
14
|
- (void) newAction:(NSString *)name key:(NSString *)key parentAction:(DTXAction *)parentAction;
|
|
@@ -18,6 +19,9 @@
|
|
|
18
19
|
@interface HybridBridge : NSObject
|
|
19
20
|
+ (void)forwardEvent:(NSDictionary<NSString*,id>* _Nullable)fields NS_SWIFT_NAME(forwardEvent(fields:));
|
|
20
21
|
+ (void)forwardAppStartEvent:(NSDictionary<NSString*,id>* _Nullable)fields keys:(NSArray<NSString*>* _Nullable)keys NS_SWIFT_NAME(forwardEvent(fields:keys:));
|
|
22
|
+
+ (void)startView:(NSDictionary<NSString*,id>* _Nullable)fields NS_SWIFT_NAME(startView(fields:));
|
|
23
|
+
+ (void)stopView;
|
|
24
|
+
+ (void)addConfigurationSubscriber:(id<ConfigurationSubscriber>)subscriber;
|
|
21
25
|
@end
|
|
22
26
|
|
|
23
27
|
typedef enum : NSUInteger {
|
package/ios/DynatraceRNBridge.mm
CHANGED
|
@@ -13,12 +13,46 @@
|
|
|
13
13
|
#import <CoreLocation/CoreLocation.h>
|
|
14
14
|
#import <React/RCTPerformanceLogger.h>
|
|
15
15
|
#import <React/RCTRootView.h>
|
|
16
|
+
#import <React/RCTBridge+Private.h>
|
|
16
17
|
#import <cxxreact/ReactMarker.h>
|
|
17
18
|
#import <cxxreact/ReactNativeVersion.h>
|
|
18
19
|
|
|
19
20
|
#include <chrono>
|
|
20
21
|
#include <type_traits>
|
|
21
22
|
|
|
23
|
+
@interface DynatraceRNBridge ()
|
|
24
|
+
- (void)handleRuntimeConfiguration:(NSDictionary<NSString*, id>*)configuration;
|
|
25
|
+
- (void)setupRuntimeConfigurationListenerIfNeeded;
|
|
26
|
+
- (void)emitToJS:(NSString*)event body:(id)body;
|
|
27
|
+
@end
|
|
28
|
+
|
|
29
|
+
@interface RNConfigurationSubscriber : NSObject <ConfigurationSubscriber>
|
|
30
|
+
@property (nonatomic, weak) DynatraceRNBridge* bridge;
|
|
31
|
+
- (instancetype)initWithBridge:(DynatraceRNBridge*)bridge;
|
|
32
|
+
@end
|
|
33
|
+
|
|
34
|
+
@implementation RNConfigurationSubscriber
|
|
35
|
+
|
|
36
|
+
- (instancetype)initWithBridge:(DynatraceRNBridge*)bridge
|
|
37
|
+
{
|
|
38
|
+
self = [super init];
|
|
39
|
+
if (self) {
|
|
40
|
+
_bridge = bridge;
|
|
41
|
+
}
|
|
42
|
+
return self;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
- (void)notifyWithConfiguration:(NSDictionary<NSString*, id>*)configuration
|
|
46
|
+
{
|
|
47
|
+
DynatraceRNBridge* bridge = self.bridge;
|
|
48
|
+
if (bridge == nil) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
[bridge handleRuntimeConfiguration:configuration];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@end
|
|
55
|
+
|
|
22
56
|
@implementation DynatraceRNBridge
|
|
23
57
|
|
|
24
58
|
NSMutableDictionary *actionDict;
|
|
@@ -37,6 +71,7 @@ NSString *const DataCollectionUserBehavior = @"USER_BEHAVIOR";
|
|
|
37
71
|
* Emitting app start event with this identifier
|
|
38
72
|
*/
|
|
39
73
|
NSString *const EmitAppMeasurementsIdentifier = @"dynatraceAppStartMeasurements";
|
|
74
|
+
NSString *const EmitDynatraceConfiguration = @"dynatraceConfiguration";
|
|
40
75
|
|
|
41
76
|
// All types which are interesting for us
|
|
42
77
|
NSString *const DownloadStart = @"downloadStart";
|
|
@@ -71,6 +106,11 @@ int64_t runJSBundleStartTime;
|
|
|
71
106
|
*/
|
|
72
107
|
int64_t runJSBundleEndTime;
|
|
73
108
|
|
|
109
|
+
// Runtime configuration (remote config)
|
|
110
|
+
static bool remoteConfigSubscribed;
|
|
111
|
+
static NSDictionary<NSString*, id>* lastRuntimeConfiguration;
|
|
112
|
+
static RNConfigurationSubscriber* configurationSubscriber;
|
|
113
|
+
|
|
74
114
|
RCT_EXPORT_MODULE(DynatraceBridge);
|
|
75
115
|
|
|
76
116
|
- (instancetype) init
|
|
@@ -83,6 +123,11 @@ RCT_EXPORT_MODULE(DynatraceBridge);
|
|
|
83
123
|
contentAppeared = -1;
|
|
84
124
|
runJSBundleStartTime = -1;
|
|
85
125
|
runJSBundleEndTime = -1;
|
|
126
|
+
|
|
127
|
+
remoteConfigSubscribed = NO;
|
|
128
|
+
lastRuntimeConfiguration = nil;
|
|
129
|
+
configurationSubscriber = [[RNConfigurationSubscriber alloc] initWithBridge:self];
|
|
130
|
+
|
|
86
131
|
registerLogTaggedMarkerCallbacks();
|
|
87
132
|
}
|
|
88
133
|
return self;
|
|
@@ -127,7 +172,7 @@ int64_t getRunJSBundleEndTime() {
|
|
|
127
172
|
}
|
|
128
173
|
|
|
129
174
|
- (NSArray<NSString *> *)supportedEvents {
|
|
130
|
-
return @[EmitAppMeasurementsIdentifier];
|
|
175
|
+
return @[EmitAppMeasurementsIdentifier, EmitDynatraceConfiguration];
|
|
131
176
|
}
|
|
132
177
|
|
|
133
178
|
int64_t GetTimestampUnix()
|
|
@@ -148,13 +193,13 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
|
|
|
148
193
|
using namespace facebook::react::ReactMarker;
|
|
149
194
|
auto logTaggedMarkerCommon = [](const ReactMarkerId markerId, const char* tag, auto previousLogTaggedMarker) {
|
|
150
195
|
if (previousLogTaggedMarker) {
|
|
151
|
-
previousLogTaggedMarker(markerId, tag);
|
|
196
|
+
previousLogTaggedMarker(markerId, tag);
|
|
152
197
|
}
|
|
153
198
|
|
|
154
199
|
if (markerId == RUN_JS_BUNDLE_START) {
|
|
155
|
-
runJSBundleStartTime = GetTimestampUnix();
|
|
200
|
+
runJSBundleStartTime = GetTimestampUnix();
|
|
156
201
|
} else if (markerId == RUN_JS_BUNDLE_STOP) {
|
|
157
|
-
runJSBundleEndTime = GetTimestampUnix();
|
|
202
|
+
runJSBundleEndTime = GetTimestampUnix();
|
|
158
203
|
}
|
|
159
204
|
};
|
|
160
205
|
|
|
@@ -182,7 +227,7 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
|
|
|
182
227
|
|
|
183
228
|
- (BOOL)isReady
|
|
184
229
|
{
|
|
185
|
-
return contentAppeared != -1 && getRunJSBundleEndTime() != -1;
|
|
230
|
+
return contentAppeared != -1 && getRunJSBundleEndTime() != -1;
|
|
186
231
|
}
|
|
187
232
|
|
|
188
233
|
- (void) contentAppeared
|
|
@@ -198,13 +243,13 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
|
|
|
198
243
|
{
|
|
199
244
|
if (!didEmit && hasListeners && [self isReady]) {
|
|
200
245
|
didEmit = YES;
|
|
201
|
-
|
|
246
|
+
|
|
202
247
|
NSMutableDictionary<NSString*, NSNumber*> *appStartMeasurements = [[NSMutableDictionary alloc] init];
|
|
203
|
-
|
|
248
|
+
|
|
204
249
|
[appStartMeasurements setObject:[self correctionOfTimestamp:getRunJSBundleStartTime()] forKey:RunJSBundleStart];
|
|
205
250
|
[appStartMeasurements setObject:[self correctionOfTimestamp:getRunJSBundleEndTime()] forKey:RunJSBundleEnd];
|
|
206
251
|
[appStartMeasurements setObject:[NSNumber numberWithLongLong:contentAppeared] forKey:ContentAppeared];
|
|
207
|
-
|
|
252
|
+
|
|
208
253
|
if (hasListeners) {
|
|
209
254
|
[self sendEventWithName:EmitAppMeasurementsIdentifier body:appStartMeasurements];
|
|
210
255
|
}
|
|
@@ -238,6 +283,12 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
|
|
|
238
283
|
{
|
|
239
284
|
hasListeners = YES;
|
|
240
285
|
[self emitMeasurements];
|
|
286
|
+
|
|
287
|
+
[self setupRuntimeConfigurationListenerIfNeeded];
|
|
288
|
+
|
|
289
|
+
if (lastRuntimeConfiguration != nil) {
|
|
290
|
+
[self emitToJS:EmitDynatraceConfiguration body:lastRuntimeConfiguration];
|
|
291
|
+
}
|
|
241
292
|
}
|
|
242
293
|
|
|
243
294
|
/**
|
|
@@ -248,6 +299,39 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
|
|
|
248
299
|
hasListeners = NO;
|
|
249
300
|
}
|
|
250
301
|
|
|
302
|
+
- (void)setupRuntimeConfigurationListenerIfNeeded
|
|
303
|
+
{
|
|
304
|
+
if (remoteConfigSubscribed) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
remoteConfigSubscribed = YES;
|
|
308
|
+
[HybridBridge addConfigurationSubscriber:(id)configurationSubscriber];
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
- (void)emitToJS:(NSString*)event body:(id)body
|
|
312
|
+
{
|
|
313
|
+
if (self.bridge == nil) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
id payload = body == nil ? [NSNull null] : body;
|
|
318
|
+
|
|
319
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
320
|
+
[self.bridge.eventDispatcher sendDeviceEventWithName:event body:payload];
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
- (void)handleRuntimeConfiguration:(NSDictionary<NSString*, id>*)configuration
|
|
325
|
+
{
|
|
326
|
+
lastRuntimeConfiguration = configuration;
|
|
327
|
+
|
|
328
|
+
if (!hasListeners) {
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
[self emitToJS:EmitDynatraceConfiguration body:configuration];
|
|
333
|
+
}
|
|
334
|
+
|
|
251
335
|
/**
|
|
252
336
|
* Constants which are exported to the JS part
|
|
253
337
|
*/
|
|
@@ -265,9 +349,9 @@ RCT_EXPORT_METHOD(start:(NSDictionary *) options)
|
|
|
265
349
|
if (options == nil) {
|
|
266
350
|
return;
|
|
267
351
|
}
|
|
268
|
-
|
|
352
|
+
|
|
269
353
|
NSMutableDictionary<NSString*, id> *properties = [[NSMutableDictionary alloc] init];
|
|
270
|
-
|
|
354
|
+
|
|
271
355
|
if (options[@"applicationId"] != NULL) {
|
|
272
356
|
properties[@"DTXApplicationID"] = options[@"applicationId"];
|
|
273
357
|
}
|
|
@@ -279,11 +363,11 @@ RCT_EXPORT_METHOD(start:(NSDictionary *) options)
|
|
|
279
363
|
if (options[@"userOptIn"] != NULL && [[options valueForKey:@"userOptIn"] isEqual: @(YES)]) {
|
|
280
364
|
properties[@"DTXUserOptIn"] = @YES;
|
|
281
365
|
}
|
|
282
|
-
|
|
366
|
+
|
|
283
367
|
if (options[@"reportCrash"] != NULL && [[options valueForKey:@"reportCrash"] isEqual: @(NO)]) {
|
|
284
368
|
properties[@"DTXCrashReportingEnabled"] = @NO;
|
|
285
369
|
}
|
|
286
|
-
|
|
370
|
+
|
|
287
371
|
if (options[@"logLevel"] != NULL && [((NSNumber *) options[@"logLevel"]) intValue] == 0){
|
|
288
372
|
properties[@"DTXLogLevel"] = @"ALL";
|
|
289
373
|
}
|
|
@@ -309,7 +393,7 @@ RCT_EXPORT_METHOD(enterManualAction:(NSString *)name key:(nonnull NSString *)key
|
|
|
309
393
|
if ([self shouldWorkOnIosWithPlatform: platform])
|
|
310
394
|
{
|
|
311
395
|
DTXAction *action = [DTXAction enterActionWithName:name];
|
|
312
|
-
|
|
396
|
+
|
|
313
397
|
if (action)
|
|
314
398
|
{
|
|
315
399
|
[actionDict setObject:action forKey:key];
|
|
@@ -326,7 +410,7 @@ RCT_EXPORT_METHOD(enterManualActionWithParent:(NSString *)name key:(nonnull NSSt
|
|
|
326
410
|
if (parentAction != nil)
|
|
327
411
|
{
|
|
328
412
|
DTXAction *childAction = [DTXAction enterActionWithName:name parentAction:parentAction];
|
|
329
|
-
|
|
413
|
+
|
|
330
414
|
if (childAction)
|
|
331
415
|
{
|
|
332
416
|
[actionDict setObject:childAction forKey:key];
|
|
@@ -378,11 +462,6 @@ RCT_EXPORT_METHOD(startView: (NSString *) name)
|
|
|
378
462
|
[Dynatrace startViewWithName:name];
|
|
379
463
|
}
|
|
380
464
|
|
|
381
|
-
RCT_EXPORT_METHOD(stopView)
|
|
382
|
-
{
|
|
383
|
-
[Dynatrace stopView];
|
|
384
|
-
}
|
|
385
|
-
|
|
386
465
|
RCT_EXPORT_METHOD(reportErrorWithoutStacktrace:(NSString *)errorName errorCode:(nonnull NSNumber *)errorCode platform: (NSString *) platform)
|
|
387
466
|
{
|
|
388
467
|
if ([self shouldWorkOnIosWithPlatform: platform])
|
|
@@ -406,11 +485,11 @@ RCT_EXPORT_METHOD(reportCrash:(NSString *)errorName errorReason:(NSString *)erro
|
|
|
406
485
|
if ([self shouldWorkOnIosWithPlatform: platform])
|
|
407
486
|
{
|
|
408
487
|
if(isRealError){
|
|
409
|
-
[DTXAction reportExternalCrashForPlatformType:DTXActionPlatformJavaScript crashName:errorName reason:errorReason stacktrace:stacktrace];
|
|
488
|
+
[DTXAction reportExternalCrashForPlatformType:DTXActionPlatformJavaScript crashName:errorName reason:errorReason stacktrace:stacktrace];
|
|
410
489
|
}else{
|
|
411
490
|
[DTXAction reportExternalCrashForPlatformType:DTXActionPlatformCustom crashName:errorName reason:errorReason stacktrace:stacktrace];
|
|
412
491
|
}
|
|
413
|
-
|
|
492
|
+
|
|
414
493
|
// Always end the session as the iOS agent has no troubles with this behavior
|
|
415
494
|
[Dynatrace endVisit];
|
|
416
495
|
}
|
|
@@ -488,7 +567,6 @@ RCT_EXPORT_METHOD(startWebRequestTiming:(NSString*) requestTag url:(NSString*) u
|
|
|
488
567
|
[timing startWebRequestTiming];
|
|
489
568
|
}
|
|
490
569
|
}
|
|
491
|
-
|
|
492
570
|
}
|
|
493
571
|
|
|
494
572
|
- (void)stopWebRequestTimingHelper:(NSString*) requestTag url:(NSString*)url responseCode:(nonnull NSNumber*) responseCode responseMessage:(NSString*)responseMessage bytesSent:(nonnull NSNumber*)bytesSent bytesReceived:(nonnull NSNumber*)bytesReceived
|
|
@@ -590,7 +668,7 @@ RCT_EXPORT_METHOD(getDataCollectionLevel:(NSString *) platform findEventsWithRes
|
|
|
590
668
|
if ([self shouldWorkOnIosWithPlatform: platform])
|
|
591
669
|
{
|
|
592
670
|
int i = [Dynatrace dataCollectionLevel];
|
|
593
|
-
|
|
671
|
+
|
|
594
672
|
if(i == DTX_DataCollectionUserBehavior){
|
|
595
673
|
resolve(DataCollectionUserBehavior);
|
|
596
674
|
}else if(i == DTX_DataCollectionPerformance){
|
|
@@ -633,7 +711,7 @@ RCT_EXPORT_METHOD(getUserPrivacyOptions:(NSString *) platform findEventsWithReso
|
|
|
633
711
|
{
|
|
634
712
|
id<DTXUserPrivacyOptions> privacyConfig = [Dynatrace userPrivacyOptions];
|
|
635
713
|
NSString * level;
|
|
636
|
-
|
|
714
|
+
|
|
637
715
|
if(privacyConfig.dataCollectionLevel == DTX_DataCollectionUserBehavior){
|
|
638
716
|
level = DataCollectionUserBehavior;
|
|
639
717
|
}else if(privacyConfig.dataCollectionLevel == DTX_DataCollectionPerformance){
|
|
@@ -653,7 +731,7 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
|
|
|
653
731
|
if ([self shouldWorkOnIosWithPlatform: platform])
|
|
654
732
|
{
|
|
655
733
|
id<DTXUserPrivacyOptions> privacyConfig = [Dynatrace userPrivacyOptions];
|
|
656
|
-
|
|
734
|
+
|
|
657
735
|
if([[userPrivacyOptions valueForKey:@"_dataCollectionLevel"] isEqualToString: DataCollectionPerformance]){
|
|
658
736
|
privacyConfig.dataCollectionLevel = DTX_DataCollectionPerformance;
|
|
659
737
|
}else if([[userPrivacyOptions valueForKey:@"_dataCollectionLevel"] isEqualToString: DataCollectionUserBehavior]){
|
|
@@ -663,7 +741,7 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
|
|
|
663
741
|
} else {
|
|
664
742
|
// do nothing and keep current value
|
|
665
743
|
}
|
|
666
|
-
|
|
744
|
+
|
|
667
745
|
if ([[userPrivacyOptions valueForKey:@"_crashReportingOptedIn"] isEqual: @(YES)]) {
|
|
668
746
|
privacyConfig.crashReportingOptedIn = YES;
|
|
669
747
|
} else if ([[userPrivacyOptions valueForKey:@"_crashReportingOptedIn"] isEqual: @(NO)]) {
|
|
@@ -678,10 +756,29 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
|
|
|
678
756
|
}
|
|
679
757
|
}
|
|
680
758
|
|
|
759
|
+
RCT_EXPORT_METHOD(getCurrentConfiguration:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
760
|
+
{
|
|
761
|
+
if (lastRuntimeConfiguration != nil) {
|
|
762
|
+
resolve(lastRuntimeConfiguration);
|
|
763
|
+
} else {
|
|
764
|
+
resolve([NSNull null]);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
RCT_EXPORT_METHOD(startViewInternal:(NSDictionary<NSString*, id>*) fields)
|
|
769
|
+
{
|
|
770
|
+
[HybridBridge startView:fields];
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
RCT_EXPORT_METHOD(stopViewInternal)
|
|
774
|
+
{
|
|
775
|
+
[HybridBridge stopView];
|
|
776
|
+
}
|
|
777
|
+
|
|
681
778
|
- (void)newAction:(NSString *)name key:(nonnull NSString *)key parentAction:(DTXAction *)parentAction
|
|
682
779
|
{
|
|
683
780
|
DTXAction *action = [DTXAction integrateActionWithName:name];
|
|
684
|
-
|
|
781
|
+
|
|
685
782
|
if (action)
|
|
686
783
|
{
|
|
687
784
|
[actionDict setObject:action forKey:key];
|
|
@@ -693,7 +790,6 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
|
|
|
693
790
|
return [actionDict objectForKey:key];
|
|
694
791
|
}
|
|
695
792
|
|
|
696
|
-
|
|
697
793
|
+ (BOOL)requiresMainQueueSetup
|
|
698
794
|
{
|
|
699
795
|
return YES;
|
|
@@ -713,4 +809,4 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
|
|
|
713
809
|
}
|
|
714
810
|
#endif
|
|
715
811
|
|
|
716
|
-
@end
|
|
812
|
+
@end
|
package/lib/core/Dynatrace.js
CHANGED
|
@@ -338,22 +338,19 @@ exports.Dynatrace = {
|
|
|
338
338
|
},
|
|
339
339
|
addEventModifier: (eventModifier) => Dynatrace_1.Dynatrace.addEventModifier(eventModifier),
|
|
340
340
|
removeEventModifier: (eventModifier) => Dynatrace_1.Dynatrace.removeEventModifier(eventModifier),
|
|
341
|
-
sendEvent: (properties) => {
|
|
342
|
-
Dynatrace_1.Dynatrace.sendEvent(properties);
|
|
343
|
-
},
|
|
344
341
|
startView: (name) => {
|
|
345
342
|
Dynatrace_1.Dynatrace.startView(name);
|
|
346
343
|
},
|
|
347
|
-
|
|
348
|
-
Dynatrace_1.Dynatrace.
|
|
344
|
+
sendEvent: (customEvent) => {
|
|
345
|
+
Dynatrace_1.Dynatrace.sendEvent(customEvent);
|
|
349
346
|
},
|
|
350
|
-
sendSessionPropertyEvent: (
|
|
351
|
-
Dynatrace_1.Dynatrace.sendSessionPropertyEvent(
|
|
347
|
+
sendSessionPropertyEvent: (sessionPropertyEventData) => {
|
|
348
|
+
Dynatrace_1.Dynatrace.sendSessionPropertyEvent(sessionPropertyEventData);
|
|
352
349
|
},
|
|
353
|
-
sendExceptionEvent: (
|
|
354
|
-
Dynatrace_1.Dynatrace.sendExceptionEvent(
|
|
350
|
+
sendExceptionEvent: (exceptionEvent) => {
|
|
351
|
+
Dynatrace_1.Dynatrace.sendExceptionEvent(exceptionEvent);
|
|
355
352
|
},
|
|
356
|
-
sendHttpRequestEvent(
|
|
357
|
-
Dynatrace_1.Dynatrace.sendHttpRequestEvent(
|
|
353
|
+
sendHttpRequestEvent: (httpRequestEvent) => {
|
|
354
|
+
Dynatrace_1.Dynatrace.sendHttpRequestEvent(httpRequestEvent);
|
|
358
355
|
},
|
|
359
356
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ConfigurationHandler = void 0;
|
|
4
|
+
const RuntimeConfigurationObserver_1 = require("../../next/configuration/RuntimeConfigurationObserver");
|
|
4
5
|
const LogLevel_1 = require("../logging/LogLevel");
|
|
5
6
|
let _configuration;
|
|
6
7
|
exports.ConfigurationHandler = {
|
|
@@ -14,6 +15,8 @@ exports.ConfigurationHandler = {
|
|
|
14
15
|
_configuration.logLevel === LogLevel_1.LogLevel.Debug,
|
|
15
16
|
isLifecycleUpdateEnabled: () => _configuration.lifecycleUpdate,
|
|
16
17
|
isActionNamePrivacyEnabled: () => _configuration.actionNamePrivacy,
|
|
18
|
+
isGrailEnabled: () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration()['3rd_gen_enabled'],
|
|
19
|
+
isRuntimeConfigurationInitiated: () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.isInitiated(),
|
|
17
20
|
getBundleName: () => _configuration.bundleName,
|
|
18
21
|
getBundleVersion: () => _configuration.bundleVersion,
|
|
19
22
|
};
|
package/lib/next/Dynatrace.js
CHANGED
|
@@ -7,24 +7,41 @@ const EventCreator_1 = require("./events/EventCreator");
|
|
|
7
7
|
const EventPipeline_1 = require("./events/EventPipeline");
|
|
8
8
|
const EventTimestamp_1 = require("./events/EventTimestamp");
|
|
9
9
|
const EventModifierUtil_1 = require("./events/modifier/EventModifierUtil");
|
|
10
|
-
const SendEventValidation_1 = require("./events/modifier/SendEventValidation");
|
|
11
10
|
const TimestampProvider_1 = require("./provider/TimestampProvider");
|
|
11
|
+
const EventData_1 = require("./events/EventData");
|
|
12
|
+
const SessionPropertyEventData_1 = require("./events/SessionPropertyEventData");
|
|
13
|
+
const ExceptionEventData_1 = require("./events/ExceptionEventData");
|
|
14
|
+
const HttpRequestEventData_1 = require("./events/HttpRequestEventData");
|
|
15
|
+
const DynatraceArgValidators_1 = require("./DynatraceArgValidators");
|
|
12
16
|
class DynatraceImpl {
|
|
13
17
|
constructor(timestampProvider) {
|
|
14
18
|
this.timestampProvider = timestampProvider;
|
|
15
19
|
this.logger = new ConsoleLogger_1.ConsoleLogger('Dynatrace');
|
|
16
20
|
}
|
|
17
21
|
addEventModifier(eventModifier) {
|
|
22
|
+
if (!(0, DynatraceArgValidators_1.isEventModifier)(eventModifier)) {
|
|
23
|
+
this.logger.info('addEventModifier(eventModifier): eventModifier is not of type IEventModifier');
|
|
24
|
+
return {
|
|
25
|
+
modifyEvent: (event) => event,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
18
28
|
this.logger.debug('addEventModifier()');
|
|
19
29
|
return EventPipeline_1.EventPipeline.addEventModifier(eventModifier);
|
|
20
30
|
}
|
|
21
31
|
removeEventModifier(eventModifier) {
|
|
32
|
+
if (!(0, DynatraceArgValidators_1.isEventModifier)(eventModifier)) {
|
|
33
|
+
this.logger.info('removeEventModifier(eventModifier): eventModifier is not of type IEventModifier');
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
22
36
|
this.logger.debug('removeEventModifier()');
|
|
23
37
|
return EventPipeline_1.EventPipeline.removeEventModifier(eventModifier);
|
|
24
38
|
}
|
|
25
39
|
startView(name) {
|
|
40
|
+
if (typeof name !== 'string') {
|
|
41
|
+
this.logger.info(`startView(name): Name must be a string!`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
26
44
|
this.logger.debug(`startView(${name})`);
|
|
27
|
-
EventPipeline_1.EventPipeline.generateViewData(name);
|
|
28
45
|
if (name != null && name.length > 0) {
|
|
29
46
|
DynatraceBridge_1.DynatraceNative.startView(name);
|
|
30
47
|
}
|
|
@@ -32,11 +49,6 @@ class DynatraceImpl {
|
|
|
32
49
|
this.logger.debug(`startView(${name}): Name can't be used. Either empty or null!`);
|
|
33
50
|
}
|
|
34
51
|
}
|
|
35
|
-
stopView() {
|
|
36
|
-
this.logger.debug('stopView()');
|
|
37
|
-
EventPipeline_1.EventPipeline.releaseViewData();
|
|
38
|
-
DynatraceBridge_1.DynatraceNative.stopView();
|
|
39
|
-
}
|
|
40
52
|
reportCrash(crash, isApiReported, isFatal = true) {
|
|
41
53
|
this.logger.debug(`reportCrash(${JSON.stringify(crash)}, ${isFatal})`);
|
|
42
54
|
const eventTimestamp = new EventTimestamp_1.EventTimestamp(this.timestampProvider);
|
|
@@ -67,42 +79,47 @@ class DynatraceImpl {
|
|
|
67
79
|
}
|
|
68
80
|
EventPipeline_1.EventPipeline.insertEvent(event);
|
|
69
81
|
}
|
|
70
|
-
sendExceptionEvent(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
eventValidated
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
sendExceptionEvent(exceptionEventData) {
|
|
83
|
+
if (!(exceptionEventData instanceof ExceptionEventData_1.default)) {
|
|
84
|
+
this.logger.info('sendExceptionEvent(exceptionEventData): exceptionEventData is not of type ExceptionEventData');
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
this.logger.debug('sendExceptionEvent(exceptionEventData)');
|
|
88
|
+
const eventValidated = exceptionEventData.toJSON();
|
|
89
|
+
if (eventValidated !== null) {
|
|
90
|
+
EventPipeline_1.EventPipeline.insertEvent(eventValidated);
|
|
91
|
+
}
|
|
80
92
|
}
|
|
81
|
-
sendEvent(
|
|
82
|
-
|
|
83
|
-
|
|
93
|
+
sendEvent(eventData) {
|
|
94
|
+
if (!(eventData instanceof EventData_1.default)) {
|
|
95
|
+
this.logger.info('sendEvent(eventData): eventData is not of type EventData');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
this.logger.debug('sendEvent(eventData)');
|
|
99
|
+
const eventValidated = eventData.toJSON();
|
|
84
100
|
if (eventValidated !== null) {
|
|
85
|
-
(0, EventModifierUtil_1.flagEventProperties)(eventValidated);
|
|
86
|
-
(0, EventModifierUtil_1.addIsApiReported)(eventValidated);
|
|
87
101
|
EventPipeline_1.EventPipeline.insertEvent(eventValidated);
|
|
88
102
|
}
|
|
89
103
|
}
|
|
90
|
-
sendSessionPropertyEvent(
|
|
91
|
-
|
|
92
|
-
|
|
104
|
+
sendSessionPropertyEvent(sessionPropertyEventData) {
|
|
105
|
+
if (!(sessionPropertyEventData instanceof SessionPropertyEventData_1.default)) {
|
|
106
|
+
this.logger.info('sendSessionPropertyEvent(SessionPropertyEventData): sessionPropertyEventData is not of type SessionPropertyEventData');
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
this.logger.debug('sendSessionPropertyEvent(SessionPropertyEventData)');
|
|
110
|
+
const eventValidated = sessionPropertyEventData.toJSON();
|
|
93
111
|
if (eventValidated !== null) {
|
|
94
|
-
if ((0, EventModifierUtil_1.containSessionProperties)(eventValidated)) {
|
|
95
|
-
eventValidated["characteristics.has_session_properties"] = true;
|
|
96
|
-
}
|
|
97
|
-
(0, EventModifierUtil_1.addIsApiReported)(eventValidated);
|
|
98
112
|
EventPipeline_1.EventPipeline.insertEvent(eventValidated);
|
|
99
113
|
}
|
|
100
114
|
}
|
|
101
|
-
sendHttpRequestEvent(
|
|
102
|
-
|
|
103
|
-
|
|
115
|
+
sendHttpRequestEvent(httpRequestEvent) {
|
|
116
|
+
if (!(httpRequestEvent instanceof HttpRequestEventData_1.default)) {
|
|
117
|
+
this.logger.info('sendHttpRequestEvent(HttpRequestEventData): httpRequestEvent is not of type HttpRequestEventData');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
this.logger.debug('sendHttpRequestEvent(HttpRequestEventData)');
|
|
121
|
+
const sanitizedEvent = httpRequestEvent.toJSON();
|
|
104
122
|
if (sanitizedEvent !== null) {
|
|
105
|
-
(0, EventModifierUtil_1.flagEventProperties)(sanitizedEvent);
|
|
106
123
|
EventPipeline_1.EventPipeline.insertEvent(sanitizedEvent);
|
|
107
124
|
}
|
|
108
125
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isEventModifier = void 0;
|
|
4
|
+
function isEventModifier(eventModifier) {
|
|
5
|
+
return (typeof eventModifier === 'object' &&
|
|
6
|
+
eventModifier !== null &&
|
|
7
|
+
'modifyEvent' in eventModifier &&
|
|
8
|
+
typeof eventModifier.modifyEvent === 'function');
|
|
9
|
+
}
|
|
10
|
+
exports.isEventModifier = isEventModifier;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addListenerOnce = exports.createEmitterNativeOnly = exports.createEmitterRuntimeConfig = void 0;
|
|
4
|
+
const react_native_1 = require("react-native");
|
|
5
|
+
const DynatraceBridge_1 = require("../core/DynatraceBridge");
|
|
6
|
+
const isEmptyObject = (value) => {
|
|
7
|
+
if (value == null) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
if (typeof value !== 'object') {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
return Object.keys(value).length === 0;
|
|
14
|
+
};
|
|
15
|
+
const createEmitterRuntimeConfig = () => {
|
|
16
|
+
if (react_native_1.Platform.OS === 'ios' && isEmptyObject(DynatraceBridge_1.DynatraceNative || {})) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const iosModule = react_native_1.NativeModules.DynatraceBridge;
|
|
20
|
+
const nativeEmitterModule = react_native_1.Platform.OS === 'android' ? DynatraceBridge_1.DynatraceNative : iosModule;
|
|
21
|
+
return new react_native_1.NativeEventEmitter(nativeEmitterModule);
|
|
22
|
+
};
|
|
23
|
+
exports.createEmitterRuntimeConfig = createEmitterRuntimeConfig;
|
|
24
|
+
const createEmitterNativeOnly = () => new react_native_1.NativeEventEmitter(DynatraceBridge_1.DynatraceNative);
|
|
25
|
+
exports.createEmitterNativeOnly = createEmitterNativeOnly;
|
|
26
|
+
const addListenerOnce = (emitter, current, eventName, handler) => {
|
|
27
|
+
if (current != null) {
|
|
28
|
+
return current;
|
|
29
|
+
}
|
|
30
|
+
if (emitter == null) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return emitter.addListener(eventName, handler);
|
|
34
|
+
};
|
|
35
|
+
exports.addListenerOnce = addListenerOnce;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AppStartObserver = void 0;
|
|
4
|
-
const react_native_1 = require("react-native");
|
|
5
4
|
const EventCreator_1 = require("../events/EventCreator");
|
|
6
5
|
const ConsoleLogger_1 = require("../../core/logging/ConsoleLogger");
|
|
7
|
-
const DynatraceBridge_1 = require("../../core/DynatraceBridge");
|
|
8
6
|
const EventPipeline_1 = require("../events/EventPipeline");
|
|
7
|
+
const DynatraceEventBus_1 = require("../DynatraceEventBus");
|
|
9
8
|
class AppStartObserverImpl {
|
|
10
9
|
constructor() {
|
|
11
10
|
this.EMIT_APP_START = 'dynatraceAppStartMeasurements';
|
|
@@ -15,7 +14,7 @@ class AppStartObserverImpl {
|
|
|
15
14
|
call() {
|
|
16
15
|
}
|
|
17
16
|
setupNativeEventEmitter() {
|
|
18
|
-
const emitter =
|
|
17
|
+
const emitter = (0, DynatraceEventBus_1.createEmitterNativeOnly)();
|
|
19
18
|
emitter.addListener(this.EMIT_APP_START, (data) => {
|
|
20
19
|
this.logger.debug(`emitter(${JSON.stringify(data)}})`);
|
|
21
20
|
const appStartEvent = (0, EventCreator_1.createAppStartEvent)(data);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateDefaultConfiguration = void 0;
|
|
4
|
+
const generateDefaultConfiguration = () => ({
|
|
5
|
+
'3rd_gen_enabled': true,
|
|
6
|
+
});
|
|
7
|
+
exports.generateDefaultConfiguration = generateDefaultConfiguration;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RuntimeConfigurationObserver = void 0;
|
|
4
|
+
const DynatraceBridge_1 = require("../../core/DynatraceBridge");
|
|
5
|
+
const DynatraceEventBus_1 = require("../DynatraceEventBus");
|
|
6
|
+
const INativeRuntimeConfiguration_1 = require("./INativeRuntimeConfiguration");
|
|
7
|
+
class RuntimeConfigurationObserverImpl {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.EMIT_CONFIGURATION = 'dynatraceConfiguration';
|
|
10
|
+
this.runtimeConfiguration = (0, INativeRuntimeConfiguration_1.generateDefaultConfiguration)();
|
|
11
|
+
this.observerIsInitiated = false;
|
|
12
|
+
this.subscription = null;
|
|
13
|
+
this.setupNativeEventEmitter();
|
|
14
|
+
}
|
|
15
|
+
getCurrentRuntimeConfiguration() {
|
|
16
|
+
return this.runtimeConfiguration;
|
|
17
|
+
}
|
|
18
|
+
isInitiated() {
|
|
19
|
+
return this.observerIsInitiated;
|
|
20
|
+
}
|
|
21
|
+
setupNativeEventEmitter() {
|
|
22
|
+
const emitter = (0, DynatraceEventBus_1.createEmitterRuntimeConfig)();
|
|
23
|
+
this.subscription = (0, DynatraceEventBus_1.addListenerOnce)(emitter, this.subscription, this.EMIT_CONFIGURATION, (data) => {
|
|
24
|
+
this.runtimeConfiguration = data;
|
|
25
|
+
this.observerIsInitiated = true;
|
|
26
|
+
});
|
|
27
|
+
if (typeof DynatraceBridge_1.DynatraceNative.getCurrentConfiguration === 'function') {
|
|
28
|
+
Promise.resolve(DynatraceBridge_1.DynatraceNative.getCurrentConfiguration())
|
|
29
|
+
.then((data) => {
|
|
30
|
+
if (data) {
|
|
31
|
+
this.runtimeConfiguration = data;
|
|
32
|
+
this.observerIsInitiated = true;
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
.catch(() => {
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.RuntimeConfigurationObserver = new RuntimeConfigurationObserverImpl();
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.includeIfTrue = exports.includeIfDefined = void 0;
|
|
4
|
+
const includeIfDefined = (key, value) => (value !== undefined ? { [key]: value } : {});
|
|
5
|
+
exports.includeIfDefined = includeIfDefined;
|
|
6
|
+
const includeIfTrue = (key, value) => value === true ? { [key]: value } : {};
|
|
7
|
+
exports.includeIfTrue = includeIfTrue;
|