Skip to content

Commit 1575cae

Browse files
committed
Condense options and move stalltracking into tracing integration
1 parent 17535c8 commit 1575cae

File tree

10 files changed

+566
-563
lines changed

10 files changed

+566
-563
lines changed

src/js/integrations/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,3 @@ export { DebugSymbolicator } from "./debugsymbolicator";
22
export { DeviceContext } from "./devicecontext";
33
export { ReactNativeErrorHandlers } from "./reactnativeerrorhandlers";
44
export { Release } from "./release";
5-
export { StallTracking } from "./stalltracking";

src/js/measurements.ts

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import { getCurrentHub, getMainCarrier, Hub } from "@sentry/hub";
22
import { Transaction } from "@sentry/tracing";
33
import { CustomSamplingContext, TransactionContext } from "@sentry/types";
4-
import { logger } from "@sentry/utils";
54

6-
import { StallTracking } from "./integrations";
75
import { ReactNativeTracing } from "./tracing";
86

97
/**
@@ -58,40 +56,20 @@ const _patchStartTransaction = (
5856
const reactNativeTracing = getCurrentHub().getIntegration(
5957
ReactNativeTracing
6058
);
61-
const stallTracking = getCurrentHub().getIntegration(StallTracking);
6259

6360
if (reactNativeTracing) {
6461
reactNativeTracing.onTransactionStart(transaction);
65-
}
66-
67-
if (stallTracking) {
68-
if (!transactionContext.startTimestamp) {
69-
const finishStallTracking = stallTracking.registerTransactionStart(
70-
transaction
71-
);
72-
73-
// eslint-disable-next-line @typescript-eslint/unbound-method
74-
const originalFinish = transaction.finish;
75-
76-
transaction.finish = (endTimestamp: number | undefined) => {
77-
const stallMeasurements = finishStallTracking();
7862

79-
// Sometimes the measurements will not be tracked due to some underlying reason, we don't add them in that case.
80-
if (stallMeasurements) {
81-
transaction.setMeasurements(stallMeasurements);
82-
}
63+
// eslint-disable-next-line @typescript-eslint/unbound-method
64+
const originalFinish = transaction.finish;
8365

84-
if (reactNativeTracing) {
85-
reactNativeTracing.onTransactionFinish(transaction);
86-
}
66+
transaction.finish = (endTimestamp: number | undefined) => {
67+
if (reactNativeTracing) {
68+
reactNativeTracing.onTransactionFinish(transaction);
69+
}
8770

88-
return originalFinish.apply(transaction, [endTimestamp]);
89-
};
90-
} else {
91-
logger.log(
92-
"[StallTracking] Stalls will not be tracked due to `startTimestamp` being set."
93-
);
94-
}
71+
return originalFinish.apply(transaction, [endTimestamp]);
72+
};
9573
}
9674

9775
return transaction;

src/js/options.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,6 @@ export interface ReactNativeOptions extends BrowserOptions {
7070
didCallNativeInit: boolean;
7171
}) => void;
7272

73-
/** Enable JS event loop stall tracking. Enabled by default. */
74-
enableStallTracking?: boolean;
75-
7673
/** Enable auto performance tracking by default. */
7774
enableAutoPerformanceTracking?: boolean;
7875
}

src/js/sdk.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ const DEFAULT_OPTIONS: ReactNativeOptions = {
3232
enableNativeCrashHandling: true,
3333
enableNativeNagger: true,
3434
autoInitializeNativeSdk: true,
35-
enableStallTracking: true,
3635
enableAutoPerformanceTracking: true,
3736
};
3837

@@ -95,10 +94,6 @@ function _init<O = ReactNativeOptions>(passedOptions: O): O {
9594
if (tracingEnabled) {
9695
if (options.enableAutoPerformanceTracking) {
9796
options.defaultIntegrations.push(new ReactNativeTracing());
98-
99-
if (options.enableStallTracking) {
100-
options.defaultIntegrations.push(new StallTracking());
101-
}
10297
}
10398
}
10499
}

src/js/tracing/nativeframes.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,13 @@ import { logger, timestampInSeconds } from "@sentry/utils";
44

55
import { NativeFramesResponse } from "../definitions";
66
import { NATIVE } from "../wrapper";
7-
import { instrumentChildSpanFinish } from "./utils";
7+
import { instrumentChildSpanFinish, MARGIN_OF_ERROR_SECONDS } from "./utils";
88

99
type FramesMeasurements = Record<
1010
"frames_total" | "frames_slow" | "frames_frozen",
1111
{ value: number }
1212
>;
1313

14-
/**
15-
* A margin of error of 50ms is allowed for the async native bridge call.
16-
* Anything larger would reduce the accuracy of our frames measurements.
17-
*/
18-
const MARGIN_OF_ERROR_SECONDS = 0.05;
19-
2014
/**
2115
* Instrumentation to add native slow/frozen frames measurements onto transactions.
2216
*/

src/js/tracing/reactnativetracing.ts

Lines changed: 34 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ import {
1717
import { logger } from "@sentry/utils";
1818

1919
import { NativeAppStartResponse } from "../definitions";
20-
import { StallTracking } from "../integrations";
20+
import { ReactNativeOptions } from "../options";
2121
import { RoutingInstrumentationInstance } from "../tracing/routingInstrumentation";
2222
import { NATIVE } from "../wrapper";
2323
import { NativeFramesInstrumentation } from "./nativeframes";
24-
import { adjustTransactionDuration } from "./utils";
24+
import { StallTrackingInstrumentation } from "./stalltracking";
25+
import { adjustTransactionDuration, isNearToNow } from "./utils";
2526

2627
export type BeforeNavigate = (
2728
context: TransactionContext
@@ -70,19 +71,6 @@ export interface ReactNativeTracingOptions
7071
* @returns A (potentially) modified context object, with `sampled = false` if the transaction should be dropped.
7172
*/
7273
beforeNavigate: BeforeNavigate;
73-
74-
/**
75-
* Track the app start time by adding measurements to the first route transaction. If there is no routing instrumentation
76-
* an app start transaction will be started.
77-
*
78-
* Default: true
79-
*/
80-
enableAppStartTracking: boolean;
81-
82-
/**
83-
* Track slow/frozen frames from the native layer and adds them as measurements to all transactions.
84-
*/
85-
enableNativeFramesTracking: boolean;
8674
}
8775

8876
const defaultReactNativeTracingOptions: ReactNativeTracingOptions = {
@@ -91,8 +79,6 @@ const defaultReactNativeTracingOptions: ReactNativeTracingOptions = {
9179
maxTransactionDuration: 600,
9280
ignoreEmptyBackNavigationTransactions: true,
9381
beforeNavigate: (context) => context,
94-
enableAppStartTracking: true,
95-
enableNativeFramesTracking: true,
9682
};
9783

9884
/**
@@ -112,10 +98,12 @@ export class ReactNativeTracing implements Integration {
11298
public options: ReactNativeTracingOptions;
11399

114100
public nativeFramesInstrumentation?: NativeFramesInstrumentation;
101+
public stallTrackingInstrumentation?: StallTrackingInstrumentation;
115102

116103
private _getCurrentHub?: () => Hub;
117104
private _awaitingAppStartData?: NativeAppStartResponse;
118105
private _appStartFinishTimestamp?: number;
106+
private _sentryOptions?: ReactNativeOptions;
119107

120108
public constructor(options: Partial<ReactNativeTracingOptions> = {}) {
121109
this.options = {
@@ -140,14 +128,14 @@ export class ReactNativeTracing implements Integration {
140128
// @ts-ignore TODO
141129
shouldCreateSpanForRequest,
142130
routingInstrumentation,
143-
enableNativeFramesTracking,
144131
} = this.options;
145132

133+
this._sentryOptions = getCurrentHub()?.getClient()?.getOptions();
146134
this._getCurrentHub = getCurrentHub;
147135

148136
void this._instrumentAppStart();
149137

150-
if (enableNativeFramesTracking) {
138+
if (this._sentryOptions?.enableAutoPerformanceTracking) {
151139
this.nativeFramesInstrumentation = new NativeFramesInstrumentation(
152140
addGlobalEventProcessor,
153141
() => {
@@ -160,6 +148,7 @@ export class ReactNativeTracing implements Integration {
160148
return false;
161149
}
162150
);
151+
this.stallTrackingInstrumentation = new StallTrackingInstrumentation();
163152
} else {
164153
NATIVE.disableNativeFramesTracking();
165154
}
@@ -187,14 +176,25 @@ export class ReactNativeTracing implements Integration {
187176
* To be called on a transaction start. Can have async methods
188177
*/
189178
public onTransactionStart(transaction: Transaction): void {
190-
this.nativeFramesInstrumentation?.onTransactionStart(transaction);
179+
if (isNearToNow(transaction.startTimestamp)) {
180+
// Only if this method is called at or within margin of error to the start timestamp.
181+
this.nativeFramesInstrumentation?.onTransactionStart(transaction);
182+
this.stallTrackingInstrumentation?.onTransactionStart(transaction);
183+
}
191184
}
192185

193186
/**
194187
* To be called on a transaction finish. Cannot have async methods.
195188
*/
196-
public onTransactionFinish(transaction: Transaction): void {
189+
public onTransactionFinish(
190+
transaction: Transaction,
191+
endTimestamp?: number
192+
): void {
197193
this.nativeFramesInstrumentation?.onTransactionFinish(transaction);
194+
this.stallTrackingInstrumentation?.onTransactionFinish(
195+
transaction,
196+
endTimestamp
197+
);
198198
}
199199

200200
/**
@@ -209,7 +209,10 @@ export class ReactNativeTracing implements Integration {
209209
* Starts a route transaction if there isn't routing instrumentation.
210210
*/
211211
private async _instrumentAppStart(): Promise<void> {
212-
if (!this.options.enableAppStartTracking || !NATIVE.enableNative) {
212+
if (
213+
!this._sentryOptions?.enableAutoPerformanceTracking ||
214+
!NATIVE.enableNative
215+
) {
213216
return;
214217
}
215218

@@ -316,12 +319,17 @@ export class ReactNativeTracing implements Integration {
316319
`[ReactNativeTracing] Starting ${context.op} transaction "${context.name}" on scope`
317320
);
318321

319-
idleTransaction.registerBeforeFinishCallback((transaction) => {
320-
this.onTransactionFinish(transaction);
321-
});
322+
idleTransaction.registerBeforeFinishCallback(
323+
(transaction, endTimestamp) => {
324+
this.onTransactionFinish(transaction, endTimestamp);
325+
}
326+
);
322327

323328
idleTransaction.registerBeforeFinishCallback((transaction) => {
324-
if (this.options.enableAppStartTracking && this._awaitingAppStartData) {
329+
if (
330+
this._sentryOptions?.enableAutoPerformanceTracking &&
331+
this._awaitingAppStartData
332+
) {
325333
transaction.startTimestamp =
326334
this._awaitingAppStartData.appStartTime / 1000;
327335
transaction.op = "ui.load";
@@ -332,24 +340,6 @@ export class ReactNativeTracing implements Integration {
332340
}
333341
});
334342

335-
const stallTracking = this._getCurrentHub().getIntegration(StallTracking);
336-
337-
if (stallTracking) {
338-
const stallTrackingFinish = stallTracking.registerTransactionStart(
339-
idleTransaction
340-
);
341-
342-
idleTransaction.registerBeforeFinishCallback(
343-
(transaction, endTimestamp) => {
344-
const stallMeasurements = stallTrackingFinish(endTimestamp);
345-
346-
if (stallMeasurements) {
347-
transaction.setMeasurements(stallMeasurements);
348-
}
349-
}
350-
);
351-
}
352-
353343
idleTransaction.registerBeforeFinishCallback(
354344
(transaction, endTimestamp) => {
355345
adjustTransactionDuration(

0 commit comments

Comments
 (0)