Skip to content

Commit 778ba53

Browse files
chargomebillyvg
authored andcommitted
feat(core): Make stream instrumentation opt-in (#13951)
1 parent 64fbe5a commit 778ba53

File tree

5 files changed

+55
-9
lines changed

5 files changed

+55
-9
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010

1111
- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
1212

13+
- **feat(core): Make stream instrumentation opt-in
14+
([#13951](https://github.com/getsentry/sentry-javascript/pull/13951))**
15+
16+
This change adds a new option `trackFetchStreamPerformance` to the browser tracing integration. Only when set to `true`,
17+
Sentry will instrument streams via fetch.
18+
1319
Work in this release was contributed by @ZakrepaShe. Thank you for your contribution!
1420

1521
## 8.34.0

dev-packages/e2e-tests/test-applications/react-router-6/src/index.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Sentry.init({
2626
useNavigationType,
2727
createRoutesFromChildren,
2828
matchRoutes,
29+
trackFetchStreamPerformance: true,
2930
}),
3031
replay,
3132
],

packages/browser/src/tracing/browserTracingIntegration.ts

+10
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,14 @@ export interface BrowserTracingOptions {
132132
*/
133133
traceXHR: boolean;
134134

135+
/**
136+
* Flag to disable tracking of long-lived streams, like server-sent events (SSE) via fetch.
137+
* Do not enable this in case you have live streams or very long running streams.
138+
*
139+
* Default: false
140+
*/
141+
trackFetchStreamPerformance: boolean;
142+
135143
/**
136144
* If true, Sentry will capture http timings and add them to the corresponding http spans.
137145
*
@@ -200,6 +208,7 @@ export const browserTracingIntegration = ((_options: Partial<BrowserTracingOptio
200208
markBackgroundSpan,
201209
traceFetch,
202210
traceXHR,
211+
trackFetchStreamPerformance,
203212
shouldCreateSpanForRequest,
204213
enableHTTPTimings,
205214
instrumentPageLoad,
@@ -409,6 +418,7 @@ export const browserTracingIntegration = ((_options: Partial<BrowserTracingOptio
409418
instrumentOutgoingRequests(client, {
410419
traceFetch,
411420
traceXHR,
421+
trackFetchStreamPerformance,
412422
tracePropagationTargets: client.getOptions().tracePropagationTargets,
413423
shouldCreateSpanForRequest,
414424
enableHTTPTimings,

packages/browser/src/tracing/request.ts

+30-9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable max-lines */
12
import {
23
SENTRY_XHR_DATA_KEY,
34
addPerformanceInstrumentationHandler,
@@ -76,7 +77,16 @@ export interface RequestInstrumentationOptions {
7677
*
7778
* Default: true
7879
*/
79-
traceXHR: boolean;
80+
traceXHR: boolean /**
81+
* Flag to disable tracking of long-lived streams, like server-sent events (SSE) via fetch.
82+
* Do not enable this in case you have live streams or very long running streams.
83+
*
84+
* Disabled by default since it can lead to issues with streams using the `cancel()` api
85+
* (https://github.com/getsentry/sentry-javascript/issues/13950)
86+
*
87+
* Default: false
88+
*/;
89+
trackFetchStreamPerformance: boolean;
8090

8191
/**
8292
* If true, Sentry will capture http timings and add them to the corresponding http spans.
@@ -101,13 +111,22 @@ export const defaultRequestInstrumentationOptions: RequestInstrumentationOptions
101111
traceFetch: true,
102112
traceXHR: true,
103113
enableHTTPTimings: true,
114+
trackFetchStreamPerformance: false,
104115
};
105116

106117
/** Registers span creators for xhr and fetch requests */
107118
export function instrumentOutgoingRequests(client: Client, _options?: Partial<RequestInstrumentationOptions>): void {
108-
const { traceFetch, traceXHR, shouldCreateSpanForRequest, enableHTTPTimings, tracePropagationTargets } = {
119+
const {
120+
traceFetch,
121+
traceXHR,
122+
trackFetchStreamPerformance,
123+
shouldCreateSpanForRequest,
124+
enableHTTPTimings,
125+
tracePropagationTargets,
126+
} = {
109127
traceFetch: defaultRequestInstrumentationOptions.traceFetch,
110128
traceXHR: defaultRequestInstrumentationOptions.traceXHR,
129+
trackFetchStreamPerformance: defaultRequestInstrumentationOptions.trackFetchStreamPerformance,
111130
..._options,
112131
};
113132

@@ -136,14 +155,16 @@ export function instrumentOutgoingRequests(client: Client, _options?: Partial<Re
136155
return event;
137156
});
138157

139-
addFetchEndInstrumentationHandler(handlerData => {
140-
if (handlerData.response) {
141-
const span = responseToSpanId.get(handlerData.response);
142-
if (span && handlerData.endTimestamp) {
143-
spanIdToEndTimestamp.set(span, handlerData.endTimestamp);
158+
if (trackFetchStreamPerformance) {
159+
addFetchEndInstrumentationHandler(handlerData => {
160+
if (handlerData.response) {
161+
const span = responseToSpanId.get(handlerData.response);
162+
if (span && handlerData.endTimestamp) {
163+
spanIdToEndTimestamp.set(span, handlerData.endTimestamp);
164+
}
144165
}
145-
}
146-
});
166+
});
167+
}
147168

148169
addFetchInstrumentationHandler(handlerData => {
149170
const createdSpan = instrumentFetchRequest(handlerData, shouldCreateSpan, shouldAttachHeadersWithTargets, spans);

packages/browser/test/tracing/request.test.ts

+8
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ describe('instrumentOutgoingRequests', () => {
5454

5555
expect(addXhrSpy).not.toHaveBeenCalled();
5656
});
57+
58+
it('does instrument streaming requests if trackFetchStreamPerformance is true', () => {
59+
const addFetchEndSpy = vi.spyOn(utils, 'addFetchEndInstrumentationHandler');
60+
61+
instrumentOutgoingRequests(client, { trackFetchStreamPerformance: true });
62+
63+
expect(addFetchEndSpy).toHaveBeenCalledWith(expect.any(Function));
64+
});
5765
});
5866

5967
interface ProtocolInfo {

0 commit comments

Comments
 (0)