Skip to content

Commit 344055e

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 9b1f5af commit 344055e

39 files changed

Lines changed: 199 additions & 83 deletions

File tree

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
} from '@sentry/node';
165167

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';
@@ -26,12 +26,12 @@ export const spanStreamingIntegration = defineIntegration(() => {
2626
}
2727

2828
const beforeSendSpan = clientOptions.beforeSendSpan;
29-
// If users misconfigure their SDK by opting into span streaming but
30-
// using an incompatible beforeSendSpan callback, we fall back to the static trace lifecycle.
31-
if (beforeSendSpan && !isStreamedBeforeSendSpanCallback(beforeSendSpan)) {
29+
if (isStaticBeforeSendSpanCallback(beforeSendSpan)) {
3230
clientOptions.traceLifecycle = 'static';
3331
DEBUG_BUILD &&
34-
debug.warn(`${initialMessage} a beforeSendSpan callback using \`withStreamedSpan\`! ${fallbackMsg}`);
32+
debug.warn(
33+
`SpanStreaming integration is incompatible with a beforeSendSpan callback using \`withStaticSpan\`! ${fallbackMsg}`,
34+
);
3535
return;
3636
}
3737

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,21 @@ describe('spanStreamingIntegration', () => {
6464
},
6565
);
6666

67-
it('falls back to static trace lifecycle if beforeSendSpan is not compatible with span streaming', () => {
67+
it('falls back to static trace lifecycle if beforeSendSpan is marked as static', () => {
6868
const debugSpy = vi.spyOn(debug, 'warn').mockImplementation(() => {});
6969
const client = new BrowserClient({
7070
...getDefaultBrowserClientOptions(),
7171
dsn: 'https://username@domain/123',
7272
integrations: [spanStreamingIntegration()],
7373
traceLifecycle: 'stream',
74-
beforeSendSpan: (span: Span) => span,
74+
beforeSendSpan: SentryCore.withStaticSpan(span => span),
7575
});
7676

7777
SentryCore.setCurrentClient(client);
7878
client.init();
7979

8080
expect(debugSpy).toHaveBeenCalledWith(
81-
'SpanStreaming integration requires a beforeSendSpan callback using `withStreamedSpan`! Falling back to static trace lifecycle.',
81+
'SpanStreaming integration is incompatible with a beforeSendSpan callback using `withStaticSpan`! Falling back to static trace lifecycle.',
8282
);
8383
debugSpy.mockRestore();
8484

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)