Skip to content

Commit 87522e9

Browse files
a7medevabdelhamid-f-nasserkholood-eaahmedAlaaInstabug
authored
feat: add w3c traceparent header injection (#1288)
* feat(example): add apm screen (#1141) * fix(android): resolve an OOM in network logs (#1244) * fix(android): APM network logging(#1253) * fix(android): add W3C External Trace Attributes placeholder * chore: add CHANGLOG * chore: add CHANGLOG * fix: remove ios sub module * fix: use correct diff link for v13.0.0, v12.9.0 releases (#1198) * feat(ios): read env vars from .xcode.env in sourcemaps script (#1200) * feat(ios): read env vars from .xcode.env in sourcemaps script * chore: update xcode project * chore: update changelog * chore/update-podfile.lock * feat: add w3c header generator * ci:fix lint * ci:fix ios tests * feat:update header format * feat:update header format test case title * feat:Inject the W3C Header to Network Requests * ci:fix lint * feat:remove tracestate * feat: get feature flags from IOS * ci: fix ios test * fix: modify function naming * fix: update APM test cases * fix: update native test cases naming * feat(ios): w3c logs mapping * fix: export number partial id * fix: modify partial id generator function * fix: modify partial id generator test cases * feat(example): add network request generators buttons * ci: fix lint * ci(example): add missing import * feat(android): map apm network logs * feat(android): add W3C native modules & tests * feat: map w3c android native modules and test * feat: register w3c feature change listener * feat: add feature flags * feat: call updated feature flags * fix: update object assigning * fix: remove comment * fix: modify test cases naming * fix: generated header injection * fix: fix variable neames * fix: update test cases * fix(android): caught header null string * fix: update network log interface * fix (example): remove redundant button * feat (example): add Enable/Disable APM buttons * fix: add w3c Attributes to network logs tests * fix: fix imports * feat(android) : add w3c attributes to APM network Logs * chore: remove flipper * fix: adjust spacing * fix: update test case * feat: migrate-Feature-Flag-APM-method-to-Core * fix: js testcases * fix: js testcases * fix: js testcases * feat: add migrate APM into core in ios section * fix: js testcases * feat: add migrate APM into core in ios section * feat: add migrate APM into core in ios section * fix: Pr comments * fix: PR comment * fix: Pr comments * fix: added changelog item * fix: feature flag listener * fix: feature flag listener * feat: migrate w3c flags to APM core * feat(example): add apm screen (#1141) * fix(android): resolve an OOM in network logs (#1244) * fix(android): APM network logging(#1253) * fix(android): add W3C External Trace Attributes placeholder * chore: add CHANGLOG * chore: add CHANGLOG * fix: remove ios sub module * feat: export upload utils (#1252) * chore(example): remove flipper (#1259) * fix(android): pass network start time in microseconds (#1260) * fix: network timestamp in android side * fix: PR comments Co-authored-by: Ahmed Elrefaey <[email protected]> --------- Co-authored-by: Ahmed Elrefaey <[email protected]> * feat: support feature flags with variants (#1230) Jira ID: MOB-14684 --------- Co-authored-by: Ahmed Elrefaey <[email protected]> * chore(android): bump android sdk to v13.3.0 (#1261) * chore(ios): bump sdk to v13.3.0 (#1262) * release: v13.3.0 (#1263) * chore: remove duplicate app flows entries in changelog (#1264) * chore: remove duplicate execution traces deprecation in changelog (#1265) * feat: navigation tracking support with expo router (#1270) * feat: add screen tracker on screen change listener and tests * feat (example): add screen change listener * chore: enhance expo router tracking support (#1272) * ci: generalize enterprise releases (#1275) * ci: run tests before enterprise releases (#1271) * ci: publish snapshots to npm (#1274) * fix(ios): network log empty response body (#1273) * fix: drop non-error objects when reporting errors (#1279) * Fix: omitted non-error objects when logging errors * ci: publish snapshots to npm (#1274) * Fix: omitted non-error objects when logging errors * fix: use warn instead of logs Co-authored-by: Ahmed Elrefaey <[email protected]> * Update CHANGELOG.md Co-authored-by: Ahmed Elrefaey <[email protected]> * fix: merge issues --------- Co-authored-by: Ahmed Elrefaey <[email protected]> * feat: capture client error in the network interceptor (#1257) * feat/support-capture-client-error-in-xhr-requests --------- Co-authored-by: Abdelhamid Nasser <[email protected]> Co-authored-by: Ahmed Elrefaey <[email protected]> Co-authored-by: kholood <[email protected]> * fix: merge issues * fix: networkLogIOS test case * fix: merge issues * fix: merge issues * fix: merge issues * fix: merge issues * fix: merge issues * fix: remove logs * fix: refactore networkLogAndroid arguments * fix: merge issues * fix: merge issues * fix: move W3cExternalTraceAttributes to models * fix: return expected value type from bridge * fix: refactor method call * fix: refactor method name * fix: return expected value types of w3c flags * chore: refactor constant names * fix: pod file * fix(android): fix w3c caught header * fix (android): reporting network logs upon disabling w3c main feature flag * chore: add changelog --------- Co-authored-by: Abdelhamid Nasser <[email protected]> Co-authored-by: kholood <[email protected]> Co-authored-by: Ahmed alaa <[email protected]> Co-authored-by: ahmed alaa <[email protected]>
1 parent e7695f8 commit 87522e9

28 files changed

+837
-34
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## [Unreleased](https://github.com/Instabug/Instabug-React-Native/compare/v14.0.0...dev)
4+
5+
### Added
6+
7+
- Add support for tracing network requests from Instabug to services like Datadog and New Relic ([#1288](https://github.com/Instabug/Instabug-React-Native/pull/1288))
8+
39
## [14.0.0](https://github.com/Instabug/Instabug-React-Native/compare/v13.4.0...14.0.0) (November 19, 2024)
410

511
### Added

android/src/main/java/com/instabug/reactlibrary/Constants.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ final class Constants {
99

1010
final static String IBG_ON_NEW_MESSAGE_HANDLER = "IBGonNewMessageHandler";
1111
final static String IBG_ON_NEW_REPLY_RECEIVED_CALLBACK = "IBGOnNewReplyReceivedCallback";
12+
13+
final static String IBG_ON_NEW_W3C_FLAGS_UPDATE_RECEIVED_CALLBACK = "IBGOnNewW3CFlagsUpdateReceivedCallback";
14+
1215
final static String IBG_SESSION_REPLAY_ON_SYNC_CALLBACK_INVOCATION = "IBGSessionReplayOnSyncCallback";
1316

1417
}

android/src/main/java/com/instabug/reactlibrary/RNInstabugAPMModule.java

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,16 @@
99

1010
import com.facebook.react.bridge.Promise;
1111
import com.facebook.react.bridge.ReactApplicationContext;
12-
import com.facebook.react.bridge.ReactContextBaseJavaModule;
1312
import com.facebook.react.bridge.ReactMethod;
13+
import com.facebook.react.bridge.ReadableMap;
1414
import com.instabug.apm.APM;
1515
import com.instabug.apm.model.ExecutionTrace;
1616
import com.instabug.apm.networking.APMNetworkLogger;
1717
import com.instabug.apm.networkinterception.cp.APMCPNetworkLog;
18+
import com.instabug.reactlibrary.utils.EventEmitterModule;
19+
import com.instabug.apm.networkinterception.cp.APMCPNetworkLog;
1820
import com.instabug.reactlibrary.utils.MainThreadHandler;
1921

20-
import org.json.JSONException;
21-
import org.json.JSONObject;
22-
import java.lang.reflect.InvocationTargetException;
2322
import java.lang.reflect.Method;
2423

2524
import java.util.HashMap;
@@ -28,7 +27,7 @@
2827

2928
import static com.instabug.reactlibrary.utils.InstabugUtil.getMethod;
3029

31-
public class RNInstabugAPMModule extends ReactContextBaseJavaModule {
30+
public class RNInstabugAPMModule extends EventEmitterModule {
3231

3332
public RNInstabugAPMModule(ReactApplicationContext reactApplicationContext) {
3433
super(reactApplicationContext);
@@ -330,14 +329,41 @@ private void networkLogAndroid(final double requestStartTime,
330329
final double statusCode,
331330
final String responseContentType,
332331
@Nullable final String errorDomain,
332+
@Nullable final ReadableMap w3cAttributes,
333333
@Nullable final String gqlQueryName,
334-
@Nullable final String serverErrorMessage) {
334+
@Nullable final String serverErrorMessage
335+
) {
335336
try {
336337
APMNetworkLogger networkLogger = new APMNetworkLogger();
337338

338339
final boolean hasError = errorDomain != null && !errorDomain.isEmpty();
339340
final String errorMessage = hasError ? errorDomain : null;
341+
Boolean isW3cHeaderFound=false;
342+
Long partialId=null;
343+
Long networkStartTimeInSeconds=null;
344+
345+
346+
try {
347+
if (!w3cAttributes.isNull("isW3cHeaderFound")) {
348+
isW3cHeaderFound = w3cAttributes.getBoolean("isW3cHeaderFound");
349+
}
340350

351+
if (!w3cAttributes.isNull("partialId")) {
352+
partialId =(long) w3cAttributes.getDouble("partialId");
353+
networkStartTimeInSeconds = (long) w3cAttributes.getDouble("networkStartTimeInSeconds");
354+
}
355+
356+
} catch (Exception e) {
357+
e.printStackTrace();
358+
}
359+
APMCPNetworkLog.W3CExternalTraceAttributes w3cExternalTraceAttributes =
360+
new APMCPNetworkLog.W3CExternalTraceAttributes(
361+
isW3cHeaderFound,
362+
partialId,
363+
networkStartTimeInSeconds,
364+
w3cAttributes.getString("w3cGeneratedHeader"),
365+
w3cAttributes.getString("w3cCaughtHeader")
366+
);
341367
try {
342368
Method method = getMethod(Class.forName("com.instabug.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);
343369
if (method != null) {
@@ -359,7 +385,7 @@ private void networkLogAndroid(final double requestStartTime,
359385
errorMessage,
360386
gqlQueryName,
361387
serverErrorMessage,
362-
null
388+
w3cExternalTraceAttributes
363389
);
364390
} else {
365391
Log.e("IB-CP-Bridge", "APMNetworkLogger.log was not found by reflection");

android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import android.util.Log;
99
import android.view.View;
1010

11+
import androidx.annotation.NonNull;
1112
import androidx.annotation.UiThread;
1213

1314
import com.facebook.react.bridge.Arguments;
@@ -22,6 +23,8 @@
2223
import com.facebook.react.bridge.WritableNativeArray;
2324
import com.facebook.react.bridge.WritableNativeMap;
2425
import com.facebook.react.uimanager.UIManagerModule;
26+
import com.instabug.apm.InternalAPM;
27+
import com.instabug.apm.configuration.cp.APMFeature;
2528
import com.instabug.library.Feature;
2629
import com.instabug.library.Instabug;
2730
import com.instabug.library.InstabugColorTheme;
@@ -30,6 +33,11 @@
3033
import com.instabug.library.LogLevel;
3134
import com.instabug.library.ReproConfigurations;
3235
import com.instabug.library.core.InstabugCore;
36+
import com.instabug.library.internal.crossplatform.CoreFeature;
37+
import com.instabug.library.internal.crossplatform.CoreFeaturesState;
38+
import com.instabug.library.internal.crossplatform.FeaturesStateListener;
39+
import com.instabug.library.internal.crossplatform.InternalCore;
40+
import com.instabug.library.featuresflags.model.IBGFeatureFlag;
3341
import com.instabug.library.featuresflags.model.IBGFeatureFlag;
3442
import com.instabug.library.internal.module.InstabugLocale;
3543
import com.instabug.library.invocation.InstabugInvocationEvent;
@@ -1148,6 +1156,105 @@ public void run() {
11481156
}
11491157
});
11501158
}
1159+
/**
1160+
* Register a listener for W3C flags value change
1161+
*/
1162+
@ReactMethod
1163+
public void registerW3CFlagsChangeListener(){
1164+
1165+
MainThreadHandler.runOnMainThread(new Runnable() {
1166+
@Override
1167+
public void run() {
1168+
try {
1169+
InternalCore.INSTANCE._setFeaturesStateListener(new FeaturesStateListener() {
1170+
@Override
1171+
public void invoke(@NonNull CoreFeaturesState featuresState) {
1172+
WritableMap params = Arguments.createMap();
1173+
params.putBoolean("isW3ExternalTraceIDEnabled", featuresState.isW3CExternalTraceIdEnabled());
1174+
params.putBoolean("isW3ExternalGeneratedHeaderEnabled", featuresState.isAttachingGeneratedHeaderEnabled());
1175+
params.putBoolean("isW3CaughtHeaderEnabled", featuresState.isAttachingCapturedHeaderEnabled());
1176+
1177+
sendEvent(Constants.IBG_ON_NEW_W3C_FLAGS_UPDATE_RECEIVED_CALLBACK, params);
1178+
}
1179+
});
1180+
}
1181+
catch (Exception e) {
1182+
e.printStackTrace();
1183+
}
1184+
1185+
}
1186+
1187+
});
1188+
}
1189+
1190+
1191+
/**
1192+
* Get first time Value of W3ExternalTraceID flag
1193+
*/
1194+
@ReactMethod
1195+
public void isW3ExternalTraceIDEnabled(Promise promise){
1196+
1197+
MainThreadHandler.runOnMainThread(new Runnable() {
1198+
@Override
1199+
public void run() {
1200+
try {
1201+
promise.resolve(InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_EXTERNAL_TRACE_ID));
1202+
}
1203+
catch (Exception e) {
1204+
e.printStackTrace();
1205+
promise.resolve(false);
1206+
}
1207+
1208+
}
1209+
1210+
});
1211+
}
1212+
1213+
1214+
/**
1215+
* Get first time Value of W3ExternalGeneratedHeader flag
1216+
*/
1217+
@ReactMethod
1218+
public void isW3ExternalGeneratedHeaderEnabled(Promise promise){
1219+
1220+
MainThreadHandler.runOnMainThread(new Runnable() {
1221+
@Override
1222+
public void run() {
1223+
try {
1224+
promise.resolve(InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_ATTACHING_GENERATED_HEADER));
1225+
}
1226+
catch (Exception e) {
1227+
e.printStackTrace();
1228+
promise.resolve(false);
1229+
}
1230+
1231+
}
1232+
1233+
});
1234+
}
1235+
1236+
/**
1237+
* Get first time Value of W3CaughtHeader flag
1238+
*/
1239+
@ReactMethod
1240+
public void isW3CaughtHeaderEnabled(Promise promise){
1241+
1242+
MainThreadHandler.runOnMainThread(new Runnable() {
1243+
@Override
1244+
public void run() {
1245+
try {
1246+
promise.resolve(InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_ATTACHING_CAPTURED_HEADER));
1247+
}
1248+
catch (Exception e) {
1249+
e.printStackTrace();
1250+
promise.resolve(false);
1251+
}
1252+
1253+
}
1254+
1255+
});
1256+
}
1257+
11511258

11521259
/**
11531260
* Map between the exported JS constant and the arg key in {@link ArgsRegistry}.

android/src/test/java/com/instabug/reactlibrary/RNInstabugAPMModuleTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,6 @@ public void testSetFlowAttribute() {
204204
verify(APM.class, times(1));
205205
APM.endUITrace();
206206
}
207+
208+
207209
}

android/src/test/java/com/instabug/reactlibrary/RNInstabugReactnativeModuleTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
import com.instabug.library.IssueType;
1919
import com.instabug.library.ReproConfigurations;
2020
import com.instabug.library.ReproMode;
21+
import com.instabug.library.internal.crossplatform.CoreFeature;
22+
import com.instabug.library.internal.crossplatform.InternalCore;
23+
import com.instabug.library.featuresflags.model.IBGFeatureFlag;
2124
import com.instabug.library.featuresflags.model.IBGFeatureFlag;
2225
import com.instabug.library.internal.module.InstabugLocale;
2326
import com.instabug.library.ui.onboarding.WelcomeMessage;
@@ -635,4 +638,28 @@ public void testWillRedirectToStore() {
635638
// then
636639
mockInstabug.verify(() -> Instabug.willRedirectToStore());
637640
}
641+
@Test
642+
public void testW3CExternalTraceIDFlag(){
643+
Promise promise = mock(Promise.class);
644+
InternalCore internalAPM = mock(InternalCore.class);
645+
rnModule.isW3ExternalTraceIDEnabled(promise);
646+
boolean expected=internalAPM._isFeatureEnabled(CoreFeature.W3C_EXTERNAL_TRACE_ID);
647+
verify(promise).resolve(expected);
648+
}
649+
@Test
650+
public void testW3CExternalGeneratedHeaderFlag(){
651+
Promise promise = mock(Promise.class);
652+
InternalCore internalAPM = mock(InternalCore.class);
653+
rnModule.isW3ExternalGeneratedHeaderEnabled(promise);
654+
boolean expected=internalAPM._isFeatureEnabled(CoreFeature.W3C_ATTACHING_GENERATED_HEADER);
655+
verify(promise).resolve(expected);
656+
}
657+
@Test
658+
public void testW3CCaughtHeaderFlag(){
659+
Promise promise = mock(Promise.class);
660+
InternalCore internalAPM = mock(InternalCore.class);
661+
rnModule.isW3CaughtHeaderEnabled(promise);
662+
boolean expected=internalAPM._isFeatureEnabled(CoreFeature.W3C_ATTACHING_CAPTURED_HEADER);
663+
verify(promise).resolve(expected);
664+
}
638665
}

examples/default/ios/InstabugTests/InstabugAPMTests.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#import <Instabug/IBGAPM.h>
1414
#import "Instabug/Instabug.h"
1515
#import "IBGConstants.h"
16+
#import "RNInstabug/IBGAPM+PrivateAPIs.h"
1617

1718
@interface InstabugAPMTests : XCTestCase
1819
@property (nonatomic, retain) InstabugAPMBridge *instabugBridge;
@@ -176,4 +177,6 @@ - (void) testEndUITrace {
176177
OCMVerify([mock endUITrace]);
177178
}
178179

180+
181+
179182
@end

examples/default/ios/InstabugTests/InstabugCrashReportingTests.m

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ - (void)setUp {
1919
}
2020

2121
- (void)testSetEnabled {
22+
23+
[self.bridge setEnabled:NO];
24+
XCTAssertFalse(IBGCrashReporting.enabled);
25+
2226
[self.bridge setEnabled:YES];
2327
XCTAssertTrue(IBGCrashReporting.enabled);
2428

25-
[self.bridge setEnabled:NO];
26-
XCTAssertFalse(IBGCrashReporting.enabled);
2729
}
2830

2931
- (void)testSendJSCrash {

0 commit comments

Comments
 (0)