feat(core): Emit low cardinality router span names - #23547

Merged
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names
Aug 25, 2026
Merged

feat(core): Emit low cardinality router span names#23547
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names

Conversation

@logaretm

Copy link
Copy Markdown
Member

Names router spans after the route they dispatch when span streaming is enabled, else Router. Static mode is unchanged.

SDKBeforeAfter
Express (OTel)/c mount pathhttp.route
Express (orchestrion)/users/123http.route
Koa/users/:idsame, Router if pathless
HapiGET /users/{id}/users/{id}
Angular/users/123Router
Emberroute:a -> route:bRouter
SvelteKitSvelteKit Route ChangeRouter

Only Koa already used its http.route. Hapi drops the method since the template has none; Angular, Ember and SvelteKit carry no route.

closes#23532

@linear-code

Copy link
Copy Markdown

JS-3417

@github-actions

github-actionsBot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.82 kB--
@sentry/browser (incl. Tracing)48.55 kB--
@sentry/browser (incl. Tracing + Span Streaming)48.57 kB--
@sentry/browser (incl. Tracing, Profiling)51.47 kB--
@sentry/browser (incl. Tracing, Replay)88 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags77.44 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)92.69 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)105.41 kB--
@sentry/browser (incl. Feedback)45.81 kB--
@sentry/browser (incl. sendFeedback)33.36 kB--
@sentry/browser (incl. FeedbackAsync)38.47 kB--
@sentry/browser (incl. Metrics)29.52 kB--
@sentry/browser (incl. Logs)29.8 kB--
@sentry/browser (incl. Metrics & Logs)30.45 kB--
@sentry/react30.33 kB--
@sentry/react (incl. Tracing)50.76 kB--
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.78 kB--
@sentry/svelte28.6 kB--
CDN Bundle30.32 kB--
CDN Bundle (incl. Tracing)49.07 kB--
CDN Bundle (incl. Logs, Metrics)32.54 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)50.94 kB--
CDN Bundle (incl. Replay, Logs, Metrics)72.96 kB--
CDN Bundle (incl. Tracing, Replay)86.57 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)88.44 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)92.33 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)94.27 kB--
CDN Bundle - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.74 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.43 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.3 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed266.14 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.82 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.84 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.51 kB--
@sentry/nextjs (client)53.27 kB--
@sentry/sveltekit (client)48.97 kB+0.02%+6 B 🔺
@sentry/core/server65.13 kB+0.04%+20 B 🔺
@sentry/core/browser52.27 kB--
@sentry/node121.66 kB+0.09%+102 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.52 kB+0.1%+82 B 🔺
@sentry/aws-serverless95.93 kB+0.11%+97 B 🔺
@sentry/cloudflare (withSentry) - minified199.28 kB--
@sentry/cloudflare (withSentry)495.43 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch 3 times, most recently from 1318630 to be3a06aCompareAugust 24, 2026 18:44
@logaretm
logaretm marked this pull request as ready for review August 24, 2026 18:50
@logaretm
logaretm requested review from a team as code ownersAugust 24, 2026 18:50
@logaretm
logaretm requested review from chargome and nicohrubec and removed request for a teamAugust 24, 2026 18:50

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.


const client = getClient();
// With span streaming, span names have to be low cardinality, so router spans are named after their route.
const isStreamedRouterSpan = layerType === LAYER_TYPE.ROUTER && !!client && hasSpanStreamingEnabled(client);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoidable getClient calls

Low Severity

Flagged because it was mentioned in the review rules file — this is more an "is this necessary" check than a hard violation. These sites newly call getClient() to gate span streaming, while the Koa, Express, and Hapi integrations already receive a client in setup. Prefering that existing reference would avoid relying on ambient current-client state in multi-client setups.

Additional Locations (2)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.

Names `router` spans after the route they dispatch when span streaming is
enabled, falling back to `Router` when the SDK has no route, per
https://getsentry.github.io/sentry-conventions/names/#routing-router.
Covers all seven sites that emit the `router` op: the OTel-derived and
orchestrion Express integrations, Koa, Hapi, Angular, Ember and SvelteKit
(Svelte 4 and 5). Two of them were leaking high-cardinality values: the
orchestrion Express integration named router spans `layer.path`, which
Express assigns the *matched* URL segment (verified against express
4.22.1: `app.use('/users/:id', router)` yields `/users/123`), and Angular
named them the raw navigation URL, since the parameterized route only
resolves at `ResolveEnd` and is applied to the root span rather than to
the routing span.
Angular, Ember and SvelteKit have no route value at the span, so they take
the fallback. Hapi drops its `GET ` prefix because the convention's
template has no method component.
`traceLifecycle: 'static'` names are byte-identical; the existing static
integration and e2e assertions are the regression check.
@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch from be3a06a to a4622eaCompareAugust 25, 2026 15:43
@logaretm
logaretm merged commit 1dca402 into developAug 25, 2026
531 of 533 checks passed
@logaretm
logaretm deleted the awad/js-3417-emit-low-cardinality-router-span-names branch August 25, 2026 16:47
logaretm added a commit that referenced this pull request Aug 26, 2026
Covers the router span name fallback #23547 added, for the two SDKs it
left untested.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emit low cardinality router span names

2 participants

@logaretm@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(core): Emit low cardinality router span names - #23547

Merged
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names
Aug 25, 2026
Merged

feat(core): Emit low cardinality router span names#23547
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names

Conversation

@logaretm

Copy link
Copy Markdown
Member

Names router spans after the route they dispatch when span streaming is enabled, else Router. Static mode is unchanged.

SDKBeforeAfter
Express (OTel)/c mount pathhttp.route
Express (orchestrion)/users/123http.route
Koa/users/:idsame, Router if pathless
HapiGET /users/{id}/users/{id}
Angular/users/123Router
Emberroute:a -> route:bRouter
SvelteKitSvelteKit Route ChangeRouter

Only Koa already used its http.route. Hapi drops the method since the template has none; Angular, Ember and SvelteKit carry no route.

closes#23532

@linear-code

Copy link
Copy Markdown

JS-3417

@github-actions

github-actionsBot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.82 kB--
@sentry/browser (incl. Tracing)48.55 kB--
@sentry/browser (incl. Tracing + Span Streaming)48.57 kB--
@sentry/browser (incl. Tracing, Profiling)51.47 kB--
@sentry/browser (incl. Tracing, Replay)88 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags77.44 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)92.69 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)105.41 kB--
@sentry/browser (incl. Feedback)45.81 kB--
@sentry/browser (incl. sendFeedback)33.36 kB--
@sentry/browser (incl. FeedbackAsync)38.47 kB--
@sentry/browser (incl. Metrics)29.52 kB--
@sentry/browser (incl. Logs)29.8 kB--
@sentry/browser (incl. Metrics & Logs)30.45 kB--
@sentry/react30.33 kB--
@sentry/react (incl. Tracing)50.76 kB--
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.78 kB--
@sentry/svelte28.6 kB--
CDN Bundle30.32 kB--
CDN Bundle (incl. Tracing)49.07 kB--
CDN Bundle (incl. Logs, Metrics)32.54 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)50.94 kB--
CDN Bundle (incl. Replay, Logs, Metrics)72.96 kB--
CDN Bundle (incl. Tracing, Replay)86.57 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)88.44 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)92.33 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)94.27 kB--
CDN Bundle - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.74 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.43 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.3 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed266.14 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.82 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.84 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.51 kB--
@sentry/nextjs (client)53.27 kB--
@sentry/sveltekit (client)48.97 kB+0.02%+6 B 🔺
@sentry/core/server65.13 kB+0.04%+20 B 🔺
@sentry/core/browser52.27 kB--
@sentry/node121.66 kB+0.09%+102 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.52 kB+0.1%+82 B 🔺
@sentry/aws-serverless95.93 kB+0.11%+97 B 🔺
@sentry/cloudflare (withSentry) - minified199.28 kB--
@sentry/cloudflare (withSentry)495.43 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch 3 times, most recently from 1318630 to be3a06aCompareAugust 24, 2026 18:44
@logaretm
logaretm marked this pull request as ready for review August 24, 2026 18:50
@logaretm
logaretm requested review from a team as code ownersAugust 24, 2026 18:50
@logaretm
logaretm requested review from chargome and nicohrubec and removed request for a teamAugust 24, 2026 18:50

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.


const client = getClient();
// With span streaming, span names have to be low cardinality, so router spans are named after their route.
const isStreamedRouterSpan = layerType === LAYER_TYPE.ROUTER && !!client && hasSpanStreamingEnabled(client);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoidable getClient calls

Low Severity

Flagged because it was mentioned in the review rules file — this is more an "is this necessary" check than a hard violation. These sites newly call getClient() to gate span streaming, while the Koa, Express, and Hapi integrations already receive a client in setup. Prefering that existing reference would avoid relying on ambient current-client state in multi-client setups.

Additional Locations (2)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.

Names `router` spans after the route they dispatch when span streaming is
enabled, falling back to `Router` when the SDK has no route, per
https://getsentry.github.io/sentry-conventions/names/#routing-router.
Covers all seven sites that emit the `router` op: the OTel-derived and
orchestrion Express integrations, Koa, Hapi, Angular, Ember and SvelteKit
(Svelte 4 and 5). Two of them were leaking high-cardinality values: the
orchestrion Express integration named router spans `layer.path`, which
Express assigns the *matched* URL segment (verified against express
4.22.1: `app.use('/users/:id', router)` yields `/users/123`), and Angular
named them the raw navigation URL, since the parameterized route only
resolves at `ResolveEnd` and is applied to the root span rather than to
the routing span.
Angular, Ember and SvelteKit have no route value at the span, so they take
the fallback. Hapi drops its `GET ` prefix because the convention's
template has no method component.
`traceLifecycle: 'static'` names are byte-identical; the existing static
integration and e2e assertions are the regression check.
@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch from be3a06a to a4622eaCompareAugust 25, 2026 15:43
@logaretm
logaretm merged commit 1dca402 into developAug 25, 2026
531 of 533 checks passed
@logaretm
logaretm deleted the awad/js-3417-emit-low-cardinality-router-span-names branch August 25, 2026 16:47
logaretm added a commit that referenced this pull request Aug 26, 2026
Covers the router span name fallback #23547 added, for the two SDKs it
left untested.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emit low cardinality router span names

2 participants

@logaretm@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(core): Emit low cardinality router span names - #23547

Merged
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names
Aug 25, 2026
Merged

feat(core): Emit low cardinality router span names#23547
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names

Conversation

@logaretm

Copy link
Copy Markdown
Member

Names router spans after the route they dispatch when span streaming is enabled, else Router. Static mode is unchanged.

SDKBeforeAfter
Express (OTel)/c mount pathhttp.route
Express (orchestrion)/users/123http.route
Koa/users/:idsame, Router if pathless
HapiGET /users/{id}/users/{id}
Angular/users/123Router
Emberroute:a -> route:bRouter
SvelteKitSvelteKit Route ChangeRouter

Only Koa already used its http.route. Hapi drops the method since the template has none; Angular, Ember and SvelteKit carry no route.

closes#23532

@linear-code

Copy link
Copy Markdown

JS-3417

@github-actions

github-actionsBot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.82 kB--
@sentry/browser (incl. Tracing)48.55 kB--
@sentry/browser (incl. Tracing + Span Streaming)48.57 kB--
@sentry/browser (incl. Tracing, Profiling)51.47 kB--
@sentry/browser (incl. Tracing, Replay)88 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags77.44 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)92.69 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)105.41 kB--
@sentry/browser (incl. Feedback)45.81 kB--
@sentry/browser (incl. sendFeedback)33.36 kB--
@sentry/browser (incl. FeedbackAsync)38.47 kB--
@sentry/browser (incl. Metrics)29.52 kB--
@sentry/browser (incl. Logs)29.8 kB--
@sentry/browser (incl. Metrics & Logs)30.45 kB--
@sentry/react30.33 kB--
@sentry/react (incl. Tracing)50.76 kB--
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.78 kB--
@sentry/svelte28.6 kB--
CDN Bundle30.32 kB--
CDN Bundle (incl. Tracing)49.07 kB--
CDN Bundle (incl. Logs, Metrics)32.54 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)50.94 kB--
CDN Bundle (incl. Replay, Logs, Metrics)72.96 kB--
CDN Bundle (incl. Tracing, Replay)86.57 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)88.44 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)92.33 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)94.27 kB--
CDN Bundle - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.74 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.43 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.3 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed266.14 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.82 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.84 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.51 kB--
@sentry/nextjs (client)53.27 kB--
@sentry/sveltekit (client)48.97 kB+0.02%+6 B 🔺
@sentry/core/server65.13 kB+0.04%+20 B 🔺
@sentry/core/browser52.27 kB--
@sentry/node121.66 kB+0.09%+102 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.52 kB+0.1%+82 B 🔺
@sentry/aws-serverless95.93 kB+0.11%+97 B 🔺
@sentry/cloudflare (withSentry) - minified199.28 kB--
@sentry/cloudflare (withSentry)495.43 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch 3 times, most recently from 1318630 to be3a06aCompareAugust 24, 2026 18:44
@logaretm
logaretm marked this pull request as ready for review August 24, 2026 18:50
@logaretm
logaretm requested review from a team as code ownersAugust 24, 2026 18:50
@logaretm
logaretm requested review from chargome and nicohrubec and removed request for a teamAugust 24, 2026 18:50

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.


const client = getClient();
// With span streaming, span names have to be low cardinality, so router spans are named after their route.
const isStreamedRouterSpan = layerType === LAYER_TYPE.ROUTER && !!client && hasSpanStreamingEnabled(client);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoidable getClient calls

Low Severity

Flagged because it was mentioned in the review rules file — this is more an "is this necessary" check than a hard violation. These sites newly call getClient() to gate span streaming, while the Koa, Express, and Hapi integrations already receive a client in setup. Prefering that existing reference would avoid relying on ambient current-client state in multi-client setups.

Additional Locations (2)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.

Names `router` spans after the route they dispatch when span streaming is
enabled, falling back to `Router` when the SDK has no route, per
https://getsentry.github.io/sentry-conventions/names/#routing-router.
Covers all seven sites that emit the `router` op: the OTel-derived and
orchestrion Express integrations, Koa, Hapi, Angular, Ember and SvelteKit
(Svelte 4 and 5). Two of them were leaking high-cardinality values: the
orchestrion Express integration named router spans `layer.path`, which
Express assigns the *matched* URL segment (verified against express
4.22.1: `app.use('/users/:id', router)` yields `/users/123`), and Angular
named them the raw navigation URL, since the parameterized route only
resolves at `ResolveEnd` and is applied to the root span rather than to
the routing span.
Angular, Ember and SvelteKit have no route value at the span, so they take
the fallback. Hapi drops its `GET ` prefix because the convention's
template has no method component.
`traceLifecycle: 'static'` names are byte-identical; the existing static
integration and e2e assertions are the regression check.
@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch from be3a06a to a4622eaCompareAugust 25, 2026 15:43
@logaretm
logaretm merged commit 1dca402 into developAug 25, 2026
531 of 533 checks passed
@logaretm
logaretm deleted the awad/js-3417-emit-low-cardinality-router-span-names branch August 25, 2026 16:47
logaretm added a commit that referenced this pull request Aug 26, 2026
Covers the router span name fallback #23547 added, for the two SDKs it
left untested.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emit low cardinality router span names

2 participants

@logaretm@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(core): Emit low cardinality router span names - #23547

Merged
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names
Aug 25, 2026
Merged

feat(core): Emit low cardinality router span names#23547
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names

Conversation

@logaretm

Copy link
Copy Markdown
Member

Names router spans after the route they dispatch when span streaming is enabled, else Router. Static mode is unchanged.

SDKBeforeAfter
Express (OTel)/c mount pathhttp.route
Express (orchestrion)/users/123http.route
Koa/users/:idsame, Router if pathless
HapiGET /users/{id}/users/{id}
Angular/users/123Router
Emberroute:a -> route:bRouter
SvelteKitSvelteKit Route ChangeRouter

Only Koa already used its http.route. Hapi drops the method since the template has none; Angular, Ember and SvelteKit carry no route.

closes#23532

@linear-code

Copy link
Copy Markdown

JS-3417

@github-actions

github-actionsBot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.82 kB--
@sentry/browser (incl. Tracing)48.55 kB--
@sentry/browser (incl. Tracing + Span Streaming)48.57 kB--
@sentry/browser (incl. Tracing, Profiling)51.47 kB--
@sentry/browser (incl. Tracing, Replay)88 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags77.44 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)92.69 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)105.41 kB--
@sentry/browser (incl. Feedback)45.81 kB--
@sentry/browser (incl. sendFeedback)33.36 kB--
@sentry/browser (incl. FeedbackAsync)38.47 kB--
@sentry/browser (incl. Metrics)29.52 kB--
@sentry/browser (incl. Logs)29.8 kB--
@sentry/browser (incl. Metrics & Logs)30.45 kB--
@sentry/react30.33 kB--
@sentry/react (incl. Tracing)50.76 kB--
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.78 kB--
@sentry/svelte28.6 kB--
CDN Bundle30.32 kB--
CDN Bundle (incl. Tracing)49.07 kB--
CDN Bundle (incl. Logs, Metrics)32.54 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)50.94 kB--
CDN Bundle (incl. Replay, Logs, Metrics)72.96 kB--
CDN Bundle (incl. Tracing, Replay)86.57 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)88.44 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)92.33 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)94.27 kB--
CDN Bundle - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.74 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.43 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.3 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed266.14 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.82 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.84 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.51 kB--
@sentry/nextjs (client)53.27 kB--
@sentry/sveltekit (client)48.97 kB+0.02%+6 B 🔺
@sentry/core/server65.13 kB+0.04%+20 B 🔺
@sentry/core/browser52.27 kB--
@sentry/node121.66 kB+0.09%+102 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.52 kB+0.1%+82 B 🔺
@sentry/aws-serverless95.93 kB+0.11%+97 B 🔺
@sentry/cloudflare (withSentry) - minified199.28 kB--
@sentry/cloudflare (withSentry)495.43 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch 3 times, most recently from 1318630 to be3a06aCompareAugust 24, 2026 18:44
@logaretm
logaretm marked this pull request as ready for review August 24, 2026 18:50
@logaretm
logaretm requested review from a team as code ownersAugust 24, 2026 18:50
@logaretm
logaretm requested review from chargome and nicohrubec and removed request for a teamAugust 24, 2026 18:50

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.


const client = getClient();
// With span streaming, span names have to be low cardinality, so router spans are named after their route.
const isStreamedRouterSpan = layerType === LAYER_TYPE.ROUTER && !!client && hasSpanStreamingEnabled(client);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoidable getClient calls

Low Severity

Flagged because it was mentioned in the review rules file — this is more an "is this necessary" check than a hard violation. These sites newly call getClient() to gate span streaming, while the Koa, Express, and Hapi integrations already receive a client in setup. Prefering that existing reference would avoid relying on ambient current-client state in multi-client setups.

Additional Locations (2)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.

Names `router` spans after the route they dispatch when span streaming is
enabled, falling back to `Router` when the SDK has no route, per
https://getsentry.github.io/sentry-conventions/names/#routing-router.
Covers all seven sites that emit the `router` op: the OTel-derived and
orchestrion Express integrations, Koa, Hapi, Angular, Ember and SvelteKit
(Svelte 4 and 5). Two of them were leaking high-cardinality values: the
orchestrion Express integration named router spans `layer.path`, which
Express assigns the *matched* URL segment (verified against express
4.22.1: `app.use('/users/:id', router)` yields `/users/123`), and Angular
named them the raw navigation URL, since the parameterized route only
resolves at `ResolveEnd` and is applied to the root span rather than to
the routing span.
Angular, Ember and SvelteKit have no route value at the span, so they take
the fallback. Hapi drops its `GET ` prefix because the convention's
template has no method component.
`traceLifecycle: 'static'` names are byte-identical; the existing static
integration and e2e assertions are the regression check.
@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch from be3a06a to a4622eaCompareAugust 25, 2026 15:43
@logaretm
logaretm merged commit 1dca402 into developAug 25, 2026
531 of 533 checks passed
@logaretm
logaretm deleted the awad/js-3417-emit-low-cardinality-router-span-names branch August 25, 2026 16:47
logaretm added a commit that referenced this pull request Aug 26, 2026
Covers the router span name fallback #23547 added, for the two SDKs it
left untested.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emit low cardinality router span names

2 participants

@logaretm@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(core): Emit low cardinality router span names - #23547

Merged
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names
Aug 25, 2026
Merged

feat(core): Emit low cardinality router span names#23547
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names

Conversation

@logaretm

Copy link
Copy Markdown
Member

Names router spans after the route they dispatch when span streaming is enabled, else Router. Static mode is unchanged.

SDKBeforeAfter
Express (OTel)/c mount pathhttp.route
Express (orchestrion)/users/123http.route
Koa/users/:idsame, Router if pathless
HapiGET /users/{id}/users/{id}
Angular/users/123Router
Emberroute:a -> route:bRouter
SvelteKitSvelteKit Route ChangeRouter

Only Koa already used its http.route. Hapi drops the method since the template has none; Angular, Ember and SvelteKit carry no route.

closes#23532

@linear-code

Copy link
Copy Markdown

JS-3417

@github-actions

github-actionsBot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.82 kB--
@sentry/browser (incl. Tracing)48.55 kB--
@sentry/browser (incl. Tracing + Span Streaming)48.57 kB--
@sentry/browser (incl. Tracing, Profiling)51.47 kB--
@sentry/browser (incl. Tracing, Replay)88 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags77.44 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)92.69 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)105.41 kB--
@sentry/browser (incl. Feedback)45.81 kB--
@sentry/browser (incl. sendFeedback)33.36 kB--
@sentry/browser (incl. FeedbackAsync)38.47 kB--
@sentry/browser (incl. Metrics)29.52 kB--
@sentry/browser (incl. Logs)29.8 kB--
@sentry/browser (incl. Metrics & Logs)30.45 kB--
@sentry/react30.33 kB--
@sentry/react (incl. Tracing)50.76 kB--
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.78 kB--
@sentry/svelte28.6 kB--
CDN Bundle30.32 kB--
CDN Bundle (incl. Tracing)49.07 kB--
CDN Bundle (incl. Logs, Metrics)32.54 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)50.94 kB--
CDN Bundle (incl. Replay, Logs, Metrics)72.96 kB--
CDN Bundle (incl. Tracing, Replay)86.57 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)88.44 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)92.33 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)94.27 kB--
CDN Bundle - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.74 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.43 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.3 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed266.14 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.82 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.84 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.51 kB--
@sentry/nextjs (client)53.27 kB--
@sentry/sveltekit (client)48.97 kB+0.02%+6 B 🔺
@sentry/core/server65.13 kB+0.04%+20 B 🔺
@sentry/core/browser52.27 kB--
@sentry/node121.66 kB+0.09%+102 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.52 kB+0.1%+82 B 🔺
@sentry/aws-serverless95.93 kB+0.11%+97 B 🔺
@sentry/cloudflare (withSentry) - minified199.28 kB--
@sentry/cloudflare (withSentry)495.43 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch 3 times, most recently from 1318630 to be3a06aCompareAugust 24, 2026 18:44
@logaretm
logaretm marked this pull request as ready for review August 24, 2026 18:50
@logaretm
logaretm requested review from a team as code ownersAugust 24, 2026 18:50
@logaretm
logaretm requested review from chargome and nicohrubec and removed request for a teamAugust 24, 2026 18:50

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.


const client = getClient();
// With span streaming, span names have to be low cardinality, so router spans are named after their route.
const isStreamedRouterSpan = layerType === LAYER_TYPE.ROUTER && !!client && hasSpanStreamingEnabled(client);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoidable getClient calls

Low Severity

Flagged because it was mentioned in the review rules file — this is more an "is this necessary" check than a hard violation. These sites newly call getClient() to gate span streaming, while the Koa, Express, and Hapi integrations already receive a client in setup. Prefering that existing reference would avoid relying on ambient current-client state in multi-client setups.

Additional Locations (2)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.

Names `router` spans after the route they dispatch when span streaming is
enabled, falling back to `Router` when the SDK has no route, per
https://getsentry.github.io/sentry-conventions/names/#routing-router.
Covers all seven sites that emit the `router` op: the OTel-derived and
orchestrion Express integrations, Koa, Hapi, Angular, Ember and SvelteKit
(Svelte 4 and 5). Two of them were leaking high-cardinality values: the
orchestrion Express integration named router spans `layer.path`, which
Express assigns the *matched* URL segment (verified against express
4.22.1: `app.use('/users/:id', router)` yields `/users/123`), and Angular
named them the raw navigation URL, since the parameterized route only
resolves at `ResolveEnd` and is applied to the root span rather than to
the routing span.
Angular, Ember and SvelteKit have no route value at the span, so they take
the fallback. Hapi drops its `GET ` prefix because the convention's
template has no method component.
`traceLifecycle: 'static'` names are byte-identical; the existing static
integration and e2e assertions are the regression check.
@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch from be3a06a to a4622eaCompareAugust 25, 2026 15:43
@logaretm
logaretm merged commit 1dca402 into developAug 25, 2026
531 of 533 checks passed
@logaretm
logaretm deleted the awad/js-3417-emit-low-cardinality-router-span-names branch August 25, 2026 16:47
logaretm added a commit that referenced this pull request Aug 26, 2026
Covers the router span name fallback #23547 added, for the two SDKs it
left untested.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emit low cardinality router span names

2 participants

@logaretm@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(core): Emit low cardinality router span names - #23547

Merged
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names
Aug 25, 2026
Merged

feat(core): Emit low cardinality router span names#23547
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names

Conversation

@logaretm

Copy link
Copy Markdown
Member

Names router spans after the route they dispatch when span streaming is enabled, else Router. Static mode is unchanged.

SDKBeforeAfter
Express (OTel)/c mount pathhttp.route
Express (orchestrion)/users/123http.route
Koa/users/:idsame, Router if pathless
HapiGET /users/{id}/users/{id}
Angular/users/123Router
Emberroute:a -> route:bRouter
SvelteKitSvelteKit Route ChangeRouter

Only Koa already used its http.route. Hapi drops the method since the template has none; Angular, Ember and SvelteKit carry no route.

closes#23532

@linear-code

Copy link
Copy Markdown

JS-3417

@github-actions

github-actionsBot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.82 kB--
@sentry/browser (incl. Tracing)48.55 kB--
@sentry/browser (incl. Tracing + Span Streaming)48.57 kB--
@sentry/browser (incl. Tracing, Profiling)51.47 kB--
@sentry/browser (incl. Tracing, Replay)88 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags77.44 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)92.69 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)105.41 kB--
@sentry/browser (incl. Feedback)45.81 kB--
@sentry/browser (incl. sendFeedback)33.36 kB--
@sentry/browser (incl. FeedbackAsync)38.47 kB--
@sentry/browser (incl. Metrics)29.52 kB--
@sentry/browser (incl. Logs)29.8 kB--
@sentry/browser (incl. Metrics & Logs)30.45 kB--
@sentry/react30.33 kB--
@sentry/react (incl. Tracing)50.76 kB--
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.78 kB--
@sentry/svelte28.6 kB--
CDN Bundle30.32 kB--
CDN Bundle (incl. Tracing)49.07 kB--
CDN Bundle (incl. Logs, Metrics)32.54 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)50.94 kB--
CDN Bundle (incl. Replay, Logs, Metrics)72.96 kB--
CDN Bundle (incl. Tracing, Replay)86.57 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)88.44 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)92.33 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)94.27 kB--
CDN Bundle - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.74 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.43 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.3 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed266.14 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.82 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.84 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.51 kB--
@sentry/nextjs (client)53.27 kB--
@sentry/sveltekit (client)48.97 kB+0.02%+6 B 🔺
@sentry/core/server65.13 kB+0.04%+20 B 🔺
@sentry/core/browser52.27 kB--
@sentry/node121.66 kB+0.09%+102 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.52 kB+0.1%+82 B 🔺
@sentry/aws-serverless95.93 kB+0.11%+97 B 🔺
@sentry/cloudflare (withSentry) - minified199.28 kB--
@sentry/cloudflare (withSentry)495.43 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch 3 times, most recently from 1318630 to be3a06aCompareAugust 24, 2026 18:44
@logaretm
logaretm marked this pull request as ready for review August 24, 2026 18:50
@logaretm
logaretm requested review from a team as code ownersAugust 24, 2026 18:50
@logaretm
logaretm requested review from chargome and nicohrubec and removed request for a teamAugust 24, 2026 18:50

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.


const client = getClient();
// With span streaming, span names have to be low cardinality, so router spans are named after their route.
const isStreamedRouterSpan = layerType === LAYER_TYPE.ROUTER && !!client && hasSpanStreamingEnabled(client);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoidable getClient calls

Low Severity

Flagged because it was mentioned in the review rules file — this is more an "is this necessary" check than a hard violation. These sites newly call getClient() to gate span streaming, while the Koa, Express, and Hapi integrations already receive a client in setup. Prefering that existing reference would avoid relying on ambient current-client state in multi-client setups.

Additional Locations (2)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.

Names `router` spans after the route they dispatch when span streaming is
enabled, falling back to `Router` when the SDK has no route, per
https://getsentry.github.io/sentry-conventions/names/#routing-router.
Covers all seven sites that emit the `router` op: the OTel-derived and
orchestrion Express integrations, Koa, Hapi, Angular, Ember and SvelteKit
(Svelte 4 and 5). Two of them were leaking high-cardinality values: the
orchestrion Express integration named router spans `layer.path`, which
Express assigns the *matched* URL segment (verified against express
4.22.1: `app.use('/users/:id', router)` yields `/users/123`), and Angular
named them the raw navigation URL, since the parameterized route only
resolves at `ResolveEnd` and is applied to the root span rather than to
the routing span.
Angular, Ember and SvelteKit have no route value at the span, so they take
the fallback. Hapi drops its `GET ` prefix because the convention's
template has no method component.
`traceLifecycle: 'static'` names are byte-identical; the existing static
integration and e2e assertions are the regression check.
@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch from be3a06a to a4622eaCompareAugust 25, 2026 15:43
@logaretm
logaretm merged commit 1dca402 into developAug 25, 2026
531 of 533 checks passed
@logaretm
logaretm deleted the awad/js-3417-emit-low-cardinality-router-span-names branch August 25, 2026 16:47
logaretm added a commit that referenced this pull request Aug 26, 2026
Covers the router span name fallback #23547 added, for the two SDKs it
left untested.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emit low cardinality router span names

2 participants

@logaretm@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(core): Emit low cardinality router span names - #23547

Merged
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names
Aug 25, 2026
Merged

feat(core): Emit low cardinality router span names#23547
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names

Conversation

@logaretm

Copy link
Copy Markdown
Member

Names router spans after the route they dispatch when span streaming is enabled, else Router. Static mode is unchanged.

SDKBeforeAfter
Express (OTel)/c mount pathhttp.route
Express (orchestrion)/users/123http.route
Koa/users/:idsame, Router if pathless
HapiGET /users/{id}/users/{id}
Angular/users/123Router
Emberroute:a -> route:bRouter
SvelteKitSvelteKit Route ChangeRouter

Only Koa already used its http.route. Hapi drops the method since the template has none; Angular, Ember and SvelteKit carry no route.

closes#23532

@linear-code

Copy link
Copy Markdown

JS-3417

@github-actions

github-actionsBot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.82 kB--
@sentry/browser (incl. Tracing)48.55 kB--
@sentry/browser (incl. Tracing + Span Streaming)48.57 kB--
@sentry/browser (incl. Tracing, Profiling)51.47 kB--
@sentry/browser (incl. Tracing, Replay)88 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags77.44 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)92.69 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)105.41 kB--
@sentry/browser (incl. Feedback)45.81 kB--
@sentry/browser (incl. sendFeedback)33.36 kB--
@sentry/browser (incl. FeedbackAsync)38.47 kB--
@sentry/browser (incl. Metrics)29.52 kB--
@sentry/browser (incl. Logs)29.8 kB--
@sentry/browser (incl. Metrics & Logs)30.45 kB--
@sentry/react30.33 kB--
@sentry/react (incl. Tracing)50.76 kB--
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.78 kB--
@sentry/svelte28.6 kB--
CDN Bundle30.32 kB--
CDN Bundle (incl. Tracing)49.07 kB--
CDN Bundle (incl. Logs, Metrics)32.54 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)50.94 kB--
CDN Bundle (incl. Replay, Logs, Metrics)72.96 kB--
CDN Bundle (incl. Tracing, Replay)86.57 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)88.44 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)92.33 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)94.27 kB--
CDN Bundle - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.74 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.43 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.3 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed266.14 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.82 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.84 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.51 kB--
@sentry/nextjs (client)53.27 kB--
@sentry/sveltekit (client)48.97 kB+0.02%+6 B 🔺
@sentry/core/server65.13 kB+0.04%+20 B 🔺
@sentry/core/browser52.27 kB--
@sentry/node121.66 kB+0.09%+102 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.52 kB+0.1%+82 B 🔺
@sentry/aws-serverless95.93 kB+0.11%+97 B 🔺
@sentry/cloudflare (withSentry) - minified199.28 kB--
@sentry/cloudflare (withSentry)495.43 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch 3 times, most recently from 1318630 to be3a06aCompareAugust 24, 2026 18:44
@logaretm
logaretm marked this pull request as ready for review August 24, 2026 18:50
@logaretm
logaretm requested review from a team as code ownersAugust 24, 2026 18:50
@logaretm
logaretm requested review from chargome and nicohrubec and removed request for a teamAugust 24, 2026 18:50

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.


const client = getClient();
// With span streaming, span names have to be low cardinality, so router spans are named after their route.
const isStreamedRouterSpan = layerType === LAYER_TYPE.ROUTER && !!client && hasSpanStreamingEnabled(client);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoidable getClient calls

Low Severity

Flagged because it was mentioned in the review rules file — this is more an "is this necessary" check than a hard violation. These sites newly call getClient() to gate span streaming, while the Koa, Express, and Hapi integrations already receive a client in setup. Prefering that existing reference would avoid relying on ambient current-client state in multi-client setups.

Additional Locations (2)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.

Names `router` spans after the route they dispatch when span streaming is
enabled, falling back to `Router` when the SDK has no route, per
https://getsentry.github.io/sentry-conventions/names/#routing-router.
Covers all seven sites that emit the `router` op: the OTel-derived and
orchestrion Express integrations, Koa, Hapi, Angular, Ember and SvelteKit
(Svelte 4 and 5). Two of them were leaking high-cardinality values: the
orchestrion Express integration named router spans `layer.path`, which
Express assigns the *matched* URL segment (verified against express
4.22.1: `app.use('/users/:id', router)` yields `/users/123`), and Angular
named them the raw navigation URL, since the parameterized route only
resolves at `ResolveEnd` and is applied to the root span rather than to
the routing span.
Angular, Ember and SvelteKit have no route value at the span, so they take
the fallback. Hapi drops its `GET ` prefix because the convention's
template has no method component.
`traceLifecycle: 'static'` names are byte-identical; the existing static
integration and e2e assertions are the regression check.
@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch from be3a06a to a4622eaCompareAugust 25, 2026 15:43
@logaretm
logaretm merged commit 1dca402 into developAug 25, 2026
531 of 533 checks passed
@logaretm
logaretm deleted the awad/js-3417-emit-low-cardinality-router-span-names branch August 25, 2026 16:47
logaretm added a commit that referenced this pull request Aug 26, 2026
Covers the router span name fallback #23547 added, for the two SDKs it
left untested.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emit low cardinality router span names

2 participants

@logaretm@s1gr1d
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(core): Emit low cardinality router span names - #23547

Merged
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names
Aug 25, 2026
Merged

feat(core): Emit low cardinality router span names#23547
logaretm merged 1 commit into
developfrom
awad/js-3417-emit-low-cardinality-router-span-names

Conversation

@logaretm

Copy link
Copy Markdown
Member

Names router spans after the route they dispatch when span streaming is enabled, else Router. Static mode is unchanged.

SDKBeforeAfter
Express (OTel)/c mount pathhttp.route
Express (orchestrion)/users/123http.route
Koa/users/:idsame, Router if pathless
HapiGET /users/{id}/users/{id}
Angular/users/123Router
Emberroute:a -> route:bRouter
SvelteKitSvelteKit Route ChangeRouter

Only Koa already used its http.route. Hapi drops the method since the template has none; Angular, Ember and SvelteKit carry no route.

closes#23532

@linear-code

Copy link
Copy Markdown

JS-3417

@github-actions

github-actionsBot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser28.57 kB--
@sentry/browser - with treeshaking flags26.92 kB--
@sentry/browser - with treeshaking flags tracing without tracing26.82 kB--
@sentry/browser (incl. Tracing)48.55 kB--
@sentry/browser (incl. Tracing + Span Streaming)48.57 kB--
@sentry/browser (incl. Tracing, Profiling)51.47 kB--
@sentry/browser (incl. Tracing, Replay)88 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags77.44 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)92.69 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)105.41 kB--
@sentry/browser (incl. Feedback)45.81 kB--
@sentry/browser (incl. sendFeedback)33.36 kB--
@sentry/browser (incl. FeedbackAsync)38.47 kB--
@sentry/browser (incl. Metrics)29.52 kB--
@sentry/browser (incl. Logs)29.8 kB--
@sentry/browser (incl. Metrics & Logs)30.45 kB--
@sentry/react30.33 kB--
@sentry/react (incl. Tracing)50.76 kB--
@sentry/vue35.64 kB--
@sentry/vue (incl. Tracing)50.78 kB--
@sentry/svelte28.6 kB--
CDN Bundle30.32 kB--
CDN Bundle (incl. Tracing)49.07 kB--
CDN Bundle (incl. Logs, Metrics)32.54 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)50.94 kB--
CDN Bundle (incl. Replay, Logs, Metrics)72.96 kB--
CDN Bundle (incl. Tracing, Replay)86.57 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)88.44 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)92.33 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)94.27 kB--
CDN Bundle - uncompressed89.94 kB--
CDN Bundle (incl. Tracing) - uncompressed146.74 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed96.23 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed152.43 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed225.3 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed266.14 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed271.82 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279.84 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed285.51 kB--
@sentry/nextjs (client)53.27 kB--
@sentry/sveltekit (client)48.97 kB+0.02%+6 B 🔺
@sentry/core/server65.13 kB+0.04%+20 B 🔺
@sentry/core/browser52.27 kB--
@sentry/node121.66 kB+0.09%+102 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection)85.18 kB--
@sentry/node - without tracing87.52 kB+0.1%+82 B 🔺
@sentry/aws-serverless95.93 kB+0.11%+97 B 🔺
@sentry/cloudflare (withSentry) - minified199.28 kB--
@sentry/cloudflare (withSentry)495.43 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch 3 times, most recently from 1318630 to be3a06aCompareAugust 24, 2026 18:44
@logaretm
logaretm marked this pull request as ready for review August 24, 2026 18:50
@logaretm
logaretm requested review from a team as code ownersAugust 24, 2026 18:50
@logaretm
logaretm requested review from chargome and nicohrubec and removed request for a teamAugust 24, 2026 18:50

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.


const client = getClient();
// With span streaming, span names have to be low cardinality, so router spans are named after their route.
const isStreamedRouterSpan = layerType === LAYER_TYPE.ROUTER && !!client && hasSpanStreamingEnabled(client);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoidable getClient calls

Low Severity

Flagged because it was mentioned in the review rules file — this is more an "is this necessary" check than a hard violation. These sites newly call getClient() to gate span streaming, while the Koa, Express, and Hapi integrations already receive a client in setup. Prefering that existing reference would avoid relying on ambient current-client state in multi-client setups.

Additional Locations (2)
Fix in CursorFix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit be3a06a. Configure here.

Names `router` spans after the route they dispatch when span streaming is
enabled, falling back to `Router` when the SDK has no route, per
https://getsentry.github.io/sentry-conventions/names/#routing-router.
Covers all seven sites that emit the `router` op: the OTel-derived and
orchestrion Express integrations, Koa, Hapi, Angular, Ember and SvelteKit
(Svelte 4 and 5). Two of them were leaking high-cardinality values: the
orchestrion Express integration named router spans `layer.path`, which
Express assigns the *matched* URL segment (verified against express
4.22.1: `app.use('/users/:id', router)` yields `/users/123`), and Angular
named them the raw navigation URL, since the parameterized route only
resolves at `ResolveEnd` and is applied to the root span rather than to
the routing span.
Angular, Ember and SvelteKit have no route value at the span, so they take
the fallback. Hapi drops its `GET ` prefix because the convention's
template has no method component.
`traceLifecycle: 'static'` names are byte-identical; the existing static
integration and e2e assertions are the regression check.
@logaretm
logaretmforce-pushed the awad/js-3417-emit-low-cardinality-router-span-names branch from be3a06a to a4622eaCompareAugust 25, 2026 15:43
@logaretm
logaretm merged commit 1dca402 into developAug 25, 2026
531 of 533 checks passed
@logaretm
logaretm deleted the awad/js-3417-emit-low-cardinality-router-span-names branch August 25, 2026 16:47
logaretm added a commit that referenced this pull request Aug 26, 2026
Covers the router span name fallback #23547 added, for the two SDKs it
left untested.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emit low cardinality router span names

2 participants

@logaretm@s1gr1d