Skip to content

Commit a32a10f

Browse files
Lms24cursoragent
andcommitted
feat(core)!: Stream beforeSendSpan payloads by default
Make streamed span JSON the default beforeSendSpan contract and provide withStaticSpan for callbacks that still process transaction span JSON. Deprecate withStreamedSpan for removal in version 12. BREAKING CHANGE: beforeSendSpan receives StreamedSpanJSON by default. Fixes #22349 Co-Authored-By: Cursor <cursoragent@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 2eeaff8 commit a32a10f

41 files changed

Lines changed: 206 additions & 87 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

dev-packages/browser-integration-tests/suites/public-api/beforeSendSpan-streamed/init.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ window.Sentry = Sentry;
44

55
Sentry.init({
66
dsn: 'https://public@dsn.ingest.sentry.io/1337',
7-
integrations: [Sentry.browserTracingIntegration(), Sentry.spanStreamingIntegration()],
7+
integrations: [Sentry.browserTracingIntegration()],
88
tracesSampleRate: 1,
9-
beforeSendSpan: Sentry.withStreamedSpan(span => {
9+
beforeSendSpan: span => {
1010
if (span.attributes['sentry.op'] === 'pageload') {
1111
span.name = 'customPageloadSpanName';
1212
span.links = [
@@ -24,5 +24,5 @@ Sentry.init({
2424
span.status = 'something';
2525
}
2626
return span;
27-
}),
27+
},
2828
});

dev-packages/node-integration-tests/suites/public-api/beforeSendSpan-streamed/scenario.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ import { loggingTransport } from '@sentry-internal/node-integration-tests';
44
Sentry.init({
55
dsn: 'https://public@dsn.ingest.sentry.io/1337',
66
tracesSampleRate: 1.0,
7-
traceLifecycle: 'stream',
87
transport: loggingTransport,
98
release: '1.0.0',
10-
beforeSendSpan: Sentry.withStreamedSpan(span => {
9+
beforeSendSpan: span => {
1110
if (span.name === 'test-child-span') {
1211
span.name = 'customChildSpanName';
1312
if (!span.attributes) {
@@ -27,7 +26,7 @@ Sentry.init({
2726
];
2827
}
2928
return span;
30-
}),
29+
},
3130
});
3231

3332
Sentry.startSpan({ name: 'test-span', op: 'test' }, () => {

dev-packages/rollup-utils/plugins/bundlePlugins.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ export function makeTerserPlugin() {
150150
'_resolveFilename',
151151
// Set on e.g. the shim feedbackIntegration to be able to detect it
152152
'_isShim',
153-
// Marker set by `withStreamedSpan()` to tag streamed `beforeSendSpan` callbacks
153+
// Markers used to distinguish static and explicitly streamed `beforeSendSpan` callbacks
154+
'_static',
154155
'_streamed',
155156
// This is used in metadata integration
156157
'_sentryModuleMetadata',

packages/astro/src/index.server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ export {
173173
unleashIntegration,
174174
growthbookIntegration,
175175
spanStreamingIntegration,
176+
withStaticSpan,
177+
// eslint-disable-next-line typescript/no-deprecated
176178
withStreamedSpan,
177179
metrics,
178180
} from '@sentry/node';

packages/astro/src/index.types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export declare function init(options: Options | clientSdk.BrowserOptions | NodeO
2121
export declare const linkedErrorsIntegration: typeof clientSdk.linkedErrorsIntegration;
2222
export declare const contextLinesIntegration: typeof clientSdk.contextLinesIntegration;
2323
export declare const spanStreamingIntegration: typeof clientSdk.spanStreamingIntegration;
24+
export declare const withStaticSpan: typeof clientSdk.withStaticSpan;
25+
// eslint-disable-next-line typescript/no-deprecated
2426
export declare const withStreamedSpan: typeof clientSdk.withStreamedSpan;
2527

2628
export declare const getDefaultIntegrations: (options: Options) => Integration[];

packages/aws-serverless/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ export {
160160
growthbookIntegration,
161161
metrics,
162162
spanStreamingIntegration,
163+
withStaticSpan,
164+
// eslint-disable-next-line typescript/no-deprecated
163165
withStreamedSpan,
164166
experimentalUseDiagnosticsChannelInjection,
165167
diagnosticsChannelInjectionIntegrations,

packages/browser/src/exports.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ export {
7272
spanToTraceHeader,
7373
spanToBaggageHeader,
7474
updateSpanName,
75+
withStaticSpan,
76+
// eslint-disable-next-line typescript/no-deprecated
7577
withStreamedSpan,
7678
metrics,
7779
} from '@sentry/core/browser';

packages/browser/src/integrations/spanstreaming.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
debug,
55
defineIntegration,
66
hasSpanStreamingEnabled,
7-
isStreamedBeforeSendSpanCallback,
7+
isStaticBeforeSendSpanCallback,
88
SpanBuffer,
99
spanIsSampled,
1010
} from '@sentry/core/browser';
@@ -36,12 +36,12 @@ export const spanStreamingIntegration = defineIntegration(() => {
3636
}
3737

3838
const beforeSendSpan = clientOptions.beforeSendSpan;
39-
// If users misconfigure their SDK by opting into span streaming but
40-
// using an incompatible beforeSendSpan callback, we fall back to the static trace lifecycle.
41-
if (beforeSendSpan && !isStreamedBeforeSendSpanCallback(beforeSendSpan)) {
39+
if (isStaticBeforeSendSpanCallback(beforeSendSpan)) {
4240
clientOptions.traceLifecycle = 'static';
4341
DEBUG_BUILD &&
44-
debug.warn(`${initialMessage} a beforeSendSpan callback using \`withStreamedSpan\`! ${fallbackMsg}`);
42+
debug.warn(
43+
`SpanStreaming integration is incompatible with a beforeSendSpan callback using \`withStaticSpan\`! ${fallbackMsg}`,
44+
);
4545
return;
4646
}
4747

packages/browser/test/integrations/spanstreaming.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,21 +79,21 @@ describe('spanStreamingIntegration', () => {
7979
},
8080
);
8181

82-
it('falls back to static trace lifecycle if beforeSendSpan is not compatible with span streaming', () => {
82+
it('falls back to static trace lifecycle if beforeSendSpan is marked as static', () => {
8383
const debugSpy = vi.spyOn(debug, 'warn').mockImplementation(() => {});
8484
const client = new BrowserClient({
8585
...getDefaultBrowserClientOptions(),
8686
dsn: 'https://username@domain/123',
8787
integrations: [spanStreamingIntegration()],
8888
traceLifecycle: 'stream',
89-
beforeSendSpan: (span: Span) => span,
89+
beforeSendSpan: SentryCore.withStaticSpan(span => span),
9090
});
9191

9292
SentryCore.setCurrentClient(client);
9393
client.init();
9494

9595
expect(debugSpy).toHaveBeenCalledWith(
96-
'SpanStreaming integration requires a beforeSendSpan callback using `withStreamedSpan`! Falling back to static trace lifecycle.',
96+
'SpanStreaming integration is incompatible with a beforeSendSpan callback using `withStaticSpan`! Falling back to static trace lifecycle.',
9797
);
9898
debugSpy.mockRestore();
9999

packages/bun/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ export {
178178
unleashIntegration,
179179
metrics,
180180
spanStreamingIntegration,
181+
withStaticSpan,
182+
// eslint-disable-next-line typescript/no-deprecated
181183
withStreamedSpan,
182184
} from '@sentry/node';
183185

0 commit comments

Comments
 (0)