@coralogix/react-native-plugin 0.1.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 +17 -0
- package/CxSdk.podspec +45 -0
- package/LICENSE +201 -0
- package/README.md +187 -0
- package/android/build.gradle +87 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/cxsdk/CxSdkModule.kt +457 -0
- package/android/src/main/java/com/cxsdk/CxSdkPackage.kt +16 -0
- package/android/src/main/java/com/cxsdk/ICxSdkModule.kt +24 -0
- package/index.cjs.js +682 -0
- package/index.d.ts +1 -0
- package/index.esm.js +678 -0
- package/ios/CxSdk-Bridging-Header.h +2 -0
- package/ios/CxSdk.mm +81 -0
- package/ios/CxSdk.swift +371 -0
- package/package.json +34 -0
- package/src/CoralogixPropgator.d.ts +2 -0
- package/src/consts.d.ts +23 -0
- package/src/index.d.ts +10 -0
- package/src/instrumentations/error/ErrorInstrumentation.d.ts +18 -0
- package/src/instrumentations/error/error.consts.d.ts +7 -0
- package/src/instrumentations/error/error.enums.d.ts +4 -0
- package/src/instrumentations/mobile-vitals/JsRefreshRateSamplerInstrumentation.d.ts +8 -0
- package/src/instrumentations/mobile-vitals/loopDetectorInstrumentation.d.ts +16 -0
- package/src/instrumentations/network/FetchInstrumentation.d.ts +5 -0
- package/src/instrumentations/network/network.enums.d.ts +10 -0
- package/src/logger.d.ts +16 -0
- package/src/model/ApplicationContextConfig.d.ts +4 -0
- package/src/model/CoralogixDomain.d.ts +10 -0
- package/src/model/CoralogixOtelWebOptionsInstrumentations.d.ts +9 -0
- package/src/model/CoralogixOtelWebType.d.ts +49 -0
- package/src/model/CoralogixRumLabels.d.ts +1 -0
- package/src/model/CustomMeasurement.d.ts +4 -0
- package/src/model/NetworkRequestDetails.d.ts +14 -0
- package/src/model/SendLog.d.ts +10 -0
- package/src/model/Types.d.ts +209 -0
- package/src/model/UserContextConfig.d.ts +8 -0
- package/src/model/ViewContextConfig.d.ts +3 -0
- package/src/utils.d.ts +5 -0
package/ios/CxSdk.mm
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
#import <React/RCTEventEmitter.h>
|
|
3
|
+
|
|
4
|
+
@interface RCT_EXTERN_MODULE(CxSdk, RCTEventEmitter)
|
|
5
|
+
|
|
6
|
+
RCT_EXTERN_METHOD(initialize:(NSDictionary *)parameter
|
|
7
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
8
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
9
|
+
|
|
10
|
+
RCT_EXTERN_METHOD(supportedEvents)
|
|
11
|
+
|
|
12
|
+
RCT_EXTERN_METHOD(setUserContext:(NSDictionary *)userContext
|
|
13
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
14
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
15
|
+
|
|
16
|
+
RCT_EXTERN_METHOD(getUserContext:(RCTPromiseResolveBlock)resolve
|
|
17
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
18
|
+
|
|
19
|
+
RCT_EXTERN_METHOD(setNetworkRequestContext:(NSDictionary *)networkRequestContext
|
|
20
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
21
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
22
|
+
|
|
23
|
+
RCT_EXTERN_METHOD(isInited:(RCTPromiseResolveBlock)resolve
|
|
24
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
25
|
+
|
|
26
|
+
RCT_EXTERN_METHOD(setLabels:(NSDictionary *)labels
|
|
27
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
28
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
29
|
+
|
|
30
|
+
RCT_EXTERN_METHOD(getLabels:(RCTPromiseResolveBlock)resolve
|
|
31
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
32
|
+
|
|
33
|
+
RCT_EXTERN_METHOD(setViewContext:(NSString *)viewContext
|
|
34
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
35
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
36
|
+
|
|
37
|
+
RCT_EXTERN_METHOD(setApplicationContext:(NSDictionary *)applicationContext
|
|
38
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
39
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
40
|
+
|
|
41
|
+
RCT_EXTERN_METHOD(getSessionId:(RCTPromiseResolveBlock)resolve
|
|
42
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
43
|
+
|
|
44
|
+
RCT_EXTERN_METHOD(shutdown:(RCTPromiseResolveBlock)resolve
|
|
45
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
46
|
+
|
|
47
|
+
RCT_EXTERN_METHOD(reportError:(NSDictionary *)errorDictionary
|
|
48
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
49
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
50
|
+
|
|
51
|
+
RCT_EXTERN_METHOD(log:(int)severity
|
|
52
|
+
message:(NSString *)message
|
|
53
|
+
data:(NSDictionary *)data
|
|
54
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
55
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
56
|
+
|
|
57
|
+
RCT_EXTERN_METHOD(reportNetworkRequest:(NSDictionary *)networkRequestDictionary
|
|
58
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
59
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
60
|
+
|
|
61
|
+
RCT_EXTERN_METHOD(sendCxSpanData:(NSArray *)beforeSendResults
|
|
62
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
63
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
64
|
+
|
|
65
|
+
RCT_EXTERN_METHOD(reportMobileVitalsMeasurementSet:(NSString *)type
|
|
66
|
+
metrics:(NSArray *)metrics
|
|
67
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
68
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
69
|
+
|
|
70
|
+
RCT_EXTERN_METHOD(reportMobileVitalsMeasurement:(NSString *)type
|
|
71
|
+
value:(double)value
|
|
72
|
+
units:(NSString *)units
|
|
73
|
+
withResolver:(RCTPromiseResolveBlock)resolve
|
|
74
|
+
withRejecter:(RCTPromiseRejectBlock)reject)
|
|
75
|
+
|
|
76
|
+
+ (BOOL)requiresMainQueueSetup
|
|
77
|
+
{
|
|
78
|
+
return NO;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@end
|
package/ios/CxSdk.swift
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Coralogix
|
|
3
|
+
import React
|
|
4
|
+
|
|
5
|
+
enum CxSdkError: Error {
|
|
6
|
+
case invalidPublicKey
|
|
7
|
+
case missingParameter
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@objc(CxSdk)
|
|
11
|
+
class CxSdk: RCTEventEmitter {
|
|
12
|
+
var coralogixRum: CoralogixRum?
|
|
13
|
+
|
|
14
|
+
override init() {
|
|
15
|
+
super.init()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
override class func requiresMainQueueSetup() -> Bool {
|
|
19
|
+
return false
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
override func supportedEvents() -> [String]! {
|
|
23
|
+
return ["onBeforeSend"]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@objc(initialize:withResolver:withRejecter:)
|
|
27
|
+
func initialize(parameter: NSDictionary,
|
|
28
|
+
resolve:RCTPromiseResolveBlock,
|
|
29
|
+
reject:RCTPromiseRejectBlock) -> Void {
|
|
30
|
+
do {
|
|
31
|
+
// Create beforeSendCallback only if parameter["beforeSend"] is not null
|
|
32
|
+
let beforeSendCallBack: (([[String: Any]]) -> Void)? = parameter["beforeSend"] != nil ? { [weak self] (event: [[String: Any]]) -> Void in
|
|
33
|
+
// Convert the event dictionary to a format that
|
|
34
|
+
// can be safely passed to JavaScript
|
|
35
|
+
let jsEvent = event.map { (element) in
|
|
36
|
+
return self?.convertToJSCompatibleEvent(event: element)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
self?.sendEvent(withName: "onBeforeSend", body: jsEvent)
|
|
40
|
+
} : nil
|
|
41
|
+
|
|
42
|
+
var options = try self.toCoralogixOptions(parameter: parameter)
|
|
43
|
+
options.beforeSendCallBack = beforeSendCallBack
|
|
44
|
+
let rnPluginVersion = parameter["frameworkVersion"] as? String ?? ""
|
|
45
|
+
|
|
46
|
+
self.coralogixRum = CoralogixRum(options: options, sdkFramework: .reactNative(version: rnPluginVersion))
|
|
47
|
+
resolve("initialize success")
|
|
48
|
+
} catch let error as CxSdkError {
|
|
49
|
+
reject("CX_SDK_ERROR", error.localizedDescription, error)
|
|
50
|
+
} catch {
|
|
51
|
+
reject("UNEXPECTED_ERROR", "An unexpected error occurred: \(error.localizedDescription)", error)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@objc(setUserContext:withResolver:withRejecter:)
|
|
56
|
+
func setUserContext(userContextMap: NSDictionary,
|
|
57
|
+
resolve:RCTPromiseResolveBlock,
|
|
58
|
+
reject:RCTPromiseRejectBlock) -> Void {
|
|
59
|
+
let userContext = self.generateUserContext(parameter: userContextMap)
|
|
60
|
+
coralogixRum?.setUserContext(userContext: userContext)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@objc(getUserContext:withRejecter:)
|
|
64
|
+
func getUserContext(resolve: @escaping RCTPromiseResolveBlock,
|
|
65
|
+
reject: @escaping RCTPromiseRejectBlock) {
|
|
66
|
+
let userContext = coralogixRum?.getUserContext()
|
|
67
|
+
resolve(userContext?.getDictionary())
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@objc(setLabels:withResolver:withRejecter:)
|
|
71
|
+
func setLabels(labelsMap: NSDictionary,
|
|
72
|
+
resolve:RCTPromiseResolveBlock,
|
|
73
|
+
reject:RCTPromiseRejectBlock) -> Void {
|
|
74
|
+
let labels = labelsMap as? [String: String] ?? [String: String]()
|
|
75
|
+
resolve(coralogixRum?.setLabels(labels: labels))
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@objc(getLabels:withRejecter:)
|
|
79
|
+
func getLabels(resolve: @escaping RCTPromiseResolveBlock,
|
|
80
|
+
reject: @escaping RCTPromiseRejectBlock) {
|
|
81
|
+
if let labels = coralogixRum?.getLabels() {
|
|
82
|
+
resolve(labels) // Assuming labels is a Dictionary or Array
|
|
83
|
+
} else {
|
|
84
|
+
reject("GET_LABELS_ERROR", "Failed to retrieve labels", nil)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@objc(setNetworkRequestContext:withResolver:withRejecter:)
|
|
89
|
+
func setNetworkRequestContext(networkRequestContext: NSDictionary,
|
|
90
|
+
resolve:RCTPromiseResolveBlock,
|
|
91
|
+
reject:RCTPromiseRejectBlock) -> Void {
|
|
92
|
+
guard let dictionary: [String: Any] = networkRequestContext as? [String: Any] else {
|
|
93
|
+
reject("Invalid networkRequestContext", "networkRequestContext is not a dictionary", nil)
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
coralogixRum?.setNetworkRequestContext(dictionary: dictionary)
|
|
97
|
+
resolve("setNetworkRequestContext success")
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@objc(isInited:withRejecter:)
|
|
101
|
+
func isInited(resolve: @escaping RCTPromiseResolveBlock,
|
|
102
|
+
reject: @escaping RCTPromiseRejectBlock) {
|
|
103
|
+
if let isInit = coralogixRum?.isInitialized() {
|
|
104
|
+
resolve(isInit)
|
|
105
|
+
} else {
|
|
106
|
+
reject("IS_INITED", "Failed to retrieve isInited", nil)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@objc(setViewContext:withResolver:withRejecter:)
|
|
111
|
+
func setViewContext(viewContext: String,
|
|
112
|
+
resolve:RCTPromiseResolveBlock,
|
|
113
|
+
reject:RCTPromiseRejectBlock) -> Void {
|
|
114
|
+
coralogixRum?.setView(name: viewContext)
|
|
115
|
+
resolve("setViewContext success")
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@objc(log:message:data:withResolver:withRejecter:)
|
|
119
|
+
func log(severity: Int,
|
|
120
|
+
message: String,
|
|
121
|
+
data: NSDictionary,
|
|
122
|
+
resolve:RCTPromiseResolveBlock,
|
|
123
|
+
reject:RCTPromiseRejectBlock) -> Void {
|
|
124
|
+
|
|
125
|
+
guard let cxLogSeverity = CoralogixLogSeverity(rawValue: Int(severity)) else {
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
let data = data as? [String: Any] ?? [String: Any]()
|
|
129
|
+
coralogixRum?.log(severity:cxLogSeverity, message: message, data: data)
|
|
130
|
+
resolve("log success")
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@objc(setApplicationContext:withResolver:withRejecter:)
|
|
134
|
+
func setApplicationContext(applicationContext: NSDictionary,
|
|
135
|
+
resolve:RCTPromiseResolveBlock,
|
|
136
|
+
reject:RCTPromiseRejectBlock) -> Void {
|
|
137
|
+
guard let dictionary = applicationContext as? [String: Any] else {
|
|
138
|
+
reject("Invalid applicationContext", "applicationContext is not a dictionary", nil)
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
let application: String = dictionary["application"] as? String ?? ""
|
|
142
|
+
let version: String = dictionary["version"] as? String ?? ""
|
|
143
|
+
coralogixRum?.setApplicationContext(application: application,
|
|
144
|
+
version: version)
|
|
145
|
+
resolve("setApplicationContext success")
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@objc(getSessionId:withRejecter:)
|
|
149
|
+
func getSessionId(resolve: @escaping RCTPromiseResolveBlock,
|
|
150
|
+
reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
151
|
+
let sessionId = coralogixRum?.getSessionId()
|
|
152
|
+
resolve(sessionId)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@objc(reportNetworkRequest:withResolver:withRejecter:)
|
|
156
|
+
func reportNetworkRequest(networkRequestDictionary:NSDictionary,
|
|
157
|
+
resolve:RCTPromiseResolveBlock,
|
|
158
|
+
reject:RCTPromiseRejectBlock) -> Void {
|
|
159
|
+
guard let dictionary = networkRequestDictionary as? [String: Any] else {
|
|
160
|
+
reject("Invalid networkRequestDictionary", "networkRequestDictionary is not a dictionary", nil)
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
let cxNetworkDict = toCoralogixNetwork(dictionary: dictionary)
|
|
164
|
+
coralogixRum?.setNetworkRequestContext(dictionary: cxNetworkDict)
|
|
165
|
+
resolve("reportNetworkRequest success")
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
@objc(shutdown:withRejecter:)
|
|
169
|
+
func shutdown(resolve:RCTPromiseResolveBlock,
|
|
170
|
+
reject:RCTPromiseRejectBlock) -> Void {
|
|
171
|
+
coralogixRum?.shutdown()
|
|
172
|
+
resolve("shutdown success")
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@objc(reportError:withResolver:withRejecter:)
|
|
176
|
+
func reportError(errorDictionary:NSDictionary,
|
|
177
|
+
resolve:@escaping RCTPromiseResolveBlock,
|
|
178
|
+
reject:@escaping RCTPromiseRejectBlock) -> Void {
|
|
179
|
+
guard let dictionary = errorDictionary as? [String: Any] else {
|
|
180
|
+
reject("Invalid Error Dictionary", "errorDictionary is not a dictionary", nil)
|
|
181
|
+
return
|
|
182
|
+
}
|
|
183
|
+
let stackTrace = (dictionary[Keys.keyStackTrace.rawValue] as? [[String: Any]]) ?? []
|
|
184
|
+
let message = dictionary[Keys.errorMessage.rawValue] as? String ?? ""
|
|
185
|
+
let errorType = dictionary[Keys.errorType.rawValue] as? String ?? "5"
|
|
186
|
+
|
|
187
|
+
coralogixRum?.reportError(message: message,
|
|
188
|
+
stackTrace: stackTrace,
|
|
189
|
+
errorType: errorType)
|
|
190
|
+
resolve("reportError success")
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@objc(sendCxSpanData:withResolver:withRejecter:)
|
|
194
|
+
func sendCxSpanData(beforeSendResults: NSArray,
|
|
195
|
+
resolve:RCTPromiseResolveBlock,
|
|
196
|
+
reject:RCTPromiseRejectBlock) -> Void {
|
|
197
|
+
guard let beforeSendResults = beforeSendResults as? [[String: Any]] else {
|
|
198
|
+
reject("Invalid sendBeforeSendData", "sendBeforeSendData is not a dictionary", nil)
|
|
199
|
+
return
|
|
200
|
+
}
|
|
201
|
+
coralogixRum?.sendBeforeSendData(data: beforeSendResults)
|
|
202
|
+
resolve("sendBeforeSendData success")
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
@objc(reportMobileVitalsMeasurementSet:metrics:withResolver:withRejecter:)
|
|
206
|
+
func reportMobileVitalsMeasurementSet(type: String, metrics: NSArray,
|
|
207
|
+
resolve:RCTPromiseResolveBlock,
|
|
208
|
+
reject:RCTPromiseRejectBlock) -> Void {
|
|
209
|
+
let list = self.toHybridMetricList(metrics: metrics)
|
|
210
|
+
coralogixRum?.reportMobileVitalsMeasurement(type: type, metrics: list)
|
|
211
|
+
resolve("reportMobileVitalsMeasurement success")
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
@objc(reportMobileVitalsMeasurement:value:units:withResolver:withRejecter:)
|
|
215
|
+
func reportMobileVitalsMeasurement(type: String, value: Double, units: String,
|
|
216
|
+
resolve:RCTPromiseResolveBlock,
|
|
217
|
+
reject:RCTPromiseRejectBlock) -> Void {
|
|
218
|
+
coralogixRum?.reportMobileVitalsMeasurement(type: type, value: value, units: units)
|
|
219
|
+
resolve("reportMobileVitalsMeasurement success")
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private func toHybridMetricList(metrics: NSArray) -> [HybridMetric] {
|
|
223
|
+
let array = metrics as? [[String: Any]] ?? []
|
|
224
|
+
|
|
225
|
+
return array.map { dict in
|
|
226
|
+
let hybridMetric = HybridMetric(name: dict["name"] as? String ?? "",
|
|
227
|
+
value: dict["value"] as? Double ?? 0.0,
|
|
228
|
+
units: dict["units"] as? String ?? "")
|
|
229
|
+
return hybridMetric
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
private func toCoralogixNetwork(dictionary: [String: Any]) -> [String: Any] {
|
|
234
|
+
var result = [String: Any]()
|
|
235
|
+
result["url"] = dictionary["url"] as? String ?? ""
|
|
236
|
+
result["host"] = dictionary["host"] as? String ?? ""
|
|
237
|
+
result["method"] = dictionary["method"] as? String ?? ""
|
|
238
|
+
result["status_code"] = dictionary["statusCode"] as? Int ?? 0
|
|
239
|
+
result["http_response_body_size"] = dictionary["duration"] as? Int ?? 0
|
|
240
|
+
result["fragments"] = dictionary["fragments"] as? String ?? ""
|
|
241
|
+
result["schema"] = dictionary["schema"] as? String ?? ""
|
|
242
|
+
result["customTraceId"] = dictionary["customTraceId"] as? String ?? ""
|
|
243
|
+
result["customSpanId"] = dictionary["customSpanId"] as? String ?? ""
|
|
244
|
+
return result
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
private func toCoralogixOptions(parameter: NSDictionary) throws -> CoralogixExporterOptions {
|
|
248
|
+
guard let publicKey = parameter["public_key"] as? String else {
|
|
249
|
+
debugPrint("Public Key Missing")
|
|
250
|
+
throw CxSdkError.invalidPublicKey
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
guard let application = parameter["application"] as? String else {
|
|
254
|
+
throw CxSdkError.missingParameter
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
guard let domain = parameter["coralogixDomain"] as? String else {
|
|
258
|
+
throw CxSdkError.missingParameter
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
let coralogixDomain = self.getCoralogixDomain(domain: domain)
|
|
262
|
+
let labels = parameter["labels"] as? [String: Any] ?? [String: Any]()
|
|
263
|
+
let instrumentations = parameter["instrumentations"] as? [String: Int] ?? [String: Int]()
|
|
264
|
+
|
|
265
|
+
var instrumentationDict: [CoralogixExporterOptions.InstrumentationType: Bool] = [:]
|
|
266
|
+
for (key, value) in instrumentations {
|
|
267
|
+
if let instrumentationKey = instrumentationType(from: key) {
|
|
268
|
+
instrumentationDict[instrumentationKey] = value == 0 ? false : true
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
let userContext = parameter["user_context"] as? [String: Any]
|
|
273
|
+
let userMetadata = userContext?["user_metadata"] as? [String: String] ?? [String: String]()
|
|
274
|
+
let coralogixUser = UserContext(userId: userContext?["user_id"] as? String ?? "",
|
|
275
|
+
userName: userContext?["user_name"] as? String ?? "",
|
|
276
|
+
userEmail:userContext?["user_email"] as? String ?? "",
|
|
277
|
+
userMetadata: userMetadata)
|
|
278
|
+
let ignoreUrls = (parameter["ignoreUrls"] as? [Any])?.compactMap { $0 as? String } ?? []
|
|
279
|
+
let ignoreError = (parameter["ignoreErrors"] as? [Any])?.compactMap { $0 as? String } ?? []
|
|
280
|
+
let options = CoralogixExporterOptions(coralogixDomain: coralogixDomain,
|
|
281
|
+
userContext: coralogixUser,
|
|
282
|
+
environment: parameter["environment"] as? String ?? "",
|
|
283
|
+
application: application,
|
|
284
|
+
version: parameter["version"] as? String ?? "",
|
|
285
|
+
publicKey: publicKey,
|
|
286
|
+
ignoreUrls: ignoreUrls,
|
|
287
|
+
ignoreErrors: ignoreError,
|
|
288
|
+
labels: labels,
|
|
289
|
+
sampleRate: 100,
|
|
290
|
+
mobileVitalsFPSSamplingRate: parameter["fpsSamplingSeconds"] as? Int ?? 300,
|
|
291
|
+
instrumentations: instrumentationDict,
|
|
292
|
+
collectIPData: parameter["collectIPData"] as? Bool ?? true,
|
|
293
|
+
proxyUrl: parameter["proxyUrl"] as? String ?? nil,
|
|
294
|
+
traceParentInHeader: parameter["traceParentInHeader"] as? [String: Any] ?? nil,
|
|
295
|
+
debug: parameter["debug"] as? Bool ?? true)
|
|
296
|
+
|
|
297
|
+
return options
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
private func convertToJSCompatibleEvent(event: [String: Any]) -> [String: Any] {
|
|
301
|
+
var jsEvent: [String: Any] = [:]
|
|
302
|
+
for (key, value) in event {
|
|
303
|
+
if let stringValue = value as? String {
|
|
304
|
+
jsEvent[key] = stringValue
|
|
305
|
+
} else if let numberValue = value as? NSNumber {
|
|
306
|
+
jsEvent[key] = numberValue
|
|
307
|
+
} else if let boolValue = value as? Bool {
|
|
308
|
+
jsEvent[key] = boolValue
|
|
309
|
+
} else if let arrayValue = value as? [Any] {
|
|
310
|
+
jsEvent[key] = arrayValue
|
|
311
|
+
} else if let dictValue = value as? [String: Any] {
|
|
312
|
+
jsEvent[key] = dictValue
|
|
313
|
+
} else if value is NSNull {
|
|
314
|
+
jsEvent[key] = NSNull()
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return jsEvent
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
private func generateUserContext(parameter: NSDictionary) -> UserContext {
|
|
321
|
+
let userMetadata = parameter["user_metadata"] as? [String: String] ?? [String: String]()
|
|
322
|
+
return UserContext(userId: parameter["user_id"] as? String ?? "",
|
|
323
|
+
userName: parameter["user_name"] as? String ?? "",
|
|
324
|
+
userEmail:parameter["user_email"] as? String ?? "",
|
|
325
|
+
userMetadata: userMetadata)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
private func instrumentationType(from string: String) -> CoralogixExporterOptions.InstrumentationType? {
|
|
329
|
+
switch string {
|
|
330
|
+
case "mobile_vitals":
|
|
331
|
+
return .mobileVitals
|
|
332
|
+
case "custom":
|
|
333
|
+
return .custom
|
|
334
|
+
case "errors":
|
|
335
|
+
return .errors
|
|
336
|
+
case "network":
|
|
337
|
+
return .network
|
|
338
|
+
case "user_interaction":
|
|
339
|
+
return .userActions
|
|
340
|
+
case "anr":
|
|
341
|
+
return .anr
|
|
342
|
+
case "lifecycle":
|
|
343
|
+
return .lifeCycle
|
|
344
|
+
default:
|
|
345
|
+
return nil
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
private func getCoralogixDomain(domain: String) -> CoralogixDomain {
|
|
350
|
+
switch domain.uppercased() {
|
|
351
|
+
case "EU1":
|
|
352
|
+
return .EU1
|
|
353
|
+
case "EU2":
|
|
354
|
+
return .EU2
|
|
355
|
+
case "US1":
|
|
356
|
+
return .US1
|
|
357
|
+
case "US2":
|
|
358
|
+
return .US2
|
|
359
|
+
case "AP1":
|
|
360
|
+
return .AP1
|
|
361
|
+
case "AP2":
|
|
362
|
+
return .AP2
|
|
363
|
+
case "AP3":
|
|
364
|
+
return .AP3
|
|
365
|
+
case "STAGING":
|
|
366
|
+
return .STG
|
|
367
|
+
default:
|
|
368
|
+
return .US2
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@coralogix/react-native-plugin",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official Coralogix React Native plugin",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "Coralogix",
|
|
7
|
+
"homepage": "https://github.com/coralogix/cx-react-native-plugin",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"official",
|
|
13
|
+
"coralogix",
|
|
14
|
+
"sdk",
|
|
15
|
+
"react-native",
|
|
16
|
+
"javascript",
|
|
17
|
+
"typescript",
|
|
18
|
+
"monitoring",
|
|
19
|
+
"frontend",
|
|
20
|
+
"mobile",
|
|
21
|
+
"plugin"
|
|
22
|
+
],
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"react-native": ">=0.73.8"
|
|
25
|
+
},
|
|
26
|
+
"main": "./index.cjs.js",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@opentelemetry/instrumentation-fetch": "0.203.0",
|
|
29
|
+
"@opentelemetry/instrumentation": "0.48.0",
|
|
30
|
+
"@opentelemetry/sdk-trace-web": "1.30.1"
|
|
31
|
+
},
|
|
32
|
+
"module": "./index.esm.js",
|
|
33
|
+
"types": "./index.d.ts"
|
|
34
|
+
}
|
package/src/consts.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CoralogixBrowserSdkConfig } from './model/Types';
|
|
2
|
+
export declare const CORALOGIX_LOGS_URL_SUFFIX = "/browser/v1beta/logs";
|
|
3
|
+
export declare const CORALOGIX_RECORDING_URL_SUFFIX = "/sessionrecording";
|
|
4
|
+
export declare const CoralogixAttributes: {
|
|
5
|
+
USER_AGENT: string;
|
|
6
|
+
LOCATION_HREF: string;
|
|
7
|
+
EVENT_TYPE: string;
|
|
8
|
+
SEVERITY: string;
|
|
9
|
+
APPLICATION_CONTEXT: string;
|
|
10
|
+
USER_CONTEXT: string;
|
|
11
|
+
SOURCE: string;
|
|
12
|
+
ERROR: {
|
|
13
|
+
TYPE: string;
|
|
14
|
+
STACK: string;
|
|
15
|
+
MESSAGE: string;
|
|
16
|
+
};
|
|
17
|
+
LOG: string;
|
|
18
|
+
CUSTOM_LABELS: string;
|
|
19
|
+
TIMESTAMP: string;
|
|
20
|
+
INTERNAL: string;
|
|
21
|
+
SSL_DURATION: string;
|
|
22
|
+
};
|
|
23
|
+
export declare const OPTIONS_DEFAULTS: Partial<CoralogixBrowserSdkConfig>;
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CoralogixOtelWebType } from './model/CoralogixOtelWebType';
|
|
2
|
+
export declare const CoralogixRum: CoralogixOtelWebType;
|
|
3
|
+
export { type ApplicationContextConfig } from './model/ApplicationContextConfig';
|
|
4
|
+
export { type ViewContextConfig } from './model/ViewContextConfig';
|
|
5
|
+
export { CoralogixDomain } from './model/CoralogixDomain';
|
|
6
|
+
export { type UserContextConfig } from './model/UserContextConfig';
|
|
7
|
+
export { type CoralogixBrowserSdkConfig, CoralogixLogSeverity, } from './model/Types';
|
|
8
|
+
export { type CoralogixOtelWebOptionsInstrumentations } from './model/CoralogixOtelWebOptionsInstrumentations';
|
|
9
|
+
export { type CustomMeasurement } from './model/CustomMeasurement';
|
|
10
|
+
export { type NetworkRequestDetails } from './model/NetworkRequestDetails';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { InstrumentationBase, InstrumentationConfig } from '@opentelemetry/instrumentation';
|
|
2
|
+
import { ErrorSource } from './error.enums';
|
|
3
|
+
export declare const getCircularReplacer: () => ((key: any, value: any) => undefined | any);
|
|
4
|
+
export interface CoralogixErrorInstrumentationConfig extends InstrumentationConfig {
|
|
5
|
+
ignoreErrors?: Array<string | RegExp>;
|
|
6
|
+
}
|
|
7
|
+
export declare class CoralogixErrorInstrumentation extends InstrumentationBase {
|
|
8
|
+
constructor(config: CoralogixErrorInstrumentationConfig);
|
|
9
|
+
init(): void;
|
|
10
|
+
private listenToConsoleError;
|
|
11
|
+
report(source: ErrorSource, arg: string | Error | Event | Array<any>): void;
|
|
12
|
+
parseErrorObject: (obj: any) => string;
|
|
13
|
+
protected reportError(err: Error): void;
|
|
14
|
+
protected reportString(message: string, firstError?: Error): void;
|
|
15
|
+
protected getPossibleEventMessage(event: any): string;
|
|
16
|
+
enable(): void;
|
|
17
|
+
disable(): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type SamplerOptions = {
|
|
2
|
+
sampleDurationMs?: number;
|
|
3
|
+
sampleIntervalMs?: number;
|
|
4
|
+
onSample: (rafRate: number) => void;
|
|
5
|
+
};
|
|
6
|
+
export declare function startJsRefreshRateSampler({ sampleDurationMs, sampleIntervalMs, onSample, }: SamplerOptions): void;
|
|
7
|
+
export declare function stopJsRefreshRateSampler(): void;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type FrameDropEvent = {
|
|
2
|
+
/** Total gap between RAF ticks */
|
|
3
|
+
delta: number;
|
|
4
|
+
/** Estimated blocking beyond the 60Hz budget */
|
|
5
|
+
stall: number;
|
|
6
|
+
/** RAF timestamp (relative, not wall clock) */
|
|
7
|
+
timestamp: number;
|
|
8
|
+
};
|
|
9
|
+
type JSLoopDetectorConfig = {
|
|
10
|
+
frameDropThresholdMs?: number;
|
|
11
|
+
onFrameDrop: (event: FrameDropEvent) => void;
|
|
12
|
+
onError?: (error: Error) => void;
|
|
13
|
+
};
|
|
14
|
+
export declare function startJSLoopDetector({ frameDropThresholdMs, onFrameDrop, onError, }: JSLoopDetectorConfig): void;
|
|
15
|
+
export declare function stopJSLoopDetector(): void;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare enum OtelNetworkAttrs {
|
|
2
|
+
METHOD = "http.method",
|
|
3
|
+
URL = "http.url",
|
|
4
|
+
STATUS_CODE = "http.status_code",
|
|
5
|
+
HOST = "http.host",
|
|
6
|
+
SCHEME = "http.scheme",
|
|
7
|
+
STATUS_TEXT = "http.status_text",
|
|
8
|
+
RESPONSE_CONTENT_LENGTH = "http.response_content_length",
|
|
9
|
+
OtelNetworkAttrs = "OtelNetworkAttrs"
|
|
10
|
+
}
|
package/src/logger.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
interface LoggerConfig {
|
|
2
|
+
shouldLog?: boolean;
|
|
3
|
+
prefix?: string;
|
|
4
|
+
}
|
|
5
|
+
declare class Logger {
|
|
6
|
+
private _shouldLog;
|
|
7
|
+
private readonly _prefix;
|
|
8
|
+
constructor(config?: LoggerConfig);
|
|
9
|
+
set shouldLog(value: boolean);
|
|
10
|
+
debug(message: string, ...args: unknown[]): void;
|
|
11
|
+
info(message: string, ...args: unknown[]): void;
|
|
12
|
+
warn(message: string, ...args: unknown[]): void;
|
|
13
|
+
error(message: string, ...args: unknown[]): void;
|
|
14
|
+
}
|
|
15
|
+
export declare const logger: Logger;
|
|
16
|
+
export {};
|