@coralogix/react-native-plugin 0.4.0 → 0.6.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 +19 -0
- package/CxSdk.podspec +3 -3
- package/README.md +43 -0
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/cxsdk/CxSdkModule.kt +46 -2
- package/android/src/main/java/com/cxsdk/RUMClient.kt +2 -0
- package/index.cjs.js +28 -4
- package/index.esm.js +28 -4
- package/ios/CxSdk.mm +5 -0
- package/ios/CxSdk.swift +38 -1
- package/package.json +1 -1
- package/src/index.d.ts +4 -2
- package/src/model/CoralogixOtelWebType.d.ts +14 -1
- package/src/model/Types.d.ts +11 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
## 0.6.0 (2026-06-04)
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- bump natives + extend reportError with optional data (0.6.0)
|
|
6
|
+
|
|
7
|
+
## 0.5.0 (2026-05-17)
|
|
8
|
+
|
|
9
|
+
### 🚀 Features
|
|
10
|
+
|
|
11
|
+
- bridge startTimeMeasure / endTimeMeasure to native (CX-40525)
|
|
12
|
+
- expose excludeFromSampling on JS config + native bridges
|
|
13
|
+
|
|
14
|
+
## Unreleased
|
|
15
|
+
|
|
16
|
+
### 🚀 Features
|
|
17
|
+
|
|
18
|
+
- Bridge `CoralogixRum.startTimeMeasure(name, labels?)` / `CoralogixRum.endTimeMeasure(name)` to the native iOS and Android SDKs as a fire-and-forget pass-through ([CX-40525](https://coralogix.atlassian.net/browse/CX-40525)). The JS side keeps no state — native owns the in-flight registry.
|
|
19
|
+
|
|
1
20
|
## 0.4.0 (2026-05-03)
|
|
2
21
|
|
|
3
22
|
### 🚀 Features
|
package/CxSdk.podspec
CHANGED
|
@@ -16,9 +16,9 @@ Pod::Spec.new do |s|
|
|
|
16
16
|
|
|
17
17
|
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
18
18
|
|
|
19
|
-
s.dependency 'Coralogix','2.
|
|
20
|
-
s.dependency 'CoralogixInternal','2.
|
|
21
|
-
s.dependency 'SessionReplay','2.
|
|
19
|
+
s.dependency 'Coralogix','2.7.0'
|
|
20
|
+
s.dependency 'CoralogixInternal','2.7.0'
|
|
21
|
+
s.dependency 'SessionReplay','2.7.0'
|
|
22
22
|
|
|
23
23
|
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
|
|
24
24
|
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
|
package/README.md
CHANGED
|
@@ -156,6 +156,25 @@ await CoralogixRum.init({
|
|
|
156
156
|
});
|
|
157
157
|
```
|
|
158
158
|
|
|
159
|
+
### Exclude From Sampling
|
|
160
|
+
|
|
161
|
+
By default, when a session is sampled out (via `sessionSampleRate`), nothing is
|
|
162
|
+
emitted for that session. Use `excludeFromSampling` to keep emitting specific
|
|
163
|
+
event categories even when the session is sampled out.
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
import { CoralogixRum } from '@coralogix/react-native-plugin';
|
|
167
|
+
|
|
168
|
+
await CoralogixRum.init({
|
|
169
|
+
// ...
|
|
170
|
+
sessionSampleRate: 10,
|
|
171
|
+
excludeFromSampling: ['errors', 'logs'], // always emitted, even for sampled-out sessions
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Allowed values: `'errors'`, `'logs'`, `'network'`, `'userInteractions'`,
|
|
176
|
+
`'mobileVitals'`, `'customSpan'`, `'customMeasurement'`.
|
|
177
|
+
|
|
159
178
|
### Ignore Errors
|
|
160
179
|
|
|
161
180
|
The ignoreErrors option allows you to exclude errors that meet specific criteria.
|
|
@@ -235,6 +254,30 @@ const tracer = CoralogixRum.getCustomTracer(['networkRequests', 'userInteraction
|
|
|
235
254
|
|
|
236
255
|
> **Note:** Only one global span may be active at a time. `startGlobalSpan` returns `null` if a global span is already open.
|
|
237
256
|
|
|
257
|
+
### Time Measurement
|
|
258
|
+
|
|
259
|
+
Measure the duration of arbitrary flows with a pair of `startTimeMeasure(name, labels?)` / `endTimeMeasure(name)` calls. The native SDK records start/end timestamps and reports the delta as a custom-measurement span (milliseconds).
|
|
260
|
+
|
|
261
|
+
```javascript
|
|
262
|
+
import { CoralogixRum } from '@coralogix/react-native-plugin';
|
|
263
|
+
|
|
264
|
+
CoralogixRum.startTimeMeasure('checkout', { flow: 'checkout' });
|
|
265
|
+
|
|
266
|
+
await validateCart();
|
|
267
|
+
await charge();
|
|
268
|
+
await confirm();
|
|
269
|
+
|
|
270
|
+
CoralogixRum.endTimeMeasure('checkout');
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Behaviour:**
|
|
274
|
+
|
|
275
|
+
- Both calls are fire-and-forget — they cross the bridge directly into native and return immediately.
|
|
276
|
+
- The JS side keeps no state; the native SDK owns the in-flight registry.
|
|
277
|
+
- **You are responsible for pairing every `startTimeMeasure(name, labels?)` with exactly one `endTimeMeasure(name)`.** Leaked starts persist in memory until `CoralogixRum.shutdown()`.
|
|
278
|
+
- Unmatched `endTimeMeasure` calls are dropped silently by the native SDK.
|
|
279
|
+
- Calling `startTimeMeasure` again with an open `name` overwrites the previous start.
|
|
280
|
+
|
|
238
281
|
### Traces Exporter
|
|
239
282
|
|
|
240
283
|
Receive OTLP-formatted trace batches from the native SDK in your JavaScript code. Use this to forward spans to an OTLP-compatible backend (e.g. Jaeger, custom collector) alongside Coralogix.
|
package/android/build.gradle
CHANGED
|
@@ -84,7 +84,7 @@ dependencies {
|
|
|
84
84
|
implementation "com.facebook.react:react-android"
|
|
85
85
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
86
86
|
|
|
87
|
-
implementation "com.coralogix:android-sdk:2.
|
|
87
|
+
implementation "com.coralogix:android-sdk:2.13.0"
|
|
88
88
|
|
|
89
89
|
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
|
90
90
|
testImplementation "org.mockito:mockito-core:5.12.0"
|
|
@@ -8,6 +8,7 @@ import com.coralogix.android.sdk.CoralogixRum
|
|
|
8
8
|
import com.coralogix.android.sdk.customspans.CoralogixCustomSpan
|
|
9
9
|
import com.coralogix.android.sdk.customspans.CoralogixGlobalSpan
|
|
10
10
|
import com.coralogix.android.sdk.customspans.CoralogixIgnoredInstrument
|
|
11
|
+
import com.coralogix.android.sdk.model.ExcludableInstrumentation
|
|
11
12
|
import com.coralogix.android.sdk.traceexporter.CoralogixTraceExporterData
|
|
12
13
|
import com.coralogix.android.sdk.internal.features.instrumentations.error.CoralogixErrorDecorator
|
|
13
14
|
import com.coralogix.android.sdk.internal.features.instrumentations.network.NetworkRequestDetails
|
|
@@ -142,6 +143,16 @@ class CxSdkModule(reactContext: ReactApplicationContext) :
|
|
|
142
143
|
CoralogixRum.sendCustomMeasurement(name, value)
|
|
143
144
|
}
|
|
144
145
|
|
|
146
|
+
@ReactMethod
|
|
147
|
+
override fun startTimeMeasure(name: String, labels: ReadableMap?) {
|
|
148
|
+
CoralogixRum.startTimeMeasure(name, labels?.toStringAnyMap() ?: emptyMap())
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@ReactMethod
|
|
152
|
+
override fun endTimeMeasure(name: String) {
|
|
153
|
+
CoralogixRum.endTimeMeasure(name)
|
|
154
|
+
}
|
|
155
|
+
|
|
145
156
|
@ReactMethod
|
|
146
157
|
override fun reportError(details: ReadableMap) {
|
|
147
158
|
val errorType = details.getString("error_type").orEmpty()
|
|
@@ -164,12 +175,19 @@ class CxSdkModule(reactContext: ReactApplicationContext) :
|
|
|
164
175
|
}
|
|
165
176
|
}.orEmpty()
|
|
166
177
|
|
|
178
|
+
val customAttributes: Map<String, Any>? = details.getMap("data")
|
|
179
|
+
?.toStringAnyMap()
|
|
180
|
+
?.filterValues { it != null }
|
|
181
|
+
?.mapValues { it.value as Any }
|
|
182
|
+
?.takeIf { it.isNotEmpty() }
|
|
183
|
+
|
|
167
184
|
CoralogixRum.reportError(
|
|
168
185
|
CoralogixErrorDecorator(
|
|
169
186
|
errorType = errorType,
|
|
170
187
|
errorMessage = message,
|
|
171
188
|
errorStack = CoralogixStackTrace(parsedStackFrames),
|
|
172
|
-
isCrash = isCrash
|
|
189
|
+
isCrash = isCrash,
|
|
190
|
+
customAttributes = customAttributes
|
|
173
191
|
)
|
|
174
192
|
)
|
|
175
193
|
}
|
|
@@ -425,6 +443,13 @@ class CxSdkModule(reactContext: ReactApplicationContext) :
|
|
|
425
443
|
getArray("networkExtraConfig")?.toNetworkCaptureRuleList() ?: emptyList()
|
|
426
444
|
else emptyList()
|
|
427
445
|
|
|
446
|
+
val excludeFromSampling = if (hasKey("excludeFromSampling") && !isNull("excludeFromSampling"))
|
|
447
|
+
getArray("excludeFromSampling")?.toExcludeFromSamplingList() ?: emptyList()
|
|
448
|
+
else emptyList()
|
|
449
|
+
|
|
450
|
+
val sessionSampleRate =
|
|
451
|
+
if (hasKey("sessionSampleRate") && !isNull("sessionSampleRate")) getInt("sessionSampleRate") else 100
|
|
452
|
+
|
|
428
453
|
return CoralogixOptions(
|
|
429
454
|
applicationName = applicationName,
|
|
430
455
|
coralogixDomain = coralogixDomain,
|
|
@@ -438,7 +463,8 @@ class CxSdkModule(reactContext: ReactApplicationContext) :
|
|
|
438
463
|
mobileVitalsOptions = getMap("mobileVitals")?.toMobileVitalsOptions() ?: mapOf(),
|
|
439
464
|
ignoreUrls = getArray("ignoreUrls")?.handleStringOrRegexList() ?: listOf(),
|
|
440
465
|
ignoreErrors = getArray("ignoreErrors")?.handleStringOrRegexList() ?: listOf(),
|
|
441
|
-
sessionSampleRate =
|
|
466
|
+
sessionSampleRate = sessionSampleRate,
|
|
467
|
+
excludeFromSampling = excludeFromSampling,
|
|
442
468
|
traceParentInHeader = traceParentInHeaderConfig,
|
|
443
469
|
debug = if (hasKey("debug")) getBoolean("debug") else false,
|
|
444
470
|
proxyUrl = getString("proxyUrl"),
|
|
@@ -851,6 +877,24 @@ class CxSdkModule(reactContext: ReactApplicationContext) :
|
|
|
851
877
|
return set
|
|
852
878
|
}
|
|
853
879
|
|
|
880
|
+
private fun ReadableArray.toExcludeFromSamplingList(): List<ExcludableInstrumentation> {
|
|
881
|
+
val set = LinkedHashSet<ExcludableInstrumentation>()
|
|
882
|
+
for (i in 0 until size()) {
|
|
883
|
+
val value = getString(i)
|
|
884
|
+
when (value) {
|
|
885
|
+
"errors" -> set.add(ExcludableInstrumentation.Errors)
|
|
886
|
+
"logs" -> set.add(ExcludableInstrumentation.Logs)
|
|
887
|
+
"network" -> set.add(ExcludableInstrumentation.Network)
|
|
888
|
+
"userInteractions" -> set.add(ExcludableInstrumentation.UserInteractions)
|
|
889
|
+
"mobileVitals" -> set.add(ExcludableInstrumentation.MobileVitals)
|
|
890
|
+
"customSpan" -> set.add(ExcludableInstrumentation.CustomSpan)
|
|
891
|
+
"customMeasurement" -> set.add(ExcludableInstrumentation.CustomMeasurement)
|
|
892
|
+
else -> Log.w("CxSdkModule", "excludeFromSampling: unrecognized value '$value' — native enum may have drifted")
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
return set.toList()
|
|
896
|
+
}
|
|
897
|
+
|
|
854
898
|
private fun ReadableArray.toHybridMetricList(): List<HybridMetric> {
|
|
855
899
|
val out = ArrayList<HybridMetric>(size())
|
|
856
900
|
for (i in 0 until size()) {
|
|
@@ -16,6 +16,8 @@ interface RUMClient {
|
|
|
16
16
|
fun log(severity: Int, message: String, data: ReadableMap, labels: ReadableMap)
|
|
17
17
|
fun reportNetworkRequest(requestDetails: ReadableMap)
|
|
18
18
|
fun sendCustomMeasurement(measurement: ReadableMap)
|
|
19
|
+
fun startTimeMeasure(name: String, labels: ReadableMap?)
|
|
20
|
+
fun endTimeMeasure(name: String)
|
|
19
21
|
fun reportError(details: ReadableMap)
|
|
20
22
|
fun sendCxSpanData(results: ReadableArray)
|
|
21
23
|
fun reportMobileVitalsMeasurement(type: String, value: Double, units: String)
|
package/index.cjs.js
CHANGED
|
@@ -33,6 +33,12 @@ let CoralogixLogSeverity = /*#__PURE__*/function (CoralogixLogSeverity) {
|
|
|
33
33
|
* being linked to spans created by that tracer.
|
|
34
34
|
*/
|
|
35
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
|
+
|
|
36
42
|
/** OTLP JSON-format trace data delivered to the `tracesExporter` callback. */
|
|
37
43
|
|
|
38
44
|
const ERROR_INSTRUMENTATION_NAME = 'errors';
|
|
@@ -531,7 +537,7 @@ function stopJsRefreshRateSampler() {
|
|
|
531
537
|
appStateSub = null;
|
|
532
538
|
}
|
|
533
539
|
|
|
534
|
-
var version = "0.
|
|
540
|
+
var version = "0.6.0";
|
|
535
541
|
var pkg = {
|
|
536
542
|
version: version};
|
|
537
543
|
|
|
@@ -995,14 +1001,15 @@ const CoralogixRum = {
|
|
|
995
1001
|
return isInited;
|
|
996
1002
|
},
|
|
997
1003
|
init: async function (options) {
|
|
998
|
-
var _resolvedOptions$debu;
|
|
1004
|
+
var _resolvedOptions$debu, _resolvedOptions$excl, _resolvedOptions$excl2;
|
|
999
1005
|
if (isInited) {
|
|
1000
1006
|
console.warn('[Coralogix React Native SDK] - already initialized');
|
|
1001
1007
|
return;
|
|
1002
1008
|
}
|
|
1003
1009
|
const resolvedOptions = resolveCoralogixOtelWebConfig(options);
|
|
1004
1010
|
logger.shouldLog = (_resolvedOptions$debu = resolvedOptions.debug) != null ? _resolvedOptions$debu : false;
|
|
1005
|
-
|
|
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) {
|
|
1006
1013
|
logger.debug('CoralogixRum: Session tracking is disabled');
|
|
1007
1014
|
return;
|
|
1008
1015
|
}
|
|
@@ -1166,7 +1173,21 @@ const CoralogixRum = {
|
|
|
1166
1173
|
}
|
|
1167
1174
|
CxSdk.sendCustomMeasurement(measurement);
|
|
1168
1175
|
},
|
|
1169
|
-
|
|
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
|
+
},
|
|
1190
|
+
reportError: (error, isCrash, data) => {
|
|
1170
1191
|
if (!isInited) {
|
|
1171
1192
|
logger.debug('CoralogixRum must be initiated before error reporting');
|
|
1172
1193
|
return;
|
|
@@ -1177,6 +1198,9 @@ const CoralogixRum = {
|
|
|
1177
1198
|
stack_trace: parseErrorStack(error),
|
|
1178
1199
|
is_crash: isCrash
|
|
1179
1200
|
};
|
|
1201
|
+
if (data && Object.keys(data).length > 0) {
|
|
1202
|
+
errorDetails.data = data;
|
|
1203
|
+
}
|
|
1180
1204
|
CxSdk.reportError(errorDetails);
|
|
1181
1205
|
}
|
|
1182
1206
|
};
|
package/index.esm.js
CHANGED
|
@@ -31,6 +31,12 @@ let CoralogixLogSeverity = /*#__PURE__*/function (CoralogixLogSeverity) {
|
|
|
31
31
|
* being linked to spans created by that tracer.
|
|
32
32
|
*/
|
|
33
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
|
+
|
|
34
40
|
/** OTLP JSON-format trace data delivered to the `tracesExporter` callback. */
|
|
35
41
|
|
|
36
42
|
const ERROR_INSTRUMENTATION_NAME = 'errors';
|
|
@@ -529,7 +535,7 @@ function stopJsRefreshRateSampler() {
|
|
|
529
535
|
appStateSub = null;
|
|
530
536
|
}
|
|
531
537
|
|
|
532
|
-
var version = "0.
|
|
538
|
+
var version = "0.6.0";
|
|
533
539
|
var pkg = {
|
|
534
540
|
version: version};
|
|
535
541
|
|
|
@@ -993,14 +999,15 @@ const CoralogixRum = {
|
|
|
993
999
|
return isInited;
|
|
994
1000
|
},
|
|
995
1001
|
init: async function (options) {
|
|
996
|
-
var _resolvedOptions$debu;
|
|
1002
|
+
var _resolvedOptions$debu, _resolvedOptions$excl, _resolvedOptions$excl2;
|
|
997
1003
|
if (isInited) {
|
|
998
1004
|
console.warn('[Coralogix React Native SDK] - already initialized');
|
|
999
1005
|
return;
|
|
1000
1006
|
}
|
|
1001
1007
|
const resolvedOptions = resolveCoralogixOtelWebConfig(options);
|
|
1002
1008
|
logger.shouldLog = (_resolvedOptions$debu = resolvedOptions.debug) != null ? _resolvedOptions$debu : false;
|
|
1003
|
-
|
|
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) {
|
|
1004
1011
|
logger.debug('CoralogixRum: Session tracking is disabled');
|
|
1005
1012
|
return;
|
|
1006
1013
|
}
|
|
@@ -1164,7 +1171,21 @@ const CoralogixRum = {
|
|
|
1164
1171
|
}
|
|
1165
1172
|
CxSdk.sendCustomMeasurement(measurement);
|
|
1166
1173
|
},
|
|
1167
|
-
|
|
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
|
+
},
|
|
1188
|
+
reportError: (error, isCrash, data) => {
|
|
1168
1189
|
if (!isInited) {
|
|
1169
1190
|
logger.debug('CoralogixRum must be initiated before error reporting');
|
|
1170
1191
|
return;
|
|
@@ -1175,6 +1196,9 @@ const CoralogixRum = {
|
|
|
1175
1196
|
stack_trace: parseErrorStack(error),
|
|
1176
1197
|
is_crash: isCrash
|
|
1177
1198
|
};
|
|
1199
|
+
if (data && Object.keys(data).length > 0) {
|
|
1200
|
+
errorDetails.data = data;
|
|
1201
|
+
}
|
|
1178
1202
|
CxSdk.reportError(errorDetails);
|
|
1179
1203
|
}
|
|
1180
1204
|
};
|
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)
|
package/ios/CxSdk.swift
CHANGED
|
@@ -226,11 +226,15 @@ class CxSdk: RCTEventEmitter {
|
|
|
226
226
|
let message = dictionary[Keys.errorMessage.rawValue] as? String ?? ""
|
|
227
227
|
let errorType = dictionary[Keys.errorType.rawValue] as? String ?? "5"
|
|
228
228
|
let isCrash = dictionary[Keys.isCrash.rawValue] as? Bool ?? false
|
|
229
|
+
// Pass `data` only when non-empty — an empty dict would surface
|
|
230
|
+
// `error_context.data = {}` on the emitted RUM event.
|
|
231
|
+
let customAttributes = (dictionary["data"] as? [String: Any]).flatMap { $0.isEmpty ? nil : $0 }
|
|
229
232
|
|
|
230
233
|
coralogixRum?.reportError(message: message,
|
|
231
234
|
stackTrace: stackTrace,
|
|
232
235
|
errorType: errorType,
|
|
233
|
-
isCrash: isCrash
|
|
236
|
+
isCrash: isCrash,
|
|
237
|
+
customAttributes: customAttributes)
|
|
234
238
|
resolve("reportError success")
|
|
235
239
|
}
|
|
236
240
|
|
|
@@ -368,6 +372,17 @@ class CxSdk: RCTEventEmitter {
|
|
|
368
372
|
resolve("sendCustomMeasurement success")
|
|
369
373
|
}
|
|
370
374
|
|
|
375
|
+
@objc(startTimeMeasure:labels:)
|
|
376
|
+
func startTimeMeasure(name: String, labels: NSDictionary) {
|
|
377
|
+
let labelsDict = labels as? [String: Any]
|
|
378
|
+
coralogixRum?.startTimeMeasure(name: name, labels: labelsDict)
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
@objc(endTimeMeasure:)
|
|
382
|
+
func endTimeMeasure(name: String) {
|
|
383
|
+
coralogixRum?.endTimeMeasure(name: name)
|
|
384
|
+
}
|
|
385
|
+
|
|
371
386
|
private func toHybridMetricList(metrics: NSArray) -> [HybridMetric] {
|
|
372
387
|
let array = metrics as? [[String: Any]] ?? []
|
|
373
388
|
|
|
@@ -472,6 +487,9 @@ class CxSdk: RCTEventEmitter {
|
|
|
472
487
|
let ignoreError = (parameter["ignoreErrors"] as? [Any])?.compactMap { $0 as? String } ?? []
|
|
473
488
|
let rawNetworkExtraConfig = parameter["networkExtraConfig"] as? [[String: Any]]
|
|
474
489
|
let networkExtraConfig = toNetworkCaptureRuleList(rawNetworkExtraConfig)
|
|
490
|
+
let excludeFromSampling = toExcludeFromSampling(parameter["excludeFromSampling"] as? [Any])
|
|
491
|
+
|
|
492
|
+
let sessionSampleRate = (parameter["sessionSampleRate"] as? NSNumber)?.intValue ?? 100
|
|
475
493
|
|
|
476
494
|
let options = CoralogixExporterOptions(
|
|
477
495
|
coralogixDomain: coralogixDomain,
|
|
@@ -483,6 +501,8 @@ class CxSdk: RCTEventEmitter {
|
|
|
483
501
|
ignoreUrls: ignoreUrls,
|
|
484
502
|
ignoreErrors: ignoreError,
|
|
485
503
|
labels: labels,
|
|
504
|
+
sessionSampleRate: sessionSampleRate,
|
|
505
|
+
excludeFromSampling: excludeFromSampling,
|
|
486
506
|
instrumentations: instrumentationDict,
|
|
487
507
|
collectIPData: parameter["collectIPData"] as? Bool ?? true,
|
|
488
508
|
proxyUrl: parameter["proxyUrl"] as? String ?? nil,
|
|
@@ -594,6 +614,23 @@ class CxSdk: RCTEventEmitter {
|
|
|
594
614
|
}
|
|
595
615
|
}
|
|
596
616
|
|
|
617
|
+
private func toExcludeFromSampling(_ raw: [Any]?) -> Set<ExcludableInstrumentation> {
|
|
618
|
+
guard let raw = raw else { return [] }
|
|
619
|
+
var result: Set<ExcludableInstrumentation> = []
|
|
620
|
+
for value in raw {
|
|
621
|
+
guard let key = value as? String else {
|
|
622
|
+
debugPrint("[CxSdk] excludeFromSampling: ignoring non-string value \(value)")
|
|
623
|
+
continue
|
|
624
|
+
}
|
|
625
|
+
guard let instrumentation = ExcludableInstrumentation(rawValue: key) else {
|
|
626
|
+
debugPrint("[CxSdk] excludeFromSampling: unrecognized value '\(key)' — native enum may have drifted")
|
|
627
|
+
continue
|
|
628
|
+
}
|
|
629
|
+
result.insert(instrumentation)
|
|
630
|
+
}
|
|
631
|
+
return result
|
|
632
|
+
}
|
|
633
|
+
|
|
597
634
|
private func instrumentationType(from string: String) -> CoralogixExporterOptions.InstrumentationType? {
|
|
598
635
|
switch string {
|
|
599
636
|
case "mobile_vitals":
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -21,7 +21,9 @@ interface CxSdkClient {
|
|
|
21
21
|
setViewContext(viewContext: string): void;
|
|
22
22
|
log(severity: CoralogixLogSeverity, message: string, data: Record<string, any> | undefined | null, labels: Record<string, any> | undefined | null): void;
|
|
23
23
|
sendCustomMeasurement(measurement: CustomMeasurement): void;
|
|
24
|
-
|
|
24
|
+
startTimeMeasure(name: string, labels: Record<string, unknown>): void;
|
|
25
|
+
endTimeMeasure(name: string): void;
|
|
26
|
+
reportError(details: Record<string, unknown>): void;
|
|
25
27
|
reportNetworkRequest(details: NetworkRequestDetails): void;
|
|
26
28
|
shutdown(): Promise<boolean>;
|
|
27
29
|
sendCxSpanData(results: CxSpan[]): void;
|
|
@@ -57,7 +59,7 @@ export { type ApplicationContextConfig } from './model/ApplicationContextConfig'
|
|
|
57
59
|
export { type ViewContextConfig } from './model/ViewContextConfig';
|
|
58
60
|
export { CoralogixDomain } from './model/CoralogixDomain';
|
|
59
61
|
export { type UserContextConfig } from './model/UserContextConfig';
|
|
60
|
-
export { type CoralogixBrowserSdkConfig, type CoralogixIgnoredInstrument, type NetworkCaptureRule, type TraceExporterData, CoralogixLogSeverity, } from './model/Types';
|
|
62
|
+
export { type CoralogixBrowserSdkConfig, type CoralogixIgnoredInstrument, type ExcludableInstrumentation, type NetworkCaptureRule, type TraceExporterData, CoralogixLogSeverity, } from './model/Types';
|
|
61
63
|
export { type CoralogixOtelWebOptionsInstrumentations } from './model/CoralogixOtelWebOptionsInstrumentations';
|
|
62
64
|
export { type CustomMeasurement } from './model/CustomMeasurement';
|
|
63
65
|
export { type NetworkRequestDetails } from './model/NetworkRequestDetails';
|
|
@@ -41,7 +41,20 @@ export interface CoralogixOtelWebType extends SendLog {
|
|
|
41
41
|
* Send custom key value pair
|
|
42
42
|
*/
|
|
43
43
|
sendCustomMeasurement: (measurement: CustomMeasurement) => void;
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Start a time measurement for `name`. The native SDK records the start
|
|
46
|
+
* timestamp; the call is fire-and-forget. Pair every `startTimeMeasure`
|
|
47
|
+
* with exactly one `endTimeMeasure(name)` — leaked starts persist in
|
|
48
|
+
* memory until shutdown.
|
|
49
|
+
*/
|
|
50
|
+
startTimeMeasure: (name: string, labels?: Record<string, unknown>) => void;
|
|
51
|
+
/**
|
|
52
|
+
* End a previously started time measurement. The native SDK computes the
|
|
53
|
+
* duration and reports it as a custom-measurement span (milliseconds).
|
|
54
|
+
* Unknown names are dropped silently by the native SDK.
|
|
55
|
+
*/
|
|
56
|
+
endTimeMeasure: (name: string) => void;
|
|
57
|
+
reportError: (error: Error, isCrash: boolean, data?: Record<string, unknown>) => void;
|
|
45
58
|
/**
|
|
46
59
|
* Report a network request to the underlying Coralogix SDK
|
|
47
60
|
* @param details
|
package/src/model/Types.d.ts
CHANGED
|
@@ -200,6 +200,11 @@ export interface CoralogixBrowserSdkConfig {
|
|
|
200
200
|
environment?: string;
|
|
201
201
|
/** Percentage of overall sessions being tracked, defaults to 100% */
|
|
202
202
|
sessionSampleRate?: number;
|
|
203
|
+
/**
|
|
204
|
+
* Event categories that bypass session sampling. Events of these categories are
|
|
205
|
+
* emitted even when the session is sampled out. Defaults to `[]`.
|
|
206
|
+
*/
|
|
207
|
+
excludeFromSampling?: ExcludableInstrumentation[];
|
|
203
208
|
/** Collect IP data */
|
|
204
209
|
collectIPData?: boolean;
|
|
205
210
|
/** Enable event access and modification before sending to Coralogix, supporting content modification, and event discarding. */
|
|
@@ -232,6 +237,12 @@ export type HybridMetric = {
|
|
|
232
237
|
* being linked to spans created by that tracer.
|
|
233
238
|
*/
|
|
234
239
|
export type CoralogixIgnoredInstrument = 'networkRequests' | 'userInteractions' | 'errors';
|
|
240
|
+
/**
|
|
241
|
+
* Event categories that can opt out of session sampling. When the session is
|
|
242
|
+
* sampled out, events whose category is listed in `excludeFromSampling` are still
|
|
243
|
+
* emitted; everything else is dropped. Mirrors the iOS/Android native enums.
|
|
244
|
+
*/
|
|
245
|
+
export type ExcludableInstrumentation = 'errors' | 'logs' | 'network' | 'userInteractions' | 'mobileVitals' | 'customSpan' | 'customMeasurement';
|
|
235
246
|
/** OTLP JSON-format trace data delivered to the `tracesExporter` callback. */
|
|
236
247
|
export interface TraceExporterData {
|
|
237
248
|
resource_spans: Record<string, unknown>[];
|