@luciq/react-native 19.2.1 → 19.3.0-40271-SNAPSHOT
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 +30 -0
- package/README.md +87 -0
- package/RNLuciq.podspec +1 -1
- package/android/native.gradle +1 -1
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqAPMModule.java +211 -117
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerModule.java +29 -7
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqReactnativeModule.java +51 -9
- package/android/src/main/java/ai/luciq/reactlibrary/utils/EventEmitterModule.java +7 -0
- package/dist/constants/Strings.d.ts +9 -0
- package/dist/constants/Strings.js +12 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/models/CustomSpan.d.ts +47 -0
- package/dist/models/CustomSpan.js +82 -0
- package/dist/modules/APM.d.ts +58 -0
- package/dist/modules/APM.js +62 -0
- package/dist/modules/Luciq.js +2 -1
- package/dist/modules/NetworkLogger.d.ts +0 -5
- package/dist/modules/NetworkLogger.js +9 -1
- package/dist/native/NativeAPM.d.ts +3 -0
- package/dist/native/NativeLuciq.d.ts +1 -0
- package/dist/utils/CustomSpansManager.d.ts +38 -0
- package/dist/utils/CustomSpansManager.js +173 -0
- package/dist/utils/FeatureFlags.d.ts +6 -0
- package/dist/utils/FeatureFlags.js +35 -0
- package/dist/utils/LuciqUtils.js +6 -0
- package/dist/utils/XhrNetworkInterceptor.js +85 -53
- package/ios/RNLuciq/LuciqAPMBridge.h +13 -0
- package/ios/RNLuciq/LuciqAPMBridge.m +55 -0
- package/ios/RNLuciq/LuciqReactBridge.m +12 -0
- package/ios/RNLuciq/Util/LCQAPM+PrivateAPIs.h +1 -0
- package/ios/native.rb +1 -1
- package/package.json +1 -2
- package/plugin/build/index.js +9 -2
- package/plugin/src/withLuciqIOS.ts +9 -2
- package/scripts/releases/changelog_to_slack_formatter.sh +9 -0
- package/scripts/releases/get_job_approver.sh +60 -0
- package/scripts/releases/get_release_notes.sh +22 -0
- package/scripts/releases/get_sdk_version.sh +5 -0
- package/scripts/releases/get_slack_id_from_username.sh +24 -0
- package/src/constants/Strings.ts +24 -0
- package/src/index.ts +2 -0
- package/src/models/CustomSpan.ts +102 -0
- package/src/modules/APM.ts +72 -0
- package/src/modules/Luciq.ts +3 -1
- package/src/modules/NetworkLogger.ts +26 -1
- package/src/native/NativeAPM.ts +7 -0
- package/src/native/NativeLuciq.ts +1 -0
- package/src/utils/CustomSpansManager.ts +202 -0
- package/src/utils/FeatureFlags.ts +44 -0
- package/src/utils/LuciqUtils.ts +15 -0
- package/src/utils/XhrNetworkInterceptor.ts +128 -55
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [19.3.0](https://github.com/luciqai/luciq-reactnative-sdk/compare/v19.3.0...19.2.1)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Custom Spans**: New feature to manually instrument code paths for performance tracking
|
|
8
|
+
- `APM.startCustomSpan(name)` - Start a custom span and return a span object
|
|
9
|
+
- `CustomSpan.end()` - End the span and report to SDK
|
|
10
|
+
- `APM.addCompletedCustomSpan(name, startDate, endDate)` - Record a pre-completed span
|
|
11
|
+
- Support for up to 100 concurrent spans
|
|
12
|
+
- Comprehensive validation (name length, empty checks, timestamp validation)
|
|
13
|
+
- Feature flag support to enable/disable custom spans
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Bump Luciq iOS SDK to v19.5.0 ([#37](https://github.com/luciqai/luciq-reactnative-sdk/pull/37)). [See release notes](https://github.com/luciqai/Luciq-iOS-sdk/releases/tag/19.5.0).
|
|
18
|
+
|
|
19
|
+
- Bump Luciq Android SDK to v19.3.0 ([#37](https://github.com/luciqai/luciq-reactnative-sdk/pull/37)). [See release notes](https://github.com/luciqai/Luciq-Android-sdk/releases/tag/v19.4.0).
|
|
20
|
+
|
|
21
|
+
## [19.2.2](https://github.com/luciqai/luciq-reactnative-sdk/compare/v19.2.2...19.2.1)
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Bump Luciq iOS SDK to v19.4.1 ([#34](https://github.com/luciqai/luciq-reactnative-sdk/pull/34)). [See release notes](https://github.com/luciqai/Luciq-iOS-sdk/releases/tag/19.4.1).
|
|
26
|
+
|
|
27
|
+
- Bump Luciq Android SDK to v19.2.2 ([#34](https://github.com/luciqai/luciq-reactnative-sdk/pull/34)). [See release notes](https://github.com/luciqai/Luciq-Android-sdk/releases/tag/v19.2.2).
|
|
28
|
+
|
|
3
29
|
## [19.2.1](https://github.com/luciqai/luciq-reactnative-sdk/compare/v19.2.1...19.1.0)
|
|
4
30
|
|
|
5
31
|
### Added
|
|
@@ -14,6 +40,10 @@
|
|
|
14
40
|
|
|
15
41
|
- Bump Luciq Android SDK to v19.2.1 ([#29](https://github.com/luciqai/luciq-reactnative-sdk/pull/29)). [See release notes](https://github.com/luciqai/Luciq-Android-sdk/releases/tag/v19.2.1).
|
|
16
42
|
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- Running Expo Plugin on ios [#31](https://github.com/luciqai/luciq-reactnative-sdk/pull/31))
|
|
46
|
+
|
|
17
47
|
## [19.1.0](https://github.com/luciqai/luciq-reactnative-sdk/compare/v19.1.0...19.0.0)
|
|
18
48
|
|
|
19
49
|
### Added
|
package/README.md
CHANGED
|
@@ -141,6 +141,93 @@ You can disable Repro Steps using the following API:
|
|
|
141
141
|
Luciq.setReproStepsConfig({ all: ReproStepsMode.disabled });
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
+
## Custom Spans
|
|
145
|
+
|
|
146
|
+
Custom spans allow you to manually instrument arbitrary code paths for performance tracking. This feature enables tracking of operations not covered by automatic instrumentation.
|
|
147
|
+
|
|
148
|
+
### Starting and Ending a Span
|
|
149
|
+
|
|
150
|
+
```javascript
|
|
151
|
+
import { APM } from '@luciq/react-native';
|
|
152
|
+
|
|
153
|
+
// Start a custom span
|
|
154
|
+
const span = await APM.startCustomSpan('Load User Profile');
|
|
155
|
+
|
|
156
|
+
if (span) {
|
|
157
|
+
try {
|
|
158
|
+
// Perform your operation
|
|
159
|
+
await loadUserProfile();
|
|
160
|
+
} finally {
|
|
161
|
+
// Always end the span, even if operation fails
|
|
162
|
+
await span.end();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Recording a Completed Span
|
|
168
|
+
|
|
169
|
+
```javascript
|
|
170
|
+
const start = new Date();
|
|
171
|
+
// ... operation already completed ...
|
|
172
|
+
const end = new Date();
|
|
173
|
+
|
|
174
|
+
await APM.addCompletedCustomSpan('Cache Lookup', start, end);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Important Notes
|
|
178
|
+
|
|
179
|
+
- **Span Limit**: Maximum of 100 concurrent spans at any time
|
|
180
|
+
- **Name Length**: Span names are truncated to 150 characters
|
|
181
|
+
- **Validation**: Empty names or invalid timestamps will be rejected
|
|
182
|
+
- **Idempotent**: Calling `span.end()` multiple times is safe
|
|
183
|
+
- **Feature Flags**: Spans are only created when SDK is initialized, APM is enabled, and custom spans feature is enabled
|
|
184
|
+
|
|
185
|
+
### API Reference
|
|
186
|
+
|
|
187
|
+
#### `APM.startCustomSpan(name: string): Promise<CustomSpan | null>`
|
|
188
|
+
|
|
189
|
+
Starts a custom span for performance tracking.
|
|
190
|
+
|
|
191
|
+
**Parameters:**
|
|
192
|
+
|
|
193
|
+
- `name` (string): The name of the span. Cannot be empty. Max 150 characters.
|
|
194
|
+
|
|
195
|
+
**Returns:**
|
|
196
|
+
|
|
197
|
+
- `Promise<CustomSpan | null>`: The span object to end later, or `null` if the span could not be created.
|
|
198
|
+
|
|
199
|
+
**Example:**
|
|
200
|
+
|
|
201
|
+
```javascript
|
|
202
|
+
const span = await APM.startCustomSpan('Database Query');
|
|
203
|
+
if (span) {
|
|
204
|
+
// ... perform operation ...
|
|
205
|
+
await span.end();
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
#### `CustomSpan.end(): Promise<void>`
|
|
210
|
+
|
|
211
|
+
Ends the custom span and reports it to the SDK. This method is idempotent.
|
|
212
|
+
|
|
213
|
+
#### `APM.addCompletedCustomSpan(name: string, startDate: Date, endDate: Date): Promise<void>`
|
|
214
|
+
|
|
215
|
+
Records a completed custom span with pre-recorded timestamps.
|
|
216
|
+
|
|
217
|
+
**Parameters:**
|
|
218
|
+
|
|
219
|
+
- `name` (string): The name of the span. Cannot be empty. Max 150 characters.
|
|
220
|
+
- `startDate` (Date): The start time of the operation.
|
|
221
|
+
- `endDate` (Date): The end time of the operation (must be after startDate).
|
|
222
|
+
|
|
223
|
+
**Example:**
|
|
224
|
+
|
|
225
|
+
```javascript
|
|
226
|
+
const start = new Date(Date.now() - 1500);
|
|
227
|
+
const end = new Date();
|
|
228
|
+
await APM.addCompletedCustomSpan('Background Task', start, end);
|
|
229
|
+
```
|
|
230
|
+
|
|
144
231
|
## Documentation
|
|
145
232
|
|
|
146
233
|
For more details about the supported APIs and how to use them, check our [**Documentation**](https://docs.luciq.ai/docs/react-native-overview).
|
package/RNLuciq.podspec
CHANGED
|
@@ -12,7 +12,7 @@ Pod::Spec.new do |s|
|
|
|
12
12
|
s.homepage = package["homepage"]
|
|
13
13
|
s.source = { :git => "https://github.com/Instabug/Instabug-React-Native.git", :tag => 'v' + package["version"] }
|
|
14
14
|
|
|
15
|
-
s.platform = :ios, "
|
|
15
|
+
s.platform = :ios, "15.0"
|
|
16
16
|
s.source_files = "ios/**/*.{h,m,mm}"
|
|
17
17
|
|
|
18
18
|
s.dependency 'React-Core'
|
package/android/native.gradle
CHANGED
|
@@ -13,21 +13,25 @@ import com.facebook.react.bridge.Promise;
|
|
|
13
13
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
14
14
|
import com.facebook.react.bridge.ReactMethod;
|
|
15
15
|
import com.facebook.react.bridge.ReadableMap;
|
|
16
|
-
import ai.luciq.apm.APM;
|
|
17
|
-
import ai.luciq.apm.networking.APMNetworkLogger;
|
|
18
|
-
import ai.luciq.apm.networkinterception.cp.APMCPNetworkLog;
|
|
19
|
-
import ai.luciq.reactlibrary.utils.EventEmitterModule;
|
|
20
|
-
import ai.luciq.reactlibrary.utils.MainThreadHandler;
|
|
21
16
|
|
|
22
17
|
import java.lang.reflect.Method;
|
|
23
|
-
import java.util.
|
|
18
|
+
import java.util.Date;
|
|
24
19
|
|
|
25
20
|
import javax.annotation.Nonnull;
|
|
26
21
|
|
|
27
|
-
import
|
|
22
|
+
import ai.luciq.apm.APM;
|
|
23
|
+
import ai.luciq.apm.InternalAPM;
|
|
24
|
+
import ai.luciq.apm.configuration.cp.APMFeature;
|
|
25
|
+
import ai.luciq.apm.configuration.cp.FeatureAvailabilityCallback;
|
|
26
|
+
import ai.luciq.apm.networking.APMNetworkLogger;
|
|
27
|
+
import ai.luciq.apm.networkinterception.cp.APMCPNetworkLog;
|
|
28
|
+
import ai.luciq.reactlibrary.utils.EventEmitterModule;
|
|
29
|
+
import ai.luciq.reactlibrary.utils.MainThreadHandler;
|
|
28
30
|
|
|
29
31
|
public class RNLuciqAPMModule extends EventEmitterModule {
|
|
30
32
|
|
|
33
|
+
private static final String NET_TAG = "LCQ-RN-NET";
|
|
34
|
+
|
|
31
35
|
public RNLuciqAPMModule(ReactApplicationContext reactApplicationContext) {
|
|
32
36
|
super(reactApplicationContext);
|
|
33
37
|
}
|
|
@@ -240,73 +244,73 @@ public class RNLuciqAPMModule extends EventEmitterModule {
|
|
|
240
244
|
});
|
|
241
245
|
}
|
|
242
246
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
247
|
+
/**
|
|
248
|
+
* The `networkLogAndroid` function logs network-related information using APMNetworkLogger in a React
|
|
249
|
+
* Native module.
|
|
250
|
+
*
|
|
251
|
+
* @param requestStartTime The `requestStartTime` parameter in the `networkLogAndroid` method
|
|
252
|
+
* represents the timestamp when the network request started. It is of type `double` and is passed as
|
|
253
|
+
* a parameter to log network-related information.
|
|
254
|
+
* @param requestDuration The `requestDuration` parameter in the `networkLogAndroid` method represents
|
|
255
|
+
* the duration of the network request in milliseconds. It indicates the time taken for the request to
|
|
256
|
+
* complete from the moment it was initiated until the response was received. This parameter helps in
|
|
257
|
+
* measuring the performance of network requests and identifying any potential
|
|
258
|
+
* @param requestHeaders requestHeaders is a string parameter that contains the headers of the network
|
|
259
|
+
* request. It typically includes information such as the content type, authorization token, and any
|
|
260
|
+
* other headers that were sent with the request.
|
|
261
|
+
* @param requestBody The `requestBody` parameter in the `networkLogAndroid` method represents the
|
|
262
|
+
* body of the HTTP request being logged. It contains the data that is sent as part of the request to
|
|
263
|
+
* the server. This could include form data, JSON payload, XML data, or any other content that is
|
|
264
|
+
* being transmitted
|
|
265
|
+
* @param requestBodySize The `requestBodySize` parameter in the `networkLogAndroid` method represents
|
|
266
|
+
* the size of the request body in bytes. It is a double value that indicates the size of the request
|
|
267
|
+
* body being sent in the network request. This parameter is used to log information related to the
|
|
268
|
+
* network request, including details
|
|
269
|
+
* @param requestMethod The `requestMethod` parameter in the `networkLogAndroid` method represents the
|
|
270
|
+
* HTTP method used in the network request, such as GET, POST, PUT, DELETE, etc. It indicates the type
|
|
271
|
+
* of operation that the client is requesting from the server.
|
|
272
|
+
* @param requestUrl The `requestUrl` parameter in the `networkLogAndroid` method represents the URL
|
|
273
|
+
* of the network request being logged. It typically contains the address of the server to which the
|
|
274
|
+
* request is being made, along with any additional path or query parameters required for the request.
|
|
275
|
+
* This URL is essential for identifying the
|
|
276
|
+
* @param requestContentType The `requestContentType` parameter in the `networkLogAndroid` method
|
|
277
|
+
* represents the content type of the request being made. This could be values like
|
|
278
|
+
* "application/json", "application/xml", "text/plain", etc., indicating the format of the data being
|
|
279
|
+
* sent in the request body. It helps in specifying
|
|
280
|
+
* @param responseHeaders The `responseHeaders` parameter in the `networkLogAndroid` method represents
|
|
281
|
+
* the headers of the response received from a network request. These headers typically include
|
|
282
|
+
* information such as content type, content length, server information, and any other metadata
|
|
283
|
+
* related to the response. The `responseHeaders` parameter is expected to
|
|
284
|
+
* @param responseBody The `responseBody` parameter in the `networkLogAndroid` method represents the
|
|
285
|
+
* body of the response received from a network request. It contains the data or content sent back by
|
|
286
|
+
* the server in response to the request made by the client. This could be in various formats such as
|
|
287
|
+
* JSON, XML, HTML
|
|
288
|
+
* @param responseBodySize The `responseBodySize` parameter in the `networkLogAndroid` method
|
|
289
|
+
* represents the size of the response body in bytes. It is a double value that indicates the size of
|
|
290
|
+
* the response body received from the network request. This parameter is used to log information
|
|
291
|
+
* related to the network request and response, including
|
|
292
|
+
* @param statusCode The `statusCode` parameter in the `networkLogAndroid` method represents the HTTP
|
|
293
|
+
* status code of the network request/response. It indicates the status of the HTTP response, such as
|
|
294
|
+
* success (200), redirection (3xx), client errors (4xx), or server errors (5xx). This parameter is
|
|
295
|
+
* @param responseContentType The `responseContentType` parameter in the `networkLogAndroid` method
|
|
296
|
+
* represents the content type of the response received from the network request. It indicates the
|
|
297
|
+
* format of the data in the response, such as JSON, XML, HTML, etc. This information is useful for
|
|
298
|
+
* understanding how to parse and handle the
|
|
299
|
+
* @param errorDomain The `errorDomain` parameter in the `networkLogAndroid` method is used to specify
|
|
300
|
+
* the domain of an error, if any occurred during the network request. If there was no error, this
|
|
301
|
+
* parameter will be `null`.
|
|
302
|
+
* @param w3cAttributes The `w3cAttributes` parameter in the `networkLogAndroid` method is a
|
|
303
|
+
* ReadableMap object that contains additional attributes related to W3C external trace. It may
|
|
304
|
+
* include the following key-value pairs:
|
|
305
|
+
* @param gqLCQueryName The `gqLCQueryName` parameter in the `networkLogAndroid` method represents the
|
|
306
|
+
* name of the GraphQL query being executed. It is a nullable parameter, meaning it can be null if no
|
|
307
|
+
* GraphQL query name is provided. This parameter is used to log information related to GraphQL
|
|
308
|
+
* queries in the network logging
|
|
309
|
+
* @param serverErrorMessage The `serverErrorMessage` parameter in the `networkLogAndroid` method is
|
|
310
|
+
* used to pass any error message received from the server during network communication. This message
|
|
311
|
+
* can provide additional details about any errors that occurred on the server side, helping in
|
|
312
|
+
* debugging and troubleshooting network-related issues.
|
|
313
|
+
*/
|
|
310
314
|
@ReactMethod
|
|
311
315
|
private void networkLogAndroid(final double requestStartTime,
|
|
312
316
|
final double requestDuration,
|
|
@@ -325,15 +329,16 @@ public class RNLuciqAPMModule extends EventEmitterModule {
|
|
|
325
329
|
@Nullable final ReadableMap w3cAttributes,
|
|
326
330
|
@Nullable final String gqLCQueryName,
|
|
327
331
|
@Nullable final String serverErrorMessage
|
|
328
|
-
|
|
332
|
+
) {
|
|
333
|
+
Log.d(NET_TAG, "[networkLogAndroid-APM] Received from JS: " + requestMethod + " " + requestUrl + ", status=" + (int) statusCode + ", duration=" + (long) requestDuration + "ms, startTime=" + (long) requestStartTime + ", error=" + errorDomain + ", gqlQuery=" + gqLCQueryName);
|
|
329
334
|
try {
|
|
330
335
|
APMNetworkLogger networkLogger = new APMNetworkLogger();
|
|
331
336
|
|
|
332
337
|
final boolean hasError = errorDomain != null && !errorDomain.isEmpty();
|
|
333
338
|
final String errorMessage = hasError ? errorDomain : null;
|
|
334
|
-
Boolean isW3cHeaderFound=false;
|
|
335
|
-
Long partialId=null;
|
|
336
|
-
Long networkStartTimeInSeconds=null;
|
|
339
|
+
Boolean isW3cHeaderFound = false;
|
|
340
|
+
Long partialId = null;
|
|
341
|
+
Long networkStartTimeInSeconds = null;
|
|
337
342
|
|
|
338
343
|
|
|
339
344
|
try {
|
|
@@ -342,13 +347,15 @@ public class RNLuciqAPMModule extends EventEmitterModule {
|
|
|
342
347
|
}
|
|
343
348
|
|
|
344
349
|
if (!w3cAttributes.isNull("partialId")) {
|
|
345
|
-
partialId =(long) w3cAttributes.getDouble("partialId");
|
|
350
|
+
partialId = (long) w3cAttributes.getDouble("partialId");
|
|
346
351
|
networkStartTimeInSeconds = (long) w3cAttributes.getDouble("networkStartTimeInSeconds");
|
|
347
352
|
}
|
|
348
353
|
|
|
349
354
|
} catch (Exception e) {
|
|
355
|
+
Log.e(NET_TAG, "[networkLogAndroid-APM] Error parsing W3C attributes for " + requestMethod + " " + requestUrl, e);
|
|
350
356
|
e.printStackTrace();
|
|
351
357
|
}
|
|
358
|
+
Log.d(NET_TAG, "[networkLogAndroid-APM] W3C attrs — isW3cHeaderFound=" + isW3cHeaderFound + ", partialId=" + partialId + ", networkStartTimeInSeconds=" + networkStartTimeInSeconds + ", generatedHeader=" + (w3cAttributes != null && !w3cAttributes.isNull("w3cGeneratedHeader") ? w3cAttributes.getString("w3cGeneratedHeader") : "null") + ", caughtHeader=" + (w3cAttributes != null && !w3cAttributes.isNull("w3cCaughtHeader") ? w3cAttributes.getString("w3cCaughtHeader") : "null"));
|
|
352
359
|
APMCPNetworkLog.W3CExternalTraceAttributes w3cExternalTraceAttributes =
|
|
353
360
|
new APMCPNetworkLog.W3CExternalTraceAttributes(
|
|
354
361
|
isW3cHeaderFound,
|
|
@@ -360,52 +367,139 @@ public class RNLuciqAPMModule extends EventEmitterModule {
|
|
|
360
367
|
try {
|
|
361
368
|
Method method = getMethod(Class.forName("ai.luciq.apm.networking.APMNetworkLogger"), "log", long.class, long.class, String.class, String.class, long.class, String.class, String.class, String.class, String.class, String.class, long.class, int.class, String.class, String.class, String.class, String.class, APMCPNetworkLog.W3CExternalTraceAttributes.class);
|
|
362
369
|
if (method != null) {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
370
|
+
method.invoke(
|
|
371
|
+
networkLogger,
|
|
372
|
+
(long) requestStartTime * 1000,
|
|
373
|
+
(long) requestDuration,
|
|
374
|
+
requestHeaders,
|
|
375
|
+
requestBody,
|
|
376
|
+
(long) requestBodySize,
|
|
377
|
+
requestMethod,
|
|
378
|
+
requestUrl,
|
|
379
|
+
requestContentType,
|
|
380
|
+
responseHeaders,
|
|
381
|
+
responseBody,
|
|
382
|
+
(long) responseBodySize,
|
|
383
|
+
(int) statusCode,
|
|
384
|
+
responseContentType,
|
|
385
|
+
errorMessage,
|
|
386
|
+
gqLCQueryName,
|
|
387
|
+
serverErrorMessage,
|
|
388
|
+
w3cExternalTraceAttributes
|
|
389
|
+
);
|
|
390
|
+
Log.d(NET_TAG, "[networkLogAndroid-APM] Successfully invoked APMNetworkLogger.log via reflection: " + requestMethod + " " + requestUrl);
|
|
383
391
|
} else {
|
|
392
|
+
Log.e(NET_TAG, "[networkLogAndroid-APM] APMNetworkLogger.log method NOT found by reflection — network log will be lost: " + requestMethod + " " + requestUrl);
|
|
384
393
|
Log.e("IB-CP-Bridge", "APMNetworkLogger.log was not found by reflection");
|
|
385
394
|
}
|
|
386
395
|
} catch (Throwable e) {
|
|
396
|
+
Log.e(NET_TAG, "[networkLogAndroid-APM] Exception invoking APMNetworkLogger.log: " + e.getMessage() + " for " + requestMethod + " " + requestUrl, e);
|
|
387
397
|
e.printStackTrace();
|
|
388
398
|
}
|
|
389
|
-
} catch(Throwable e) {
|
|
399
|
+
} catch (Throwable e) {
|
|
400
|
+
Log.e(NET_TAG, "[networkLogAndroid-APM] Top-level exception: " + e.getMessage() + " for " + requestMethod + " " + requestUrl, e);
|
|
390
401
|
e.printStackTrace();
|
|
391
402
|
}
|
|
392
403
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Enables or disables screen rendering
|
|
407
|
+
*
|
|
408
|
+
* @param isEnabled boolean indicating enabled or disabled.
|
|
409
|
+
*/
|
|
410
|
+
@ReactMethod
|
|
411
|
+
public void setScreenRenderingEnabled(boolean isEnabled) {
|
|
412
|
+
MainThreadHandler.runOnMainThread(new Runnable() {
|
|
413
|
+
@Override
|
|
414
|
+
public void run() {
|
|
415
|
+
try {
|
|
416
|
+
APM.setScreenRenderingEnabled(isEnabled);
|
|
417
|
+
} catch (Exception e) {
|
|
418
|
+
e.printStackTrace();
|
|
408
419
|
}
|
|
409
|
-
}
|
|
410
|
-
}
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Syncs a custom span to the native SDK (currently logs only).
|
|
426
|
+
*
|
|
427
|
+
* @param name Name of the custom span
|
|
428
|
+
* @param startTimestamp Start time in microseconds since epoch
|
|
429
|
+
* @param endTimestamp End time in microseconds since epoch
|
|
430
|
+
* @param promise Promise to resolve when complete
|
|
431
|
+
*/
|
|
432
|
+
@ReactMethod
|
|
433
|
+
public void syncCustomSpan(final String name,
|
|
434
|
+
final double startTimestamp,
|
|
435
|
+
final double endTimestamp,
|
|
436
|
+
final Promise promise) {
|
|
437
|
+
MainThreadHandler.runOnMainThread(new Runnable() {
|
|
438
|
+
@Override
|
|
439
|
+
public void run() {
|
|
440
|
+
try {
|
|
441
|
+
// Convert microseconds to milliseconds for Date objects
|
|
442
|
+
Date startDate = new Date((long) (startTimestamp / 1000));
|
|
443
|
+
Date endDate = new Date((long) (endTimestamp / 1000));
|
|
444
|
+
|
|
445
|
+
APM.addCompletedCustomSpan(name, startDate, endDate);
|
|
446
|
+
|
|
447
|
+
promise.resolve(true);
|
|
448
|
+
} catch (Exception e) {
|
|
449
|
+
Log.e("IB-CP-Bridge", "Error syncing span", e);
|
|
450
|
+
promise.resolve(false);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Checks if custom spans feature is enabled.
|
|
458
|
+
*
|
|
459
|
+
* @param promise Promise that resolves with boolean indicating if enabled
|
|
460
|
+
*/
|
|
461
|
+
@ReactMethod
|
|
462
|
+
public void isCustomSpanEnabled(final Promise promise) {
|
|
463
|
+
MainThreadHandler.runOnMainThread(new Runnable() {
|
|
464
|
+
@Override
|
|
465
|
+
public void run() {
|
|
466
|
+
try {
|
|
467
|
+
InternalAPM._isFeatureEnabledCP(APMFeature.CUSTOM_SPANS, "LuciqCustomSpan", new FeatureAvailabilityCallback() {
|
|
468
|
+
@Override
|
|
469
|
+
public void invoke(boolean isEnabled) {
|
|
470
|
+
promise.resolve(isEnabled);
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
} catch (Exception e) {
|
|
474
|
+
Log.e("IB-CP-Bridge", "Error checking feature flag", e);
|
|
475
|
+
promise.resolve(false);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Checks if APM is enabled.
|
|
483
|
+
*
|
|
484
|
+
* @param promise Promise that resolves with boolean indicating if enabled
|
|
485
|
+
*/
|
|
486
|
+
@ReactMethod
|
|
487
|
+
public void isAPMEnabled(final Promise promise) {
|
|
488
|
+
MainThreadHandler.runOnMainThread(new Runnable() {
|
|
489
|
+
@Override
|
|
490
|
+
public void run() {
|
|
491
|
+
try {
|
|
492
|
+
InternalAPM._isFeatureEnabledCP(APMFeature.APM, "APM", new FeatureAvailabilityCallback() {
|
|
493
|
+
@Override
|
|
494
|
+
public void invoke(boolean isEnabled) {
|
|
495
|
+
promise.resolve(isEnabled);
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
} catch (Exception e) {
|
|
499
|
+
Log.e("IB-CP-Bridge", "Error checking APM enabled", e);
|
|
500
|
+
promise.resolve(false);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
}
|
|
411
505
|
}
|