Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
a5f7fe1
wip
Lms24 Sep 26, 2025
e9c7160
types, serialization, integration WIP
Lms24 Oct 1, 2025
4721ca6
create span v2 envelope
Lms24 Oct 1, 2025
6a1e628
exports
Lms24 Oct 2, 2025
05411c6
apply ignorespans, improve beforesendspan, handle segment span being …
Lms24 Oct 2, 2025
91573dc
apply common attributes
Lms24 Oct 3, 2025
2c4caae
linter really doesn't like me and I can't blame him
Lms24 Oct 3, 2025
b478c42
apply scope contexts, extras, request data attributes
Lms24 Oct 3, 2025
a0d7e95
cleanup
Lms24 Oct 14, 2025
89255d0
changelog entry
Lms24 Oct 14, 2025
ae5ccfb
size-limit bumps
Lms24 Oct 14, 2025
da9851e
fix lint, circular deps, size limit
Lms24 Oct 14, 2025
8caf686
bump preview version
Lms24 Oct 15, 2025
30dc334
s/makeV2Callback/withStreamSpan
Lms24 Oct 15, 2025
f59aac8
add todos for event processors and integration hooks
Lms24 Oct 15, 2025
39c3062
changelog
Lms24 Oct 16, 2025
a852db8
export withStreamSpan from browser
Lms24 Oct 16, 2025
f189348
changelog
Lms24 Oct 16, 2025
a889cba
fix some attribute mishaps
Lms24 Oct 31, 2025
bd39924
remove is_remote, add is_segment
Lms24 Nov 10, 2025
62b1875
add `sentry.segment.id` common span attribute
Lms24 Nov 10, 2025
94af180
rip span kind
Lms24 Nov 12, 2025
736eaa2
restart ci
Lms24 Nov 12, 2025
b4618ae
does this fix size limit?
Lms24 Nov 21, 2025
6a0f7fa
kk limits fixed but raise limits :(
Lms24 Nov 21, 2025
1bbadd9
size limit once more
Lms24 Nov 21, 2025
2a7941e
s/user.username/user.name
Lms24 Nov 25, 2025
df26056
one more limit bump
Lms24 Nov 25, 2025
741916a
rewrite to `captureSpan`
Lms24 Nov 28, 2025
00c0d66
capturespan
Lms24 Nov 28, 2025
b727599
add integration test for pageload span
Lms24 Dec 1, 2025
216648c
more integration tests
Lms24 Dec 1, 2025
5596acf
span links test
Lms24 Dec 1, 2025
2c57e0b
set web vitals as attributes in span-first
Lms24 Dec 2, 2025
8a0d662
rewrite httpContext integration to use processSpan client hook
Lms24 Dec 2, 2025
1ac1405
minor lint stuff
Lms24 Dec 4, 2025
40c74d1
initial StreamingSpanExporter implementation for otel
Lms24 Dec 4, 2025
267ba6e
rewrite pipeline to just always use spanJSonV2 because thanks OTel
Lms24 Dec 5, 2025
588e0a1
wip
Lms24 Dec 10, 2025
4961b80
add exporter
Lms24 Dec 10, 2025
1a28c3a
more contexts
Lms24 Dec 10, 2025
9c3d3fd
add unit tests for captureSpan pipeline and utils
Lms24 Dec 11, 2025
1b26b1c
add another test for scope attribute precedence over contexts
Lms24 Dec 12, 2025
f87e9d3
Potential fix for code scanning alert no. 424: Missing regular expres…
Lms24 Dec 12, 2025
1ec94dd
fix lint errors
Lms24 Dec 12, 2025
a655a85
skip integration tests for cdn bundles
Lms24 Dec 12, 2025
0138ff6
fix skip tests not for esm/cjs npm package exports
Lms24 Dec 12, 2025
7b16758
fix missing exports of `withStreamSpan`
Lms24 Dec 12, 2025
5f0b92e
apply request data to segment span
Lms24 Dec 15, 2025
e1f4eda
register a bunch of known contexts
Lms24 Dec 15, 2025
6c1eda2
use new attribute serialization for spanv2
Lms24 Dec 15, 2025
cef2f39
remove unused code
Lms24 Dec 15, 2025
6b39ac7
flush buffer when `Sentry.flush()` is called
Lms24 Dec 16, 2025
13c3631
extract span buffer to class, add serverSpanStreamingIntegration, use…
Lms24 Dec 16, 2025
a3555ad
raise size limits
Lms24 Dec 17, 2025
780b812
save some bytes in httpContext integration when tree-shaking tracing
Lms24 Dec 17, 2025
2b9f6d5
fix test flakiness
Lms24 Dec 18, 2025
411f3ea
fix regex
Lms24 Dec 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 32 additions & 25 deletions .size-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ module.exports = [
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init'),
gzip: true,
limit: '25 KB',
limit: '26KB',
},
{
name: '@sentry/browser - with treeshaking flags',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init'),
gzip: true,
limit: '24.1 KB',
limit: '25 KB',
modifyWebpackConfig: function (config) {
const webpack = require('webpack');

Expand All @@ -38,7 +38,7 @@ module.exports = [
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'browserTracingIntegration'),
gzip: true,
limit: '42 KB',
limit: '43 KB',
},
{
name: '@sentry/browser (incl. Tracing, Profiling)',
Expand All @@ -47,6 +47,13 @@ module.exports = [
gzip: true,
limit: '48 KB',
},
// {
// name: '@sentry/browser (incl. Tracing Span-First)',
// path: 'packages/browser/build/npm/esm/index.js',
// import: createImport('init', 'browserTracingIntegration', 'spanStreamingIntegration'),
// gzip: true,
// limit: '44 KB',
// },
{
name: '@sentry/browser (incl. Tracing, Replay)',
path: 'packages/browser/build/npm/esm/prod/index.js',
Expand Down Expand Up @@ -82,35 +89,35 @@ module.exports = [
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'replayCanvasIntegration'),
gzip: true,
limit: '85 KB',
limit: '87 KB',
},
{
name: '@sentry/browser (incl. Tracing, Replay, Feedback)',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration'),
gzip: true,
limit: '98 KB',
limit: '99 KB',
},
{
name: '@sentry/browser (incl. Feedback)',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'feedbackIntegration'),
gzip: true,
limit: '42 KB',
limit: '43 KB',
},
{
name: '@sentry/browser (incl. sendFeedback)',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'sendFeedback'),
gzip: true,
limit: '30 KB',
limit: '31 KB',
},
{
name: '@sentry/browser (incl. FeedbackAsync)',
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'feedbackAsyncIntegration'),
gzip: true,
limit: '35 KB',
limit: '36 KB',
},
// React SDK (ESM)
{
Expand All @@ -119,57 +126,57 @@ module.exports = [
import: createImport('init', 'ErrorBoundary'),
ignore: ['react/jsx-runtime'],
gzip: true,
limit: '27 KB',
limit: '28 KB',
},
{
name: '@sentry/react (incl. Tracing)',
path: 'packages/react/build/esm/index.js',
import: createImport('init', 'ErrorBoundary', 'reactRouterV6BrowserTracingIntegration'),
ignore: ['react/jsx-runtime'],
gzip: true,
limit: '44 KB',
limit: '46 KB',
},
// Vue SDK (ESM)
{
name: '@sentry/vue',
path: 'packages/vue/build/esm/index.js',
import: createImport('init'),
gzip: true,
limit: '30 KB',
limit: '31 KB',
},
{
name: '@sentry/vue (incl. Tracing)',
path: 'packages/vue/build/esm/index.js',
import: createImport('init', 'browserTracingIntegration'),
gzip: true,
limit: '44 KB',
limit: '45 KB',
},
// Svelte SDK (ESM)
{
name: '@sentry/svelte',
path: 'packages/svelte/build/esm/index.js',
import: createImport('init'),
gzip: true,
limit: '25 KB',
limit: '26 KB',
},
// Browser CDN bundles
{
name: 'CDN Bundle',
path: createCDNPath('bundle.min.js'),
gzip: true,
limit: '27.5 KB',
limit: '28.5 KB',
},
{
name: 'CDN Bundle (incl. Tracing)',
path: createCDNPath('bundle.tracing.min.js'),
gzip: true,
limit: '42.5 KB',
limit: '44 KB',
},
{
name: 'CDN Bundle (incl. Tracing, Replay)',
path: createCDNPath('bundle.tracing.replay.min.js'),
gzip: true,
limit: '80 KB',
limit: '81 KB',
},
{
name: 'CDN Bundle (incl. Tracing, Replay, Feedback)',
Expand All @@ -183,21 +190,21 @@ module.exports = [
path: createCDNPath('bundle.min.js'),
gzip: false,
brotli: false,
limit: '82 KB',
limit: '83 KB',
},
{
name: 'CDN Bundle (incl. Tracing) - uncompressed',
path: createCDNPath('bundle.tracing.min.js'),
gzip: false,
brotli: false,
limit: '127 KB',
limit: '129 KB',
},
{
name: 'CDN Bundle (incl. Tracing, Replay) - uncompressed',
path: createCDNPath('bundle.tracing.replay.min.js'),
gzip: false,
brotli: false,
limit: '245 KB',
limit: '247 KB',
},
{
name: 'CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed',
Expand All @@ -213,7 +220,7 @@ module.exports = [
import: createImport('init'),
ignore: ['next/router', 'next/constants'],
gzip: true,
limit: '46 KB',
limit: '48 KB',
},
// SvelteKit SDK (ESM)
{
Expand All @@ -222,7 +229,7 @@ module.exports = [
import: createImport('init'),
ignore: ['$app/stores'],
gzip: true,
limit: '42 KB',
limit: '44 KB',
},
// Node-Core SDK (ESM)
{
Expand All @@ -231,7 +238,7 @@ module.exports = [
import: createImport('init'),
ignore: [...builtinModules, ...nodePrefixedBuiltinModules],
gzip: true,
limit: '52 KB',
limit: '53 KB',
},
// Node SDK (ESM)
{
Expand All @@ -240,14 +247,14 @@ module.exports = [
import: createImport('init'),
ignore: [...builtinModules, ...nodePrefixedBuiltinModules],
gzip: true,
limit: '162 KB',
limit: '166 KB',
},
{
name: '@sentry/node - without tracing',
path: 'packages/node/build/esm/index.js',
import: createImport('initWithoutDefaultIntegrations', 'getDefaultIntegrationsWithoutPerformance'),
gzip: true,
limit: '95 KB',
limit: '97 KB',
ignore: [...builtinModules, ...nodePrefixedBuiltinModules],
modifyWebpackConfig: function (config) {
const webpack = require('webpack');
Expand All @@ -270,7 +277,7 @@ module.exports = [
import: createImport('init'),
ignore: [...builtinModules, ...nodePrefixedBuiltinModules],
gzip: true,
limit: '111 KB',
limit: '112 KB',
},
];

Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
},
"angular.enable-strict-mode-prompt": false
}
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,16 @@ Work in this release was contributed by @hanseo0507. Thank you for your contribu

Work in this release was contributed by @0xbad0c0d3. Thank you for your contribution!

## 10.21.0-alpha.1

This release is a preview release for sending spans in browser via spanV2 instead of transaction event envelopes. All of this is experimental and subject to change. Use at your own risk. [More Details.](https://github.com/getsentry/sentry-javascript/pull/17852)

- export withStreamSpan from `@sentry/browser`

## 10.21.0-alpha.0

This release is a preview release for sending spans in browser via spanV2 instead of transaction event envelopes. All of this is experimental and subject to change. Use at your own risk. [More Details.](https://github.com/getsentry/sentry-javascript/pull/17852)

## 10.20.0

### Important Changes
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
traceLifecycle: 'stream',
integrations: [Sentry.browserTracingIntegration(), Sentry.spanStreamingIntegration()],
tracePropagationTargets: ['http://sentry-test-site.example'],
tracesSampleRate: 1,
sendDefaultPii: true,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
document.getElementById('go-background').addEventListener('click', () => {
setTimeout(() => {
Object.defineProperty(document, 'hidden', { value: true, writable: true });
const ev = document.createEvent('Event');
ev.initEvent('visibilitychange');
document.dispatchEvent(ev);
}, 250);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<button id="go-background">New Tab</button>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { expect } from '@playwright/test';
import { sentryTest } from '../../../utils/fixtures';
import { shouldSkipTracingTest, testingCdnBundle } from '../../../utils/helpers';
import { getSpanOp, waitForV2Spans } from '../../../utils/spanFirstUtils';

sentryTest('ends pageload span when the page goes to background', async ({ getLocalTestUrl, page }) => {
// for now, spanStreamingIntegration is only exported in the NPM package, so we skip the test for bundles.
if (shouldSkipTracingTest() || testingCdnBundle()) {
sentryTest.skip();
}

const url = await getLocalTestUrl({ testDir: __dirname });

const spanPromise = waitForV2Spans(page, spans => !!spans.find(span => getSpanOp(span) === 'pageload'));

await page.goto(url);
await page.locator('#go-background').click();

const pageloadSpan = (await spanPromise).find(span => getSpanOp(span) === 'pageload');

expect(pageloadSpan?.status).toBe('error'); // a cancelled span previously mapped to status error with message cancelled.
expect(pageloadSpan?.attributes?.['sentry.op']?.value).toBe('pageload');
expect(pageloadSpan?.attributes?.['sentry.cancellation_reason']?.value).toBe('document.hidden');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
traceLifecycle: 'stream',
integrations: [Sentry.browserTracingIntegration(), Sentry.spanStreamingIntegration()],
tracePropagationTargets: ['http://sentry-test-site.example'],
tracesSampleRate: 1,
sendDefaultPii: true,
debug: true,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/core';
import { sentryTest } from '../../../utils/fixtures';
import {
envelopeRequestParser,
runScriptInSandbox,
shouldSkipTracingTest,
testingCdnBundle,
waitForErrorRequest,
} from '../../../utils/helpers';
import { getSpanOp, waitForV2Spans } from '../../../utils/spanFirstUtils';

sentryTest(
'puts the pageload span name onto an error event caught during pageload',
async ({ getLocalTestUrl, page, browserName }) => {
// for now, spanStreamingIntegration is only exported in the NPM package, so we skip the test for bundles.
// This test fails on Webkit as errors thrown from `runScriptInSandbox` are Script Errors and skipped by Sentry
if (shouldSkipTracingTest() || testingCdnBundle() || browserName === 'webkit') {
sentryTest.skip();
}

const url = await getLocalTestUrl({ testDir: __dirname });

const errorEventPromise = waitForErrorRequest(page);
const spanPromise = waitForV2Spans(page, spans => !!spans.find(span => getSpanOp(span) === 'pageload'));

await page.goto(url);

await runScriptInSandbox(page, {
content: `
throw new Error('Error during pageload');
`,
});

const errorEvent = envelopeRequestParser<Event>(await errorEventPromise);
const pageloadSpan = (await spanPromise).find(span => getSpanOp(span) === 'pageload');

expect(pageloadSpan?.attributes?.['sentry.op']?.value).toEqual('pageload');
expect(errorEvent.exception?.values?.[0]).toBeDefined();

expect(pageloadSpan?.name).toEqual('/index.html');

expect(pageloadSpan?.status).toBe('error');
expect(pageloadSpan?.attributes?.['sentry.idle_span_finish_reason']?.value).toBe('idleTimeout');

expect(errorEvent.transaction).toEqual(pageloadSpan?.name);
},
);
12 changes: 12 additions & 0 deletions dev-packages/browser-integration-tests/suites/span-first/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
traceLifecycle: 'stream',
integrations: [Sentry.browserTracingIntegration(), Sentry.spanStreamingIntegration()],
tracePropagationTargets: ['http://sentry-test-site.example'],
tracesSampleRate: 1,
sendDefaultPii: true,
});
Loading