@luciq/react-native 19.6.0 → 19.7.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 +12 -0
- package/README.md +174 -111
- package/android/native.gradle +1 -1
- package/android/proguard-rules.txt +1 -1
- package/android/src/main/java/ai/luciq/reactlibrary/Constants.java +3 -0
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqAPMModule.java +13 -5
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerModule.java +29 -9
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqReactnativeModule.java +139 -118
- package/android/src/main/java/ai/luciq/reactlibrary/utils/EventEmitterModule.java +5 -0
- package/android/src/main/java/ai/luciq/reactlibrary/utils/LuciqRNLogger.java +53 -0
- package/dist/modules/Luciq.js +10 -1
- package/dist/modules/NetworkLogger.d.ts +0 -5
- package/dist/modules/NetworkLogger.js +9 -1
- package/dist/utils/FeatureFlags.d.ts +6 -0
- package/dist/utils/FeatureFlags.js +35 -0
- package/dist/utils/LuciqUtils.js +7 -0
- package/dist/utils/XhrNetworkInterceptor.js +85 -53
- package/ios/RNLuciq/LuciqNetworkLoggerBridge.m +30 -6
- package/ios/RNLuciq/LuciqReactBridge.m +21 -4
- package/ios/RNLuciq/Util/LuciqRNLogger.h +32 -0
- package/ios/RNLuciq/Util/LuciqRNLogger.m +57 -0
- package/ios/native.rb +1 -1
- package/package.json +1 -1
- package/src/modules/Luciq.ts +13 -1
- package/src/modules/NetworkLogger.ts +26 -1
- package/src/utils/FeatureFlags.ts +44 -0
- package/src/utils/LuciqUtils.ts +20 -0
- package/src/utils/XhrNetworkInterceptor.ts +128 -55
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [19.7.0](https://github.com/luciqai/luciq-reactnative-sdk/compare/v19.7.0...19.6.0)
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Fix NetworkLogger late initialization on Android.
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Bump Luciq iOS SDK to v19.7.0 ([#54](https://github.com/luciqai/luciq-reactnative-sdk/pull/49)). [See release notes](https://github.com/luciqai/luciq-ios-sdk/releases/tag/19.7.0).
|
|
12
|
+
|
|
13
|
+
- Bump Luciq Android SDK to v19.7.0 ([#54](https://github.com/luciqai/luciq-reactnative-sdk/pull/49)). [See release notes](https://github.com/luciqai/luciq-android-sdk/releases/tag/v19.7.0).
|
|
14
|
+
|
|
3
15
|
## [19.6.0](https://github.com/luciqai/luciq-reactnative-sdk/compare/v19.6.0...19.4.0)
|
|
4
16
|
|
|
5
17
|
### Added
|
package/README.md
CHANGED
|
@@ -1,48 +1,82 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src=".github/assets/luciq-logo.png" alt="Luciq" width="120" />
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
[](https://www.npmjs.com/package/@luciq/react-native)
|
|
5
|
-
[](https://github.com/luciqai/luciq-reactnative-sdk/blob/master/LICENSE)
|
|
6
|
-
[](https://twitter.com/Luciqai)
|
|
7
|
-
[](https://luciq.ai)
|
|
4
|
+
<p><strong>🚀 The Agentic Observability Platform built for Mobile</strong></p>
|
|
8
5
|
|
|
9
|
-
|
|
6
|
+
[](https://www.npmjs.com/package/@luciq/react-native)
|
|
7
|
+
[](https://www.npmjs.com/package/@luciq/react-native)
|
|
8
|
+
[](https://www.npmjs.com/package/@luciq/react-native)
|
|
9
|
+
[](https://github.com/luciqai/luciq-reactnative-sdk/blob/master/LICENSE)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
<br />
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Our intelligent AI agents help you capture rich, contextual data for every issue, including full session replays, console logs, and detailed network requests, to proactively detect, prioritize, and resolve problems automatically.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
<strong>Ship faster, deliver frustration-free user sessions, and focus on building what matters.</strong>
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
</div>
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
---
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
## Table of Contents
|
|
22
|
+
|
|
23
|
+
- [Requirements](#requirements)
|
|
24
|
+
- [Installation](#installation)
|
|
25
|
+
- [Initializing Luciq](#initializing-luciq)
|
|
26
|
+
- [iOS Usage Descriptions](#ios-usage-descriptions)
|
|
27
|
+
- [Source Map Uploads for Crash Reports](#source-map-uploads-for-crash-reports)
|
|
28
|
+
- [Network Logging](#network-logging)
|
|
29
|
+
- [Repro Steps](#repro-steps)
|
|
30
|
+
- [React Navigation](#react-navigation)
|
|
31
|
+
- [React Native Navigation (Wix)](#react-native-navigation-wix)
|
|
32
|
+
- [Manual screen reporting](#manual-screen-reporting)
|
|
33
|
+
- [Disabling Repro Steps](#disabling-repro-steps)
|
|
34
|
+
- [Custom Spans (APM)](#custom-spans-apm)
|
|
35
|
+
- [Start / end a span](#start--end-a-span)
|
|
36
|
+
- [Record a completed span](#record-a-completed-span)
|
|
37
|
+
- [Behavior](#behavior)
|
|
38
|
+
- [API reference](#api-reference)
|
|
39
|
+
- [TypeScript](#typescript)
|
|
40
|
+
- [Support](#support)
|
|
41
|
+
|
|
42
|
+
---
|
|
24
43
|
|
|
25
|
-
|
|
44
|
+
## Requirements
|
|
45
|
+
|
|
46
|
+
- React Native `>= 0.72.3`
|
|
47
|
+
- iOS `>= 13.4`
|
|
48
|
+
- Android `minSdkVersion >= 21`
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
1. Install the package:
|
|
26
53
|
|
|
27
54
|
```bash
|
|
55
|
+
npm install @luciq/react-native
|
|
56
|
+
# or
|
|
28
57
|
yarn add @luciq/react-native
|
|
29
58
|
```
|
|
30
59
|
|
|
31
|
-
2.
|
|
60
|
+
2. **Expo only.** Add the Luciq config plugin to `app.json`:
|
|
32
61
|
|
|
33
62
|
```json
|
|
34
|
-
|
|
63
|
+
{
|
|
64
|
+
"expo": {
|
|
65
|
+
"plugins": [
|
|
35
66
|
[
|
|
36
67
|
"@luciq/react-native",
|
|
37
68
|
{
|
|
38
|
-
// optional that add Mic,Photo permission on iOS and FOREGROUND_SERVICE_MEDIA_PROJECTION on android
|
|
39
69
|
"addScreenRecordingBugReportingPermission": true
|
|
40
70
|
}
|
|
41
71
|
]
|
|
42
|
-
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
43
75
|
```
|
|
44
76
|
|
|
45
|
-
|
|
77
|
+
`addScreenRecordingBugReportingPermission` is optional — when `true`, the plugin adds the iOS microphone & photo-library usage descriptions and the Android `FOREGROUND_SERVICE_MEDIA_PROJECTION` permission required for screen recording in bug reports.
|
|
78
|
+
|
|
79
|
+
3. **iOS only.** Install CocoaPods:
|
|
46
80
|
|
|
47
81
|
```bash
|
|
48
82
|
cd ios && pod install && cd ..
|
|
@@ -50,184 +84,213 @@ For more info, visit Luciq.ai.
|
|
|
50
84
|
|
|
51
85
|
## Initializing Luciq
|
|
52
86
|
|
|
53
|
-
|
|
87
|
+
Call `Luciq.init` once, as early as possible — at the top of your entry file (`index.js` or `App.tsx`), outside any component. `InvocationEvent` is a named export, not a property on the default `Luciq` namespace.
|
|
54
88
|
|
|
55
|
-
```
|
|
56
|
-
import Luciq from '@luciq/react-native';
|
|
89
|
+
```ts
|
|
90
|
+
import Luciq, { InvocationEvent } from '@luciq/react-native';
|
|
57
91
|
|
|
58
92
|
Luciq.init({
|
|
59
93
|
token: 'APP_TOKEN',
|
|
60
|
-
invocationEvents: [
|
|
94
|
+
invocationEvents: [InvocationEvent.shake],
|
|
61
95
|
});
|
|
62
96
|
```
|
|
63
97
|
|
|
64
|
-
|
|
98
|
+
You can combine multiple invocation events:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
Luciq.init({
|
|
102
|
+
token: 'APP_TOKEN',
|
|
103
|
+
invocationEvents: [
|
|
104
|
+
InvocationEvent.shake,
|
|
105
|
+
InvocationEvent.screenshot,
|
|
106
|
+
InvocationEvent.floatingButton,
|
|
107
|
+
],
|
|
108
|
+
});
|
|
109
|
+
```
|
|
65
110
|
|
|
66
|
-
|
|
111
|
+
Available `InvocationEvent` values: `shake`, `screenshot`, `twoFingersSwipe`, `floatingButton`, `none`.
|
|
67
112
|
|
|
68
|
-
|
|
113
|
+
Find your app token in your [**Luciq dashboard**](https://dashboard.luciq.ai) under **Settings → SDK Integration**.
|
|
69
114
|
|
|
70
|
-
|
|
115
|
+
## iOS Usage Descriptions
|
|
116
|
+
|
|
117
|
+
Luciq needs microphone access to capture audio during screen recordings, and photo-library access to let users attach images to bug reports. Apple rejects apps that omit usage descriptions for either, so add the following keys to your app's `Info.plist`:
|
|
71
118
|
|
|
72
119
|
- `NSMicrophoneUsageDescription`
|
|
73
120
|
- `NSPhotoLibraryUsageDescription`
|
|
74
121
|
|
|
75
|
-
|
|
122
|
+
Suggested copy:
|
|
76
123
|
|
|
77
|
-
- "`<app name>` needs access to
|
|
78
|
-
- "`<app name>` needs
|
|
124
|
+
- _"`<app name>` needs microphone access to record audio with screen recordings attached to bug reports."_
|
|
125
|
+
- _"`<app name>` needs photo-library access to attach images to bug reports."_
|
|
79
126
|
|
|
80
|
-
|
|
127
|
+
The permission prompts only appear when a user actually starts a screen recording or attaches a photo from the Luciq UI.
|
|
81
128
|
|
|
82
|
-
##
|
|
129
|
+
## Source Map Uploads for Crash Reports
|
|
83
130
|
|
|
84
|
-
For your app crashes to show
|
|
131
|
+
For your app crashes to show fully symbolicated stack traces, the build scripts in `@luciq/react-native` will generate and upload source maps to your dashboard on release builds. The uploader reads your app token from the `Luciq.init({ token: 'YOUR_APP_TOKEN' })` call in JavaScript.
|
|
85
132
|
|
|
86
|
-
If your
|
|
87
|
-
We also automatically read your `versionName` and `versionCode` to upload your sourcemap file. alternatively, can also set the environment variables `LUCIQ_APP_VERSION_NAME` and `LUCIQ_APP_VERSION_CODE` to be used instead.
|
|
133
|
+
If your token is defined as a constant or imported from elsewhere, override the lookup with environment variables:
|
|
88
134
|
|
|
89
|
-
|
|
135
|
+
| Variable | Purpose |
|
|
136
|
+
| --------------------------------- | ------------------------------------- |
|
|
137
|
+
| `LUCIQ_APP_TOKEN` | App token used for the upload |
|
|
138
|
+
| `LUCIQ_APP_VERSION_NAME` | Overrides the inferred `versionName` |
|
|
139
|
+
| `LUCIQ_APP_VERSION_CODE` | Overrides the inferred `versionCode` |
|
|
140
|
+
| `LUCIQ_SOURCEMAPS_UPLOAD_DISABLE` | Set to `TRUE` to skip the upload step |
|
|
90
141
|
|
|
91
142
|
## Network Logging
|
|
92
143
|
|
|
93
|
-
|
|
144
|
+
Network logging is enabled by default. It intercepts `fetch` and `XMLHttpRequest` calls and attaches them to outgoing reports. Disable it with:
|
|
94
145
|
|
|
95
|
-
```
|
|
146
|
+
```ts
|
|
96
147
|
import { NetworkLogger } from '@luciq/react-native';
|
|
97
|
-
```
|
|
98
148
|
|
|
99
|
-
```javascript
|
|
100
149
|
NetworkLogger.setEnabled(false);
|
|
101
150
|
```
|
|
102
151
|
|
|
103
152
|
## Repro Steps
|
|
104
153
|
|
|
105
|
-
Luciq Repro Steps
|
|
154
|
+
Luciq Repro Steps record the screens a user visits. Each screen is attached to a bug report when it's sent. Repro Steps are enabled by default.
|
|
106
155
|
|
|
107
|
-
|
|
156
|
+
### React Navigation
|
|
108
157
|
|
|
109
|
-
|
|
110
|
-
- **v5**
|
|
111
|
-
set the `onStateChange` to `Luciq.onStateChange` in your NavigationContainer as follows:
|
|
158
|
+
**v5+** — pass `Luciq.onStateChange` to your `NavigationContainer`:
|
|
112
159
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
160
|
+
```tsx
|
|
161
|
+
import { NavigationContainer } from '@react-navigation/native';
|
|
162
|
+
import Luciq from '@luciq/react-native';
|
|
116
163
|
|
|
117
|
-
|
|
118
|
-
|
|
164
|
+
<NavigationContainer onStateChange={Luciq.onStateChange}>{/* ... */}</NavigationContainer>;
|
|
165
|
+
```
|
|
119
166
|
|
|
120
|
-
|
|
121
|
-
export default () => <App onNavigationStateChange={Luciq.onNavigationStateChange} />;
|
|
122
|
-
```
|
|
167
|
+
**v4 and below** — wire `Luciq.onNavigationStateChange` to the root app:
|
|
123
168
|
|
|
124
|
-
|
|
169
|
+
```tsx
|
|
170
|
+
export default () => <App onNavigationStateChange={Luciq.onNavigationStateChange} />;
|
|
171
|
+
```
|
|
125
172
|
|
|
126
|
-
|
|
173
|
+
### React Native Navigation (Wix)
|
|
127
174
|
|
|
128
|
-
|
|
129
|
-
Navigation.events().registerComponentDidAppearListener(luciq.aiponentDidAppearListener);
|
|
130
|
-
```
|
|
175
|
+
Register `Luciq.componentDidAppearListener`:
|
|
131
176
|
|
|
132
|
-
|
|
177
|
+
```ts
|
|
178
|
+
import { Navigation } from 'react-native-navigation';
|
|
179
|
+
import Luciq from '@luciq/react-native';
|
|
180
|
+
|
|
181
|
+
Navigation.events().registerComponentDidAppearListener(Luciq.componentDidAppearListener);
|
|
182
|
+
```
|
|
133
183
|
|
|
134
|
-
|
|
135
|
-
|
|
184
|
+
### Manual screen reporting
|
|
185
|
+
|
|
186
|
+
For custom navigation, report screen changes yourself:
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
Luciq.reportScreenChange('CheckoutScreen');
|
|
136
190
|
```
|
|
137
191
|
|
|
138
|
-
|
|
192
|
+
### Disabling Repro Steps
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
import Luciq, { ReproStepsMode } from '@luciq/react-native';
|
|
139
196
|
|
|
140
|
-
```javascript
|
|
141
197
|
Luciq.setReproStepsConfig({ all: ReproStepsMode.disabled });
|
|
142
198
|
```
|
|
143
199
|
|
|
144
|
-
|
|
200
|
+
`ReproStepsMode` values: `enabled`, `enabledWithNoScreenshots`, `disabled`.
|
|
145
201
|
|
|
146
|
-
Custom
|
|
202
|
+
## Custom Spans (APM)
|
|
147
203
|
|
|
148
|
-
|
|
204
|
+
Custom spans let you manually instrument arbitrary code paths for performance tracking — useful for operations that aren't covered by the automatic instrumentation.
|
|
149
205
|
|
|
150
|
-
|
|
206
|
+
### Start / end a span
|
|
207
|
+
|
|
208
|
+
```ts
|
|
151
209
|
import { APM } from '@luciq/react-native';
|
|
152
210
|
|
|
153
|
-
// Start a custom span
|
|
154
211
|
const span = await APM.startCustomSpan('Load User Profile');
|
|
155
212
|
|
|
156
213
|
if (span) {
|
|
157
214
|
try {
|
|
158
|
-
// Perform your operation
|
|
159
215
|
await loadUserProfile();
|
|
160
216
|
} finally {
|
|
161
|
-
// Always end the span, even if operation fails
|
|
162
217
|
await span.end();
|
|
163
218
|
}
|
|
164
219
|
}
|
|
165
220
|
```
|
|
166
221
|
|
|
167
|
-
###
|
|
222
|
+
### Record a completed span
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
import { APM } from '@luciq/react-native';
|
|
168
226
|
|
|
169
|
-
|
|
170
|
-
const start = new Date();
|
|
171
|
-
// ... operation already completed ...
|
|
227
|
+
const start = new Date(Date.now() - 1500);
|
|
172
228
|
const end = new Date();
|
|
173
229
|
|
|
174
230
|
await APM.addCompletedCustomSpan('Cache Lookup', start, end);
|
|
175
231
|
```
|
|
176
232
|
|
|
177
|
-
###
|
|
233
|
+
### Behavior
|
|
178
234
|
|
|
179
|
-
- **
|
|
180
|
-
- **Name
|
|
181
|
-
- **
|
|
182
|
-
- **Idempotent
|
|
183
|
-
- **
|
|
235
|
+
- **Limit:** up to 100 concurrent spans at a time.
|
|
236
|
+
- **Name length:** truncated to 150 characters; empty names are rejected.
|
|
237
|
+
- **Timestamps:** `endDate` must be after `startDate`; otherwise the span is rejected.
|
|
238
|
+
- **Idempotent:** calling `span.end()` more than once is safe.
|
|
239
|
+
- **Gating:** spans are only created when the SDK is initialized, APM is enabled, and the custom-spans feature is enabled for your account.
|
|
184
240
|
|
|
185
|
-
### API
|
|
241
|
+
### API reference
|
|
186
242
|
|
|
187
243
|
#### `APM.startCustomSpan(name: string): Promise<CustomSpan | null>`
|
|
188
244
|
|
|
189
|
-
Starts a custom span
|
|
245
|
+
Starts a custom span. Returns the span object, or `null` if the span couldn't be created (e.g. feature disabled, span cap reached, invalid name).
|
|
246
|
+
|
|
247
|
+
#### `CustomSpan.end(): Promise<void>`
|
|
190
248
|
|
|
191
|
-
|
|
249
|
+
Ends the span and reports it. Idempotent.
|
|
192
250
|
|
|
193
|
-
|
|
251
|
+
#### `APM.addCompletedCustomSpan(name: string, startDate: Date, endDate: Date): Promise<void>`
|
|
194
252
|
|
|
195
|
-
|
|
253
|
+
Records a span whose start and end times are already known.
|
|
196
254
|
|
|
197
|
-
|
|
255
|
+
## TypeScript
|
|
198
256
|
|
|
199
|
-
|
|
257
|
+
The package ships with type definitions. The public surface is exposed as:
|
|
200
258
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
259
|
+
- `Luciq` (default export) — top-level SDK actions: `init`, `onStateChange`, `onNavigationStateChange`, `componentDidAppearListener`, `reportScreenChange`, `setReproStepsConfig`, and many more.
|
|
260
|
+
- Named modules: `APM`, `BugReporting`, `CrashReporting`, `FeatureRequests`, `NetworkLogger`, `Replies`, `SessionReplay`, `Surveys`.
|
|
261
|
+
- Named enums: `InvocationEvent`, `ReproStepsMode`, `LogLevel`, `NetworkInterceptionMode`, `Locale`, `ColorTheme`, `WelcomeMessageMode`, `ExtendedBugReportMode`, `NonFatalErrorLevel`, and more.
|
|
262
|
+
- Named types: `LuciqConfig`, `ThemeConfig`, `NetworkData`, `Survey`, `SessionMetadata`.
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
import Luciq, {
|
|
266
|
+
APM,
|
|
267
|
+
BugReporting,
|
|
268
|
+
CrashReporting,
|
|
269
|
+
InvocationEvent,
|
|
270
|
+
NetworkLogger,
|
|
271
|
+
ReproStepsMode,
|
|
272
|
+
type LuciqConfig,
|
|
273
|
+
} from '@luciq/react-native';
|
|
207
274
|
```
|
|
208
275
|
|
|
209
|
-
|
|
276
|
+
## Support
|
|
210
277
|
|
|
211
|
-
|
|
278
|
+
<div align="center">
|
|
212
279
|
|
|
213
|
-
|
|
280
|
+
### Need Help?
|
|
214
281
|
|
|
215
|
-
|
|
282
|
+
🌐 **[Visit our website](https://luciq.ai)** • 📖 **[Read the docs](https://docs.luciq.ai/)** • 💬 **[Get help](https://help.luciq.ai)**
|
|
216
283
|
|
|
217
|
-
|
|
284
|
+
### Contact Us
|
|
218
285
|
|
|
219
|
-
|
|
220
|
-
- `startDate` (Date): The start time of the operation.
|
|
221
|
-
- `endDate` (Date): The end time of the operation (must be after startDate).
|
|
286
|
+
**Primary Contact Email:** [support@luciq.ai](mailto:support@luciq.ai)
|
|
222
287
|
|
|
223
|
-
**
|
|
288
|
+
**LinkedIn:** [linkedin.com/company/luciq](https://linkedin.com/company/luciq)
|
|
224
289
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
await APM.addCompletedCustomSpan('Background Task', start, end);
|
|
229
|
-
```
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
<p>Made with ❤️ by the Luciq team</p>
|
|
230
293
|
|
|
231
|
-
|
|
294
|
+
<img src=".github/assets/luciq-logo.png" alt="Luciq" width="60" />
|
|
232
295
|
|
|
233
|
-
|
|
296
|
+
</div>
|
package/android/native.gradle
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
-keep class
|
|
1
|
+
-keep class ai.luciq.** {*;}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
package ai.luciq.reactlibrary;
|
|
2
2
|
|
|
3
|
+
import static ai.luciq.reactlibrary.Constants.Bridge_TAG;
|
|
4
|
+
import static ai.luciq.reactlibrary.Constants.NET_TAG;
|
|
3
5
|
import static ai.luciq.reactlibrary.utils.LuciqUtil.getMethod;
|
|
4
6
|
|
|
5
7
|
import android.os.SystemClock;
|
|
6
|
-
import android.util.Log;
|
|
7
8
|
|
|
8
9
|
import androidx.annotation.NonNull;
|
|
9
10
|
import androidx.annotation.Nullable;
|
|
@@ -27,6 +28,7 @@ import ai.luciq.apm.configuration.cp.FeatureAvailabilityCallback;
|
|
|
27
28
|
import ai.luciq.apm.networking.APMNetworkLogger;
|
|
28
29
|
import ai.luciq.apm.networkinterception.cp.APMCPNetworkLog;
|
|
29
30
|
import ai.luciq.reactlibrary.utils.EventEmitterModule;
|
|
31
|
+
import ai.luciq.reactlibrary.utils.LuciqRNLogger;
|
|
30
32
|
import ai.luciq.reactlibrary.utils.MainThreadHandler;
|
|
31
33
|
|
|
32
34
|
public class RNLuciqAPMModule extends EventEmitterModule {
|
|
@@ -328,6 +330,7 @@ public class RNLuciqAPMModule extends EventEmitterModule {
|
|
|
328
330
|
@Nullable final String gqLCQueryName,
|
|
329
331
|
@Nullable final String serverErrorMessage
|
|
330
332
|
) {
|
|
333
|
+
LuciqRNLogger.d(NET_TAG, "[networkLogAndroid-APM] Received from JS: " + requestMethod + " " + requestUrl + ", status=" + (int) statusCode + ", duration=" + (long) requestDuration + "ms, startTime=" + (long) requestStartTime + ", error=" + errorDomain + ", gqlQuery=" + gqLCQueryName);
|
|
331
334
|
try {
|
|
332
335
|
APMNetworkLogger networkLogger = new APMNetworkLogger();
|
|
333
336
|
|
|
@@ -349,8 +352,10 @@ public class RNLuciqAPMModule extends EventEmitterModule {
|
|
|
349
352
|
}
|
|
350
353
|
|
|
351
354
|
} catch (Exception e) {
|
|
355
|
+
LuciqRNLogger.e(NET_TAG, "[networkLogAndroid-APM] Error parsing W3C attributes for " + requestMethod + " " + requestUrl, e);
|
|
352
356
|
e.printStackTrace();
|
|
353
357
|
}
|
|
358
|
+
LuciqRNLogger.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"));
|
|
354
359
|
APMCPNetworkLog.W3CExternalTraceAttributes w3cExternalTraceAttributes = new APMCPNetworkLog.W3CExternalTraceAttributes(isW3cHeaderFound, partialId, networkStartTimeInSeconds, w3cAttributes.getString("w3cGeneratedHeader"), w3cAttributes.getString("w3cCaughtHeader"));
|
|
355
360
|
try {
|
|
356
361
|
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);
|
|
@@ -375,13 +380,16 @@ public class RNLuciqAPMModule extends EventEmitterModule {
|
|
|
375
380
|
serverErrorMessage,
|
|
376
381
|
w3cExternalTraceAttributes
|
|
377
382
|
);
|
|
383
|
+
LuciqRNLogger.d(NET_TAG, "[networkLogAndroid-APM] Successfully invoked APMNetworkLogger.log via reflection: " + requestMethod + " " + requestUrl);
|
|
378
384
|
} else {
|
|
379
|
-
|
|
385
|
+
LuciqRNLogger.e(NET_TAG, "[networkLogAndroid-APM] APMNetworkLogger.log method NOT found by reflection — network log will be lost: " + requestMethod + " " + requestUrl);
|
|
380
386
|
}
|
|
381
387
|
} catch (Throwable e) {
|
|
388
|
+
LuciqRNLogger.e(NET_TAG, "[networkLogAndroid-APM] Exception invoking APMNetworkLogger.log: " + e.getMessage() + " for " + requestMethod + " " + requestUrl, e);
|
|
382
389
|
e.printStackTrace();
|
|
383
390
|
}
|
|
384
391
|
} catch (Throwable e) {
|
|
392
|
+
LuciqRNLogger.e(NET_TAG, "[networkLogAndroid-APM] Top-level exception: " + e.getMessage() + " for " + requestMethod + " " + requestUrl, e);
|
|
385
393
|
e.printStackTrace();
|
|
386
394
|
}
|
|
387
395
|
}
|
|
@@ -430,7 +438,7 @@ public class RNLuciqAPMModule extends EventEmitterModule {
|
|
|
430
438
|
|
|
431
439
|
promise.resolve(true);
|
|
432
440
|
} catch (Exception e) {
|
|
433
|
-
|
|
441
|
+
LuciqRNLogger.e(Bridge_TAG, "Error syncing span", e);
|
|
434
442
|
promise.resolve(false);
|
|
435
443
|
}
|
|
436
444
|
}
|
|
@@ -455,7 +463,7 @@ public class RNLuciqAPMModule extends EventEmitterModule {
|
|
|
455
463
|
}
|
|
456
464
|
});
|
|
457
465
|
} catch (Exception e) {
|
|
458
|
-
|
|
466
|
+
LuciqRNLogger.e(Bridge_TAG, "Error checking feature flag", e);
|
|
459
467
|
promise.resolve(false);
|
|
460
468
|
}
|
|
461
469
|
}
|
|
@@ -480,7 +488,7 @@ public class RNLuciqAPMModule extends EventEmitterModule {
|
|
|
480
488
|
}
|
|
481
489
|
});
|
|
482
490
|
} catch (Exception e) {
|
|
483
|
-
|
|
491
|
+
LuciqRNLogger.e(Bridge_TAG, "Error checking APM enabled", e);
|
|
484
492
|
promise.resolve(false);
|
|
485
493
|
}
|
|
486
494
|
}
|