Skip to content

Commit d9f10d6

Browse files
ahmedAlaaInstabugmzelzoghbia7medevkholood-eaYoussefFouadd
authored
feat: exclude DEV server from network logs (#1307)
* feat: exclude dev server * feat: exclude DEV server url from network logs * feat: exclude DEV server url from network logs * feat: exclude DEV server url from network logs * feat: exclude DEV server url from network logs * feat: exclude DEV server url from network logs * feat: exclude DEV server url from network logs * feat: exclude DEV server url from network logs * feat: exclude DEV server url from network logs * feat: exclude DEV server url from network logs * merge dev * fix: Adjust logging behavior based on the debugLogLevel. (#1319) * refactor(example): upgrade to react native 0.75.4 (#1302) * chore: upgrade dependencies * refactor(example): upgrade to react native 0.75.4 * chore: integrate android sdk v14 snapshot * ci: install cocoapods 1.14 * ci: upgrade xcode to 15.4 * chore: remove .xcode.env.local * ci: install cocoapods into usr/local/bin * ci: fix empty jacoco report issue * Release: v14.0.0 (#1312) * Release : v14.0.0 * Release : v14.0.0 * Release : v14.0.0 * feat: add session sync callback (#1292) * feat(android): add session sync callback (#1281) * feat(android): add SRSyncCallback * feat: implement and test syncCallback CP side * feat(example): use SRSyncCallback in example app * ci: fix tests * fix: export session data type * fix(example): use session data type * fix(android):remove data modifier * fix(android): add property modifiers * fix(android): update test case * fix: enhance test case * fix: update session data type * fix: add more session metadata to setSyncCallback * fix: update syncCallback test * feat: add launchType to session metadata for setSyncCallback * fix: import type * fix: assert evaluate sync returns correct value * fix: import type * fix: cleanup * chore: update js doc * fix: typo * fix: follow interface naming convention * fix: update type * fix: refactor syncCallback * fix: default syncing session to true * fix: convert network logs to readable array * chore: add discriptive comment * chore: use readable map for session metadata * fix: setSyncCallback should sync in case of exception * fix: move SessionMetadata to models * fix: update SessionMetadata type import * fix: report bug e2e test --------- Co-authored-by: Ahmed Elrefaey <[email protected]> * feat(ios): add session sync callback (#1282) * feat(android): add SRSyncCallback * feat: implement and test syncCallback CP side * feat(example): use SRSyncCallback in example app * ci: fix tests * fix: export session data type * fix(example): use session data type * fix(android):remove data modifier * fix(android): add property modifiers * fix(android): update test case * fix: enhance test case * fix(ios): update network log signature * chore(ios): integrate dynamic sampling snapshot * fix:update IOS network log unit test * fix: update session metadata * feat(ios): add setSyncCallback * fix: pod.lock file * fix: update session data type * fix: add more session metadata to setSyncCallback * fix: update syncCallback test * feat: add launchType to session metadata for setSyncCallback * fix: import type * fix: enhance test case * fix: add more session metadata to setSyncCallback * fix: update syncCallback test * feat: add launchType to session metadata for setSyncCallback * fix: import type * feat(ios): add launchType metadata to session syncCallback * fix: add unknown type to launch types * fix: assert evaluate sync returns correct value * fix: import type * fix: cleanup * chore: update js doc * fix: typo * fix: follow interface naming convention * fix: update type * fix: refactor syncCallback * fix: default syncing session to true * fix: convert network logs to readable array * chore: add discriptive comment * chore: use readable map for session metadata * fix: setSyncCallback should sync in case of exception * fix: move SessionMetadata to models * fix: update SessionMetadata type import * fix: report bug e2e test * chore (ios): update snapshot * chore (ios): refactor callback * fix: return network logs * chore: update podfile.lock * chore: fix formatting * chore: revert Podfile.lock * chore: fix ci * fix: launchType typo * fix: update class sessionEvaluationCompletion atomicity * chore: enhance syncCallback formatting * chore: update evaluateSync formatting * fix: fix test SetSyncCallback * fix: update getNetworkLogsArray return value --------- Co-authored-by: Ahmed Elrefaey <[email protected]> * Revert "fix(ios): update network log signature" This reverts commit 8d9036e. * chore(ios): update snapshot * fix: ios network logging test after reverting * fix: convert sendEvent arg from writable to readable map * chore(android): update snapshot * fix(android): refactor getSessionMetadataMap to tolerate null values * fix(ios): update fulfill exception wait time in test * fix(android): convert session metadat map to readable map * chore: update docs * fix: remove hot launch type * fix: increase timeout expectation in test case * Revert "fix: increase timeout expectation in test case" This reverts commit be32acd. * feat(example): add features and buttons implementation (#1280) Jira ID: RL-224 * fix(android): add unknown launch type * chore: update documentation * feat: upgrade to 14.0.0 * feat: upgrade to 14.0.0 * feat: upgrade to 14.0.0 * merge dev * merge dev * merge dev * fix: test case --------- Co-authored-by: Ahmed Elrefaey <[email protected]> Co-authored-by: YoussefFouadd <[email protected]> Co-authored-by: Ahmed alaa <[email protected]> * master-on-dev (#1316) Co-authored-by: Mohamed Zakaria El-Zoghbi <[email protected]> * fix: adjust logging with debuglogLevel * chore: update release date (#1320) --------- Co-authored-by: Mohamed Zakaria El-Zoghbi <[email protected]> Co-authored-by: Ahmed Elrefaey <[email protected]> Co-authored-by: kholood <[email protected]> Co-authored-by: YoussefFouadd <[email protected]> --------- Co-authored-by: Mohamed Zakaria El-Zoghbi <[email protected]> Co-authored-by: Ahmed Elrefaey <[email protected]> Co-authored-by: kholood <[email protected]> Co-authored-by: YoussefFouadd <[email protected]>
1 parent 067ccbb commit d9f10d6

File tree

10 files changed

+113
-18
lines changed

10 files changed

+113
-18
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
- Bump Instabug iOS SDK to v14.0.0 ([#1312](https://github.com/Instabug/Instabug-React-Native/pull/1312)). [See release notes](https://github.com/Instabug/Instabug-iOS/releases/tag/14.0.0).
1818
- Bump Instabug Android SDK to v14.0.0 ([#1312](https://github.com/Instabug/Instabug-React-Native/pull/1312)). [See release notes](https://github.com/Instabug/Instabug-Android/releases/tag/v14.0.0).
1919

20+
### Added
21+
22+
- Exclude DEV server from network logs ([#1307](https://github.com/Instabug/Instabug-React-Native/pull/1307)).
23+
2024
### Fixed
2125

2226
- Replace thrown errors with logs ([#1220](https://github.com/Instabug/Instabug-React-Native/pull/1220))

src/modules/CrashReporting.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import InstabugUtils from '../utils/InstabugUtils';
55
import { Platform } from 'react-native';
66
import type { NonFatalOptions } from '../models/NonFatalOptions';
77
import { NonFatalErrorLevel } from '../utils/Enums';
8+
import { Logger } from '../utils/logger';
89

910
/**
1011
* Enables and disables everything related to crash reporting including intercepting
@@ -35,7 +36,7 @@ export const reportError = (error: ExtendedError, nonFatalOptions: NonFatalOptio
3536
),
3637
);
3738
} else {
38-
console.warn(
39+
Logger.warn(
3940
`IBG-RN: The error ${error} has been omitted because only error type is supported.`,
4041
);
4142
return;

src/modules/Instabug.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import { captureUnhandledRejections } from '../utils/UnhandledRejectionTracking'
2727
import type { ReproConfig } from '../models/ReproConfig';
2828
import type { FeatureFlag } from '../models/FeatureFlag';
2929
import InstabugConstants from '../utils/InstabugConstants';
30+
import { InstabugRNConfig } from '../utils/config';
31+
import { Logger } from '../utils/logger';
3032

3133
let _currentScreen: string | null = null;
3234
let _lastScreen: string | null = null;
@@ -93,6 +95,8 @@ export const init = (config: InstabugConfig) => {
9395
_isFirstScreen = true;
9496
_currentScreen = firstScreen;
9597

98+
InstabugRNConfig.debugLogsLevel = config.debugLogsLevel ?? LogLevel.error;
99+
96100
reportCurrentViewForAndroid(firstScreen);
97101
setTimeout(() => {
98102
if (_currentScreen === firstScreen) {
@@ -387,9 +391,10 @@ export const setReproStepsConfig = (config: ReproConfig) => {
387391
*/
388392
export const setUserAttribute = (key: string, value: string) => {
389393
if (!key || typeof key !== 'string' || typeof value !== 'string') {
390-
console.error(InstabugConstants.SET_USER_ATTRIBUTES_ERROR_TYPE_MESSAGE);
394+
Logger.error(InstabugConstants.SET_USER_ATTRIBUTES_ERROR_TYPE_MESSAGE);
391395
return;
392396
}
397+
393398
NativeInstabug.setUserAttribute(key, value);
394399
};
395400

@@ -411,7 +416,7 @@ export const getUserAttribute = async (key: string): Promise<string | null> => {
411416
*/
412417
export const removeUserAttribute = (key: string) => {
413418
if (!key || typeof key !== 'string') {
414-
console.error(InstabugConstants.REMOVE_USER_ATTRIBUTES_ERROR_TYPE_MESSAGE);
419+
Logger.error(InstabugConstants.REMOVE_USER_ATTRIBUTES_ERROR_TYPE_MESSAGE);
415420

416421
return;
417422
}
@@ -638,6 +643,13 @@ export const willRedirectToStore = () => {
638643
NativeInstabug.willRedirectToStore();
639644
};
640645

646+
/**
647+
* This API has be called when changing the default Metro server port (8081) to exclude the DEV URL from network logging.
648+
*/
649+
export const setMetroDevServerPort = (port: number) => {
650+
InstabugRNConfig.metroDevServerPort = port.toString();
651+
};
652+
641653
export const componentDidAppearListener = (event: ComponentDidAppearEvent) => {
642654
if (_isFirstScreen) {
643655
_lastScreen = event.componentName;

src/modules/NetworkLogger.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,21 @@ import type { RequestHandler } from '@apollo/client';
22

33
import InstabugConstants from '../utils/InstabugConstants';
44
import xhr, { NetworkData, ProgressCallback } from '../utils/XhrNetworkInterceptor';
5-
import { reportNetworkLog, isContentTypeNotAllowed } from '../utils/InstabugUtils';
5+
import { isContentTypeNotAllowed, reportNetworkLog } from '../utils/InstabugUtils';
6+
import { InstabugRNConfig } from '../utils/config';
7+
import { Logger } from '../utils/logger';
68

79
export type { NetworkData };
810

911
export type NetworkDataObfuscationHandler = (data: NetworkData) => Promise<NetworkData>;
1012
let _networkDataObfuscationHandler: NetworkDataObfuscationHandler | null | undefined;
1113
let _requestFilterExpression = 'false';
1214

15+
function getPortFromUrl(url: string) {
16+
const portMatch = url.match(/:(\d+)(?=\/|$)/);
17+
return portMatch ? portMatch[1] : null;
18+
}
19+
1320
/**
1421
* Sets whether network logs should be sent with bug reports.
1522
* It is enabled by default.
@@ -27,33 +34,39 @@ export const setEnabled = (isEnabled: boolean) => {
2734
network = await _networkDataObfuscationHandler(network);
2835
}
2936

37+
if (__DEV__) {
38+
const urlPort = getPortFromUrl(network.url);
39+
if (urlPort === InstabugRNConfig.metroDevServerPort) {
40+
return;
41+
}
42+
}
3043
if (network.requestBodySize > InstabugConstants.MAX_NETWORK_BODY_SIZE_IN_BYTES) {
3144
network.requestBody = InstabugConstants.MAX_REQUEST_BODY_SIZE_EXCEEDED_MESSAGE;
32-
console.warn('IBG-RN:', InstabugConstants.MAX_REQUEST_BODY_SIZE_EXCEEDED_MESSAGE);
45+
Logger.warn('IBG-RN:', InstabugConstants.MAX_REQUEST_BODY_SIZE_EXCEEDED_MESSAGE);
3346
}
3447

3548
if (network.responseBodySize > InstabugConstants.MAX_NETWORK_BODY_SIZE_IN_BYTES) {
3649
network.responseBody = InstabugConstants.MAX_RESPONSE_BODY_SIZE_EXCEEDED_MESSAGE;
37-
console.warn('IBG-RN:', InstabugConstants.MAX_RESPONSE_BODY_SIZE_EXCEEDED_MESSAGE);
50+
Logger.warn('IBG-RN:', InstabugConstants.MAX_RESPONSE_BODY_SIZE_EXCEEDED_MESSAGE);
3851
}
3952

4053
if (network.requestBody && isContentTypeNotAllowed(network.requestContentType)) {
4154
network.requestBody = `Body is omitted because content type ${network.requestContentType} isn't supported`;
42-
console.warn(
55+
Logger.warn(
4356
`IBG-RN: The request body for the network request with URL ${network.url} has been omitted because the content type ${network.requestContentType} isn't supported.`,
4457
);
4558
}
4659

4760
if (network.responseBody && isContentTypeNotAllowed(network.contentType)) {
4861
network.responseBody = `Body is omitted because content type ${network.contentType} isn't supported`;
49-
console.warn(
62+
Logger.warn(
5063
`IBG-RN: The response body for the network request with URL ${network.url} has been omitted because the content type ${network.contentType} isn't supported.`,
5164
);
5265
}
5366

5467
reportNetworkLog(network);
5568
} catch (e) {
56-
console.error(e);
69+
Logger.error(e);
5770
}
5871
}
5972
});
@@ -96,7 +109,7 @@ export const apolloLinkRequestHandler: RequestHandler = (operation, forward) =>
96109
return { headers: newHeaders };
97110
});
98111
} catch (e) {
99-
console.error(e);
112+
Logger.error(e);
100113
}
101114

102115
return forward(operation);

src/utils/InstabugConstants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const InstabugConstants = {
1111
'IBG-RN: Expected key and value passed to setUserAttribute to be of type string',
1212
REMOVE_USER_ATTRIBUTES_ERROR_TYPE_MESSAGE:
1313
'IBG-RN: Expected key and value passed to removeUserAttribute to be of type string',
14+
DEFAULT_METRO_PORT: '8081',
1415
};
1516

1617
export default InstabugConstants;

src/utils/UnhandledRejectionTracking.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import tracking, { RejectionTrackingOptions } from 'promise/setimmediate/rejecti
22
import { sendCrashReport } from './InstabugUtils';
33
import { NativeCrashReporting } from '../native/NativeCrashReporting';
44
import { NonFatalErrorLevel } from './Enums';
5+
import { Logger } from './logger';
56

67
export interface HermesInternalType {
78
enablePromiseRejectionTracker?: (options?: RejectionTrackingOptions) => void;
@@ -113,5 +114,5 @@ function _originalOnUnhandled(id: number, rejection: unknown = {}) {
113114
`Possible Unhandled Promise Rejection (id: ${id}):\n` +
114115
`${message ?? ''}\n` +
115116
(stack == null ? '' : stack);
116-
console.warn(warning);
117+
Logger.warn(warning);
117118
}

src/utils/config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import InstabugConstants from './InstabugConstants';
2+
import { LogLevel } from './Enums';
3+
4+
export const InstabugRNConfig = {
5+
metroDevServerPort: InstabugConstants.DEFAULT_METRO_PORT,
6+
debugLogsLevel: LogLevel.error,
7+
};

src/utils/logger.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { InstabugRNConfig } from './config';
2+
import { LogLevel } from './Enums';
3+
4+
export class Logger {
5+
private static shouldLog(level: LogLevel): boolean {
6+
const currentLevel = InstabugRNConfig.debugLogsLevel;
7+
8+
// Return true if the current log level is equal to or more verbose than the requested level
9+
const logLevelHierarchy: Record<LogLevel, number> = {
10+
[LogLevel.verbose]: 3,
11+
[LogLevel.debug]: 2,
12+
[LogLevel.error]: 1,
13+
[LogLevel.none]: 0,
14+
};
15+
16+
return logLevelHierarchy[currentLevel] >= logLevelHierarchy[level];
17+
}
18+
19+
// General logging method that takes a logging function as an argument
20+
private static logMessage(
21+
level: LogLevel,
22+
logMethod: (...args: any[]) => void,
23+
message?: any,
24+
...optionalParams: any[]
25+
): void {
26+
if (this.shouldLog(level)) {
27+
logMethod(message, ...optionalParams);
28+
}
29+
}
30+
31+
static error(message?: any, ...optionalParams: any[]) {
32+
this.logMessage(LogLevel.error, console.error, message, ...optionalParams); // Pass console.error for errors
33+
}
34+
35+
static info(message?: any, ...optionalParams: any[]) {
36+
this.logMessage(LogLevel.verbose, console.info, message, ...optionalParams); // Pass console.info for info
37+
}
38+
39+
static log(message?: any, ...optionalParams: any[]) {
40+
this.logMessage(LogLevel.verbose, console.log, message, ...optionalParams); // Default log method
41+
}
42+
43+
static warn(message?: any, ...optionalParams: any[]) {
44+
this.logMessage(LogLevel.debug, console.warn, message, ...optionalParams); // Use console.warn for debug
45+
}
46+
47+
static trace(message?: any, ...optionalParams: any[]) {
48+
this.logMessage(LogLevel.debug, console.trace, message, ...optionalParams); // Use console.trace for debugging
49+
}
50+
51+
static debug(message?: any, ...optionalParams: any[]) {
52+
this.logMessage(LogLevel.debug, console.debug, message, ...optionalParams); // Use console.debug for debug logs
53+
}
54+
}

test/modules/Instabug.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
import InstabugUtils from '../../src/utils/InstabugUtils';
2525
import type { FeatureFlag } from '../../src/models/FeatureFlag';
2626
import InstabugConstants from '../../src/utils/InstabugConstants';
27+
import { Logger } from '../../src/utils/logger';
2728

2829
describe('Instabug Module', () => {
2930
beforeEach(() => {
@@ -641,7 +642,7 @@ describe('Instabug Module', () => {
641642
[{}, 'value'],
642643
['key', []],
643644
])("should fail if key and value aren't strings when calling setUserAttribute", (key, value) => {
644-
const logSpy = jest.spyOn(console, 'error');
645+
const logSpy = jest.spyOn(Logger, 'error');
645646

646647
// @ts-ignore
647648
Instabug.setUserAttribute(key, value);

test/modules/NetworkLogger.spec.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as NetworkLogger from '../../src/modules/NetworkLogger';
77
import Interceptor from '../../src/utils/XhrNetworkInterceptor';
88
import { isContentTypeNotAllowed, reportNetworkLog } from '../../src/utils/InstabugUtils';
99
import InstabugConstants from '../../src/utils/InstabugConstants';
10+
import { Logger } from '../../src/utils/logger';
1011

1112
const clone = <T>(obj: T): T => {
1213
return JSON.parse(JSON.stringify(obj));
@@ -94,7 +95,7 @@ describe('NetworkLogger Module', () => {
9495

9596
it('should not break if network data obfuscation fails', async () => {
9697
// Avoid the console.error to clutter the test log
97-
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
98+
const consoleSpy = jest.spyOn(Logger, 'error').mockImplementation(() => {});
9899

99100
// Make a circular object, this should make JSON.stringify fail
100101
const handler = jest.fn(() => {
@@ -138,7 +139,7 @@ describe('NetworkLogger Module', () => {
138139
});
139140

140141
it('should not break if apollo handler throws an error', async () => {
141-
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
142+
const consoleSpy = jest.spyOn(Logger, 'error').mockImplementation(() => {});
142143

143144
const operation = {
144145
setContext: jest.fn(() => {
@@ -155,7 +156,7 @@ describe('NetworkLogger Module', () => {
155156
});
156157

157158
it('should omit request body if its content type is not allowed', () => {
158-
const consoleWarn = jest.spyOn(console, 'warn').mockImplementation();
159+
const consoleWarn = jest.spyOn(Logger, 'warn').mockImplementation();
159160
jest.mocked(isContentTypeNotAllowed).mockReturnValueOnce(true);
160161

161162
const networkData = {
@@ -180,7 +181,7 @@ describe('NetworkLogger Module', () => {
180181
});
181182

182183
it('should omit response body if its content type is not allowed', () => {
183-
const consoleWarn = jest.spyOn(console, 'warn').mockImplementation();
184+
const consoleWarn = jest.spyOn(Logger, 'warn').mockImplementation();
184185
jest.mocked(isContentTypeNotAllowed).mockReturnValueOnce(true);
185186

186187
const networkData = {
@@ -205,7 +206,7 @@ describe('NetworkLogger Module', () => {
205206
});
206207

207208
it('should omit request body if its size exceeds the maximum allowed size', () => {
208-
const consoleWarn = jest.spyOn(console, 'warn').mockImplementation();
209+
const consoleWarn = jest.spyOn(Logger, 'warn').mockImplementation();
209210

210211
const networkData = {
211212
...network,
@@ -244,7 +245,7 @@ describe('NetworkLogger Module', () => {
244245
});
245246

246247
it('should omit response body if its size exceeds the maximum allowed size', () => {
247-
const consoleWarn = jest.spyOn(console, 'warn').mockImplementation();
248+
const consoleWarn = jest.spyOn(Logger, 'warn').mockImplementation();
248249

249250
const networkData = {
250251
...network,

0 commit comments

Comments
 (0)