@coralogix/react-native-plugin 0.3.3 → 0.5.0
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/CHANGELOG.md +23 -0
- package/CxSdk.podspec +3 -3
- package/README.md +139 -0
- package/android/build.gradle +13 -1
- package/android/src/main/java/com/cxsdk/CxSdkModule.kt +151 -4
- package/android/src/main/java/com/cxsdk/RUMClient.kt +7 -0
- package/android/src/test/kotlin/com/cxsdk/ExtractOtelIdsTest.kt +49 -0
- package/index.cjs.js +195 -4
- package/index.esm.js +193 -5
- package/ios/CxSdk.mm +21 -0
- package/ios/CxSdk.swift +123 -1
- package/package.json +1 -1
- package/src/custom-spans/CoralogixCustomSpan.d.ts +9 -0
- package/src/custom-spans/CoralogixCustomTracer.d.ts +18 -0
- package/src/custom-spans/CoralogixGlobalSpan.d.ts +20 -0
- package/src/custom-spans/CustomSpanBridge.d.ts +11 -0
- package/src/custom-spans/CustomSpanRegistry.d.ts +12 -0
- package/src/index.d.ts +16 -1
- package/src/model/CoralogixDomain.d.ts +1 -0
- package/src/model/CoralogixOtelWebType.d.ts +20 -1
- package/src/model/Types.d.ts +23 -0
package/index.cjs.js
CHANGED
|
@@ -27,6 +27,20 @@ let CoralogixLogSeverity = /*#__PURE__*/function (CoralogixLogSeverity) {
|
|
|
27
27
|
return CoralogixLogSeverity;
|
|
28
28
|
}({});
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Instrumentation names that can be excluded from a custom tracer's span context.
|
|
32
|
+
* Pass one or more values to `getCustomTracer()` to prevent those event types from
|
|
33
|
+
* being linked to spans created by that tracer.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Event categories that can opt out of session sampling. When the session is
|
|
38
|
+
* sampled out, events whose category is listed in `excludeFromSampling` are still
|
|
39
|
+
* emitted; everything else is dropped. Mirrors the iOS/Android native enums.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
/** OTLP JSON-format trace data delivered to the `tracesExporter` callback. */
|
|
43
|
+
|
|
30
44
|
const ERROR_INSTRUMENTATION_NAME = 'errors';
|
|
31
45
|
const ERROR_INSTRUMENTATION_VERSION = '1';
|
|
32
46
|
|
|
@@ -523,7 +537,7 @@ function stopJsRefreshRateSampler() {
|
|
|
523
537
|
appStateSub = null;
|
|
524
538
|
}
|
|
525
539
|
|
|
526
|
-
var version = "0.
|
|
540
|
+
var version = "0.5.0";
|
|
527
541
|
var pkg = {
|
|
528
542
|
version: version};
|
|
529
543
|
|
|
@@ -561,6 +575,128 @@ class Logger {
|
|
|
561
575
|
}
|
|
562
576
|
const logger = new Logger();
|
|
563
577
|
|
|
578
|
+
let activeGlobalSpanId = null;
|
|
579
|
+
const spanTraceIds = new Map();
|
|
580
|
+
let ignoredInstruments = new Set();
|
|
581
|
+
const CustomSpanRegistry = {
|
|
582
|
+
getActive: () => activeGlobalSpanId,
|
|
583
|
+
setActive: id => {
|
|
584
|
+
activeGlobalSpanId = id;
|
|
585
|
+
},
|
|
586
|
+
clearActive: () => {
|
|
587
|
+
activeGlobalSpanId = null;
|
|
588
|
+
},
|
|
589
|
+
registerSpan: (spanId, traceId) => {
|
|
590
|
+
spanTraceIds.set(spanId, traceId);
|
|
591
|
+
},
|
|
592
|
+
unregisterSpan: spanId => {
|
|
593
|
+
spanTraceIds.delete(spanId);
|
|
594
|
+
},
|
|
595
|
+
getTraceId: spanId => spanTraceIds.get(spanId),
|
|
596
|
+
setIgnoredInstruments: set => {
|
|
597
|
+
ignoredInstruments = set;
|
|
598
|
+
},
|
|
599
|
+
getIgnoredInstruments: () => ignoredInstruments,
|
|
600
|
+
clear: () => {
|
|
601
|
+
activeGlobalSpanId = null;
|
|
602
|
+
spanTraceIds.clear();
|
|
603
|
+
ignoredInstruments.clear();
|
|
604
|
+
}
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
/** A child span nested under a {@link CoralogixGlobalSpan}. */
|
|
608
|
+
class CoralogixCustomSpan {
|
|
609
|
+
constructor(spanId, traceId, bridge) {
|
|
610
|
+
this.spanId = void 0;
|
|
611
|
+
this.traceId = void 0;
|
|
612
|
+
this.bridge = void 0;
|
|
613
|
+
this.spanId = spanId;
|
|
614
|
+
this.traceId = traceId;
|
|
615
|
+
this.bridge = bridge;
|
|
616
|
+
}
|
|
617
|
+
async endSpan() {
|
|
618
|
+
CustomSpanRegistry.unregisterSpan(this.spanId);
|
|
619
|
+
await this.bridge.endSpan(this.spanId);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/** A root-level custom span. All child spans and `withContext` network calls share its traceId. */
|
|
624
|
+
class CoralogixGlobalSpan {
|
|
625
|
+
constructor(spanId, traceId, bridge) {
|
|
626
|
+
this.spanId = void 0;
|
|
627
|
+
this.traceId = void 0;
|
|
628
|
+
this.bridge = void 0;
|
|
629
|
+
this.spanId = spanId;
|
|
630
|
+
this.traceId = traceId;
|
|
631
|
+
this.bridge = bridge;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/** Creates a child span nested under this global span. */
|
|
635
|
+
async startCustomSpan(name, labels) {
|
|
636
|
+
const raw = await this.bridge.startCustomSpan(this.spanId, name, labels != null ? labels : null);
|
|
637
|
+
if (!raw) return null;
|
|
638
|
+
CustomSpanRegistry.registerSpan(raw.spanId, raw.traceId);
|
|
639
|
+
return new CoralogixCustomSpan(raw.spanId, raw.traceId, this.bridge);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Runs fn() with this span set as the active global span for the duration of
|
|
644
|
+
* the returned promise. The active span ID remains set throughout the full
|
|
645
|
+
* async chain — including code after intermediate awaits — because we await
|
|
646
|
+
* fn() before clearing. Only detached callbacks (e.g. setTimeout) that fire
|
|
647
|
+
* after withContext resolves won't be linked.
|
|
648
|
+
*/
|
|
649
|
+
async withContext(fn) {
|
|
650
|
+
const prev = CustomSpanRegistry.getActive();
|
|
651
|
+
CustomSpanRegistry.setActive(this.spanId);
|
|
652
|
+
try {
|
|
653
|
+
return await fn();
|
|
654
|
+
} finally {
|
|
655
|
+
if (prev !== null) {
|
|
656
|
+
CustomSpanRegistry.setActive(prev);
|
|
657
|
+
} else {
|
|
658
|
+
CustomSpanRegistry.clearActive();
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
async endSpan() {
|
|
663
|
+
CustomSpanRegistry.unregisterSpan(this.spanId);
|
|
664
|
+
if (CustomSpanRegistry.getActive() === this.spanId) {
|
|
665
|
+
CustomSpanRegistry.clearActive();
|
|
666
|
+
}
|
|
667
|
+
await this.bridge.endSpan(this.spanId);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Entry point for manual RUM tracing. Obtain an instance via `CoralogixRum.getCustomTracer()`.
|
|
673
|
+
* The `ignoredInstruments` list controls which auto-instrumented events are NOT linked to spans
|
|
674
|
+
* created by this tracer (e.g. passing `['networkRequests']` keeps network spans independent).
|
|
675
|
+
*/
|
|
676
|
+
class CoralogixCustomTracer {
|
|
677
|
+
constructor(ignoredInstruments, bridge) {
|
|
678
|
+
this.ignoredInstruments = void 0;
|
|
679
|
+
this.bridge = void 0;
|
|
680
|
+
this.ignoredInstruments = ignoredInstruments;
|
|
681
|
+
this.bridge = bridge;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Starts a new global (root) span. Returns `null` if a global span is already active —
|
|
686
|
+
* only one global span may exist at a time across the entire app.
|
|
687
|
+
*/
|
|
688
|
+
async startGlobalSpan(name, labels) {
|
|
689
|
+
const raw = await this.bridge.startGlobalSpan(name, labels != null ? labels : null, this.ignoredInstruments);
|
|
690
|
+
if (!raw) {
|
|
691
|
+
logger.debug('CoralogixCustomTracer: startGlobalSpan returned null — check that the SDK is initialized, traceParentInHeader is enabled, and no other global span is already active');
|
|
692
|
+
return null;
|
|
693
|
+
}
|
|
694
|
+
CustomSpanRegistry.registerSpan(raw.spanId, raw.traceId);
|
|
695
|
+
CustomSpanRegistry.setIgnoredInstruments(new Set(this.ignoredInstruments));
|
|
696
|
+
return new CoralogixGlobalSpan(raw.spanId, raw.traceId, this.bridge);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
564
700
|
const CORALOGIX_LOGS_URL_SUFFIX = '/browser/v1beta/logs';
|
|
565
701
|
const CORALOGIX_RECORDING_URL_SUFFIX = '/sessionrecording';
|
|
566
702
|
const OPTIONS_DEFAULTS = {
|
|
@@ -838,6 +974,7 @@ let CoralogixDomain = /*#__PURE__*/function (CoralogixDomain) {
|
|
|
838
974
|
CoralogixDomain["AP1"] = "AP1";
|
|
839
975
|
CoralogixDomain["AP2"] = "AP2";
|
|
840
976
|
CoralogixDomain["AP3"] = "AP3";
|
|
977
|
+
CoralogixDomain["US3"] = "US3";
|
|
841
978
|
CoralogixDomain["STAGING"] = "staging";
|
|
842
979
|
return CoralogixDomain;
|
|
843
980
|
}({});
|
|
@@ -847,6 +984,7 @@ const LINKING_ERROR = `The package 'cx-plugin' doesn't seem to be linked. Make s
|
|
|
847
984
|
default: ''
|
|
848
985
|
}) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n';
|
|
849
986
|
let beforeSendCallback;
|
|
987
|
+
let tracesExporterSubscription;
|
|
850
988
|
let _deregisterInstrumentations;
|
|
851
989
|
const CxSdk = reactNative.NativeModules.CxSdk ? reactNative.NativeModules.CxSdk : createErrorProxy(LINKING_ERROR);
|
|
852
990
|
function createErrorProxy(errorMessage) {
|
|
@@ -863,14 +1001,15 @@ const CoralogixRum = {
|
|
|
863
1001
|
return isInited;
|
|
864
1002
|
},
|
|
865
1003
|
init: async function (options) {
|
|
866
|
-
var _resolvedOptions$debu;
|
|
1004
|
+
var _resolvedOptions$debu, _resolvedOptions$excl, _resolvedOptions$excl2;
|
|
867
1005
|
if (isInited) {
|
|
868
1006
|
console.warn('[Coralogix React Native SDK] - already initialized');
|
|
869
1007
|
return;
|
|
870
1008
|
}
|
|
871
1009
|
const resolvedOptions = resolveCoralogixOtelWebConfig(options);
|
|
872
1010
|
logger.shouldLog = (_resolvedOptions$debu = resolvedOptions.debug) != null ? _resolvedOptions$debu : false;
|
|
873
|
-
|
|
1011
|
+
const hasExcludeOverrides = ((_resolvedOptions$excl = (_resolvedOptions$excl2 = resolvedOptions.excludeFromSampling) == null ? void 0 : _resolvedOptions$excl2.length) != null ? _resolvedOptions$excl : 0) > 0;
|
|
1012
|
+
if (!isSamplingOn(resolvedOptions.sessionSampleRate) && !hasExcludeOverrides) {
|
|
874
1013
|
logger.debug('CoralogixRum: Session tracking is disabled');
|
|
875
1014
|
return;
|
|
876
1015
|
}
|
|
@@ -886,10 +1025,28 @@ const CoralogixRum = {
|
|
|
886
1025
|
} else {
|
|
887
1026
|
finalOptions = resolvedOptions;
|
|
888
1027
|
}
|
|
1028
|
+
if (finalOptions.tracesExporter) {
|
|
1029
|
+
const callback = finalOptions.tracesExporter;
|
|
1030
|
+
tracesExporterSubscription = eventEmitter.addListener('onTracesExport', jsonString => {
|
|
1031
|
+
let data;
|
|
1032
|
+
try {
|
|
1033
|
+
data = JSON.parse(jsonString);
|
|
1034
|
+
} catch (e) {
|
|
1035
|
+
logger.warn('Error parsing onTracesExport payload:', e);
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
try {
|
|
1039
|
+
callback(data);
|
|
1040
|
+
} catch (e) {
|
|
1041
|
+
logger.warn('tracesExporter callback threw:', e);
|
|
1042
|
+
}
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
889
1045
|
await CxSdk.initialize(_extends({}, finalOptions, {
|
|
890
1046
|
frameworkVersion: pkg.version,
|
|
891
1047
|
networkExtraConfig: finalOptions.networkExtraConfig ? serializeNetworkCaptureRules(finalOptions.networkExtraConfig) : undefined,
|
|
892
|
-
hasBeforeSend: !!finalOptions.beforeSend
|
|
1048
|
+
hasBeforeSend: !!finalOptions.beforeSend,
|
|
1049
|
+
hasTracesExporter: !!finalOptions.tracesExporter
|
|
893
1050
|
}));
|
|
894
1051
|
isInited = true;
|
|
895
1052
|
},
|
|
@@ -901,6 +1058,10 @@ const CoralogixRum = {
|
|
|
901
1058
|
if (subscription) {
|
|
902
1059
|
subscription.remove();
|
|
903
1060
|
}
|
|
1061
|
+
if (tracesExporterSubscription) {
|
|
1062
|
+
tracesExporterSubscription.remove();
|
|
1063
|
+
tracesExporterSubscription = undefined;
|
|
1064
|
+
}
|
|
904
1065
|
isInited = false;
|
|
905
1066
|
_deregisterInstrumentations == null || _deregisterInstrumentations();
|
|
906
1067
|
_deregisterInstrumentations = undefined;
|
|
@@ -992,6 +1153,19 @@ const CoralogixRum = {
|
|
|
992
1153
|
reportNetworkRequest: details => {
|
|
993
1154
|
CxSdk.reportNetworkRequest(details);
|
|
994
1155
|
},
|
|
1156
|
+
/**
|
|
1157
|
+
* Returns a tracer for creating manual custom spans.
|
|
1158
|
+
* Pass `ignoredInstruments` to prevent specific auto-instrumented event types from being
|
|
1159
|
+
* linked to spans created by this tracer.
|
|
1160
|
+
*/
|
|
1161
|
+
getCustomTracer(ignoredInstruments = []) {
|
|
1162
|
+
const bridge = {
|
|
1163
|
+
startGlobalSpan: (name, labels, instruments) => CxSdk.startGlobalSpan(name, labels, instruments),
|
|
1164
|
+
startCustomSpan: (parentSpanId, name, labels) => CxSdk.startCustomSpan(parentSpanId, name, labels),
|
|
1165
|
+
endSpan: spanId => CxSdk.endSpan(spanId)
|
|
1166
|
+
};
|
|
1167
|
+
return new CoralogixCustomTracer(ignoredInstruments, bridge);
|
|
1168
|
+
},
|
|
995
1169
|
sendCustomMeasurement: measurement => {
|
|
996
1170
|
if (!isInited) {
|
|
997
1171
|
logger.debug('CoralogixRum must be initiated before sending custom measurements');
|
|
@@ -999,6 +1173,20 @@ const CoralogixRum = {
|
|
|
999
1173
|
}
|
|
1000
1174
|
CxSdk.sendCustomMeasurement(measurement);
|
|
1001
1175
|
},
|
|
1176
|
+
startTimeMeasure: (name, labels) => {
|
|
1177
|
+
if (!isInited) {
|
|
1178
|
+
logger.debug('CoralogixRum must be initiated before startTimeMeasure');
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
CxSdk.startTimeMeasure(name, labels != null ? labels : {});
|
|
1182
|
+
},
|
|
1183
|
+
endTimeMeasure: name => {
|
|
1184
|
+
if (!isInited) {
|
|
1185
|
+
logger.debug('CoralogixRum must be initiated before endTimeMeasure');
|
|
1186
|
+
return;
|
|
1187
|
+
}
|
|
1188
|
+
CxSdk.endTimeMeasure(name);
|
|
1189
|
+
},
|
|
1002
1190
|
reportError: (error, isCrash) => {
|
|
1003
1191
|
if (!isInited) {
|
|
1004
1192
|
logger.debug('CoralogixRum must be initiated before error reporting');
|
|
@@ -1221,7 +1409,10 @@ const subscription = eventEmitter.addListener('onBeforeSend', events => {
|
|
|
1221
1409
|
}
|
|
1222
1410
|
});
|
|
1223
1411
|
|
|
1412
|
+
exports.CoralogixCustomSpan = CoralogixCustomSpan;
|
|
1413
|
+
exports.CoralogixCustomTracer = CoralogixCustomTracer;
|
|
1224
1414
|
exports.CoralogixDomain = CoralogixDomain;
|
|
1415
|
+
exports.CoralogixGlobalSpan = CoralogixGlobalSpan;
|
|
1225
1416
|
exports.CoralogixLogSeverity = CoralogixLogSeverity;
|
|
1226
1417
|
exports.CoralogixRum = CoralogixRum;
|
|
1227
1418
|
exports.CxSdk = CxSdk;
|
package/index.esm.js
CHANGED
|
@@ -25,6 +25,20 @@ let CoralogixLogSeverity = /*#__PURE__*/function (CoralogixLogSeverity) {
|
|
|
25
25
|
return CoralogixLogSeverity;
|
|
26
26
|
}({});
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Instrumentation names that can be excluded from a custom tracer's span context.
|
|
30
|
+
* Pass one or more values to `getCustomTracer()` to prevent those event types from
|
|
31
|
+
* being linked to spans created by that tracer.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Event categories that can opt out of session sampling. When the session is
|
|
36
|
+
* sampled out, events whose category is listed in `excludeFromSampling` are still
|
|
37
|
+
* emitted; everything else is dropped. Mirrors the iOS/Android native enums.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/** OTLP JSON-format trace data delivered to the `tracesExporter` callback. */
|
|
41
|
+
|
|
28
42
|
const ERROR_INSTRUMENTATION_NAME = 'errors';
|
|
29
43
|
const ERROR_INSTRUMENTATION_VERSION = '1';
|
|
30
44
|
|
|
@@ -521,7 +535,7 @@ function stopJsRefreshRateSampler() {
|
|
|
521
535
|
appStateSub = null;
|
|
522
536
|
}
|
|
523
537
|
|
|
524
|
-
var version = "0.
|
|
538
|
+
var version = "0.5.0";
|
|
525
539
|
var pkg = {
|
|
526
540
|
version: version};
|
|
527
541
|
|
|
@@ -559,6 +573,128 @@ class Logger {
|
|
|
559
573
|
}
|
|
560
574
|
const logger = new Logger();
|
|
561
575
|
|
|
576
|
+
let activeGlobalSpanId = null;
|
|
577
|
+
const spanTraceIds = new Map();
|
|
578
|
+
let ignoredInstruments = new Set();
|
|
579
|
+
const CustomSpanRegistry = {
|
|
580
|
+
getActive: () => activeGlobalSpanId,
|
|
581
|
+
setActive: id => {
|
|
582
|
+
activeGlobalSpanId = id;
|
|
583
|
+
},
|
|
584
|
+
clearActive: () => {
|
|
585
|
+
activeGlobalSpanId = null;
|
|
586
|
+
},
|
|
587
|
+
registerSpan: (spanId, traceId) => {
|
|
588
|
+
spanTraceIds.set(spanId, traceId);
|
|
589
|
+
},
|
|
590
|
+
unregisterSpan: spanId => {
|
|
591
|
+
spanTraceIds.delete(spanId);
|
|
592
|
+
},
|
|
593
|
+
getTraceId: spanId => spanTraceIds.get(spanId),
|
|
594
|
+
setIgnoredInstruments: set => {
|
|
595
|
+
ignoredInstruments = set;
|
|
596
|
+
},
|
|
597
|
+
getIgnoredInstruments: () => ignoredInstruments,
|
|
598
|
+
clear: () => {
|
|
599
|
+
activeGlobalSpanId = null;
|
|
600
|
+
spanTraceIds.clear();
|
|
601
|
+
ignoredInstruments.clear();
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
/** A child span nested under a {@link CoralogixGlobalSpan}. */
|
|
606
|
+
class CoralogixCustomSpan {
|
|
607
|
+
constructor(spanId, traceId, bridge) {
|
|
608
|
+
this.spanId = void 0;
|
|
609
|
+
this.traceId = void 0;
|
|
610
|
+
this.bridge = void 0;
|
|
611
|
+
this.spanId = spanId;
|
|
612
|
+
this.traceId = traceId;
|
|
613
|
+
this.bridge = bridge;
|
|
614
|
+
}
|
|
615
|
+
async endSpan() {
|
|
616
|
+
CustomSpanRegistry.unregisterSpan(this.spanId);
|
|
617
|
+
await this.bridge.endSpan(this.spanId);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/** A root-level custom span. All child spans and `withContext` network calls share its traceId. */
|
|
622
|
+
class CoralogixGlobalSpan {
|
|
623
|
+
constructor(spanId, traceId, bridge) {
|
|
624
|
+
this.spanId = void 0;
|
|
625
|
+
this.traceId = void 0;
|
|
626
|
+
this.bridge = void 0;
|
|
627
|
+
this.spanId = spanId;
|
|
628
|
+
this.traceId = traceId;
|
|
629
|
+
this.bridge = bridge;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/** Creates a child span nested under this global span. */
|
|
633
|
+
async startCustomSpan(name, labels) {
|
|
634
|
+
const raw = await this.bridge.startCustomSpan(this.spanId, name, labels != null ? labels : null);
|
|
635
|
+
if (!raw) return null;
|
|
636
|
+
CustomSpanRegistry.registerSpan(raw.spanId, raw.traceId);
|
|
637
|
+
return new CoralogixCustomSpan(raw.spanId, raw.traceId, this.bridge);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* Runs fn() with this span set as the active global span for the duration of
|
|
642
|
+
* the returned promise. The active span ID remains set throughout the full
|
|
643
|
+
* async chain — including code after intermediate awaits — because we await
|
|
644
|
+
* fn() before clearing. Only detached callbacks (e.g. setTimeout) that fire
|
|
645
|
+
* after withContext resolves won't be linked.
|
|
646
|
+
*/
|
|
647
|
+
async withContext(fn) {
|
|
648
|
+
const prev = CustomSpanRegistry.getActive();
|
|
649
|
+
CustomSpanRegistry.setActive(this.spanId);
|
|
650
|
+
try {
|
|
651
|
+
return await fn();
|
|
652
|
+
} finally {
|
|
653
|
+
if (prev !== null) {
|
|
654
|
+
CustomSpanRegistry.setActive(prev);
|
|
655
|
+
} else {
|
|
656
|
+
CustomSpanRegistry.clearActive();
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
async endSpan() {
|
|
661
|
+
CustomSpanRegistry.unregisterSpan(this.spanId);
|
|
662
|
+
if (CustomSpanRegistry.getActive() === this.spanId) {
|
|
663
|
+
CustomSpanRegistry.clearActive();
|
|
664
|
+
}
|
|
665
|
+
await this.bridge.endSpan(this.spanId);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* Entry point for manual RUM tracing. Obtain an instance via `CoralogixRum.getCustomTracer()`.
|
|
671
|
+
* The `ignoredInstruments` list controls which auto-instrumented events are NOT linked to spans
|
|
672
|
+
* created by this tracer (e.g. passing `['networkRequests']` keeps network spans independent).
|
|
673
|
+
*/
|
|
674
|
+
class CoralogixCustomTracer {
|
|
675
|
+
constructor(ignoredInstruments, bridge) {
|
|
676
|
+
this.ignoredInstruments = void 0;
|
|
677
|
+
this.bridge = void 0;
|
|
678
|
+
this.ignoredInstruments = ignoredInstruments;
|
|
679
|
+
this.bridge = bridge;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Starts a new global (root) span. Returns `null` if a global span is already active —
|
|
684
|
+
* only one global span may exist at a time across the entire app.
|
|
685
|
+
*/
|
|
686
|
+
async startGlobalSpan(name, labels) {
|
|
687
|
+
const raw = await this.bridge.startGlobalSpan(name, labels != null ? labels : null, this.ignoredInstruments);
|
|
688
|
+
if (!raw) {
|
|
689
|
+
logger.debug('CoralogixCustomTracer: startGlobalSpan returned null — check that the SDK is initialized, traceParentInHeader is enabled, and no other global span is already active');
|
|
690
|
+
return null;
|
|
691
|
+
}
|
|
692
|
+
CustomSpanRegistry.registerSpan(raw.spanId, raw.traceId);
|
|
693
|
+
CustomSpanRegistry.setIgnoredInstruments(new Set(this.ignoredInstruments));
|
|
694
|
+
return new CoralogixGlobalSpan(raw.spanId, raw.traceId, this.bridge);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
562
698
|
const CORALOGIX_LOGS_URL_SUFFIX = '/browser/v1beta/logs';
|
|
563
699
|
const CORALOGIX_RECORDING_URL_SUFFIX = '/sessionrecording';
|
|
564
700
|
const OPTIONS_DEFAULTS = {
|
|
@@ -836,6 +972,7 @@ let CoralogixDomain = /*#__PURE__*/function (CoralogixDomain) {
|
|
|
836
972
|
CoralogixDomain["AP1"] = "AP1";
|
|
837
973
|
CoralogixDomain["AP2"] = "AP2";
|
|
838
974
|
CoralogixDomain["AP3"] = "AP3";
|
|
975
|
+
CoralogixDomain["US3"] = "US3";
|
|
839
976
|
CoralogixDomain["STAGING"] = "staging";
|
|
840
977
|
return CoralogixDomain;
|
|
841
978
|
}({});
|
|
@@ -845,6 +982,7 @@ const LINKING_ERROR = `The package 'cx-plugin' doesn't seem to be linked. Make s
|
|
|
845
982
|
default: ''
|
|
846
983
|
}) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n';
|
|
847
984
|
let beforeSendCallback;
|
|
985
|
+
let tracesExporterSubscription;
|
|
848
986
|
let _deregisterInstrumentations;
|
|
849
987
|
const CxSdk = NativeModules.CxSdk ? NativeModules.CxSdk : createErrorProxy(LINKING_ERROR);
|
|
850
988
|
function createErrorProxy(errorMessage) {
|
|
@@ -861,14 +999,15 @@ const CoralogixRum = {
|
|
|
861
999
|
return isInited;
|
|
862
1000
|
},
|
|
863
1001
|
init: async function (options) {
|
|
864
|
-
var _resolvedOptions$debu;
|
|
1002
|
+
var _resolvedOptions$debu, _resolvedOptions$excl, _resolvedOptions$excl2;
|
|
865
1003
|
if (isInited) {
|
|
866
1004
|
console.warn('[Coralogix React Native SDK] - already initialized');
|
|
867
1005
|
return;
|
|
868
1006
|
}
|
|
869
1007
|
const resolvedOptions = resolveCoralogixOtelWebConfig(options);
|
|
870
1008
|
logger.shouldLog = (_resolvedOptions$debu = resolvedOptions.debug) != null ? _resolvedOptions$debu : false;
|
|
871
|
-
|
|
1009
|
+
const hasExcludeOverrides = ((_resolvedOptions$excl = (_resolvedOptions$excl2 = resolvedOptions.excludeFromSampling) == null ? void 0 : _resolvedOptions$excl2.length) != null ? _resolvedOptions$excl : 0) > 0;
|
|
1010
|
+
if (!isSamplingOn(resolvedOptions.sessionSampleRate) && !hasExcludeOverrides) {
|
|
872
1011
|
logger.debug('CoralogixRum: Session tracking is disabled');
|
|
873
1012
|
return;
|
|
874
1013
|
}
|
|
@@ -884,10 +1023,28 @@ const CoralogixRum = {
|
|
|
884
1023
|
} else {
|
|
885
1024
|
finalOptions = resolvedOptions;
|
|
886
1025
|
}
|
|
1026
|
+
if (finalOptions.tracesExporter) {
|
|
1027
|
+
const callback = finalOptions.tracesExporter;
|
|
1028
|
+
tracesExporterSubscription = eventEmitter.addListener('onTracesExport', jsonString => {
|
|
1029
|
+
let data;
|
|
1030
|
+
try {
|
|
1031
|
+
data = JSON.parse(jsonString);
|
|
1032
|
+
} catch (e) {
|
|
1033
|
+
logger.warn('Error parsing onTracesExport payload:', e);
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
try {
|
|
1037
|
+
callback(data);
|
|
1038
|
+
} catch (e) {
|
|
1039
|
+
logger.warn('tracesExporter callback threw:', e);
|
|
1040
|
+
}
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
887
1043
|
await CxSdk.initialize(_extends({}, finalOptions, {
|
|
888
1044
|
frameworkVersion: pkg.version,
|
|
889
1045
|
networkExtraConfig: finalOptions.networkExtraConfig ? serializeNetworkCaptureRules(finalOptions.networkExtraConfig) : undefined,
|
|
890
|
-
hasBeforeSend: !!finalOptions.beforeSend
|
|
1046
|
+
hasBeforeSend: !!finalOptions.beforeSend,
|
|
1047
|
+
hasTracesExporter: !!finalOptions.tracesExporter
|
|
891
1048
|
}));
|
|
892
1049
|
isInited = true;
|
|
893
1050
|
},
|
|
@@ -899,6 +1056,10 @@ const CoralogixRum = {
|
|
|
899
1056
|
if (subscription) {
|
|
900
1057
|
subscription.remove();
|
|
901
1058
|
}
|
|
1059
|
+
if (tracesExporterSubscription) {
|
|
1060
|
+
tracesExporterSubscription.remove();
|
|
1061
|
+
tracesExporterSubscription = undefined;
|
|
1062
|
+
}
|
|
902
1063
|
isInited = false;
|
|
903
1064
|
_deregisterInstrumentations == null || _deregisterInstrumentations();
|
|
904
1065
|
_deregisterInstrumentations = undefined;
|
|
@@ -990,6 +1151,19 @@ const CoralogixRum = {
|
|
|
990
1151
|
reportNetworkRequest: details => {
|
|
991
1152
|
CxSdk.reportNetworkRequest(details);
|
|
992
1153
|
},
|
|
1154
|
+
/**
|
|
1155
|
+
* Returns a tracer for creating manual custom spans.
|
|
1156
|
+
* Pass `ignoredInstruments` to prevent specific auto-instrumented event types from being
|
|
1157
|
+
* linked to spans created by this tracer.
|
|
1158
|
+
*/
|
|
1159
|
+
getCustomTracer(ignoredInstruments = []) {
|
|
1160
|
+
const bridge = {
|
|
1161
|
+
startGlobalSpan: (name, labels, instruments) => CxSdk.startGlobalSpan(name, labels, instruments),
|
|
1162
|
+
startCustomSpan: (parentSpanId, name, labels) => CxSdk.startCustomSpan(parentSpanId, name, labels),
|
|
1163
|
+
endSpan: spanId => CxSdk.endSpan(spanId)
|
|
1164
|
+
};
|
|
1165
|
+
return new CoralogixCustomTracer(ignoredInstruments, bridge);
|
|
1166
|
+
},
|
|
993
1167
|
sendCustomMeasurement: measurement => {
|
|
994
1168
|
if (!isInited) {
|
|
995
1169
|
logger.debug('CoralogixRum must be initiated before sending custom measurements');
|
|
@@ -997,6 +1171,20 @@ const CoralogixRum = {
|
|
|
997
1171
|
}
|
|
998
1172
|
CxSdk.sendCustomMeasurement(measurement);
|
|
999
1173
|
},
|
|
1174
|
+
startTimeMeasure: (name, labels) => {
|
|
1175
|
+
if (!isInited) {
|
|
1176
|
+
logger.debug('CoralogixRum must be initiated before startTimeMeasure');
|
|
1177
|
+
return;
|
|
1178
|
+
}
|
|
1179
|
+
CxSdk.startTimeMeasure(name, labels != null ? labels : {});
|
|
1180
|
+
},
|
|
1181
|
+
endTimeMeasure: name => {
|
|
1182
|
+
if (!isInited) {
|
|
1183
|
+
logger.debug('CoralogixRum must be initiated before endTimeMeasure');
|
|
1184
|
+
return;
|
|
1185
|
+
}
|
|
1186
|
+
CxSdk.endTimeMeasure(name);
|
|
1187
|
+
},
|
|
1000
1188
|
reportError: (error, isCrash) => {
|
|
1001
1189
|
if (!isInited) {
|
|
1002
1190
|
logger.debug('CoralogixRum must be initiated before error reporting');
|
|
@@ -1219,4 +1407,4 @@ const subscription = eventEmitter.addListener('onBeforeSend', events => {
|
|
|
1219
1407
|
}
|
|
1220
1408
|
});
|
|
1221
1409
|
|
|
1222
|
-
export { CoralogixDomain, CoralogixLogSeverity, CoralogixRum, CxSdk, SessionReplay, attachReactNavigationObserver, parseErrorStack };
|
|
1410
|
+
export { CoralogixCustomSpan, CoralogixCustomTracer, CoralogixDomain, CoralogixGlobalSpan, CoralogixLogSeverity, CoralogixRum, CxSdk, SessionReplay, attachReactNavigationObserver, parseErrorStack };
|
package/ios/CxSdk.mm
CHANGED
|
@@ -80,6 +80,11 @@ RCT_EXTERN_METHOD(sendCustomMeasurement:(NSDictionary *)measurement
|
|
|
80
80
|
withResolver:(RCTPromiseResolveBlock)resolve
|
|
81
81
|
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
82
82
|
|
|
83
|
+
RCT_EXTERN_METHOD(startTimeMeasure:(NSString *)name
|
|
84
|
+
labels:(NSDictionary *)labels)
|
|
85
|
+
|
|
86
|
+
RCT_EXTERN_METHOD(endTimeMeasure:(NSString *)name)
|
|
87
|
+
|
|
83
88
|
RCT_EXTERN_METHOD(initializeSessionReplay:(NSDictionary *)options
|
|
84
89
|
withResolver:(RCTPromiseResolveBlock)resolve
|
|
85
90
|
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
@@ -106,6 +111,22 @@ RCT_EXTERN_METHOD(maskViewByTag:(nonnull NSNumber *)viewTag
|
|
|
106
111
|
withResolver:(RCTPromiseResolveBlock)resolve
|
|
107
112
|
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
108
113
|
|
|
114
|
+
RCT_EXTERN_METHOD(startGlobalSpan:(NSString *)name
|
|
115
|
+
labels:(NSDictionary *)labels
|
|
116
|
+
ignoredInstruments:(NSArray *)ignoredInstruments
|
|
117
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
118
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
119
|
+
|
|
120
|
+
RCT_EXTERN_METHOD(startCustomSpan:(NSString *)parentSpanId
|
|
121
|
+
name:(NSString *)name
|
|
122
|
+
labels:(NSDictionary *)labels
|
|
123
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
124
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
125
|
+
|
|
126
|
+
RCT_EXTERN_METHOD(endSpan:(NSString *)spanId
|
|
127
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
128
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
129
|
+
|
|
109
130
|
+ (BOOL)requiresMainQueueSetup
|
|
110
131
|
{
|
|
111
132
|
return NO;
|