Skip to content

Commit 829d885

Browse files
committed
fix(astro): Ensure span name from beforeStartSpan isn't overwritten
1 parent ec29e5d commit 829d885

File tree

5 files changed

+85
-28
lines changed

5 files changed

+85
-28
lines changed

dev-packages/e2e-tests/test-applications/astro-5/sentry.client.config.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,17 @@ Sentry.init({
55
environment: 'qa',
66
tracesSampleRate: 1.0,
77
tunnel: 'http://localhost:3031/', // proxy server
8-
integrations: [Sentry.browserTracingIntegration()],
8+
integrations: [
9+
Sentry.browserTracingIntegration({
10+
beforeStartSpan: opts => {
11+
if (opts.name.startsWith('/blog/')) {
12+
return {
13+
...opts,
14+
name: window.location.pathname,
15+
}
16+
}
17+
return opts;
18+
}
19+
})
20+
],
921
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
import Layout from '../../layouts/Layout.astro';
3+
4+
export const prerender = false;
5+
6+
const { slug } = Astro.params;
7+
8+
---
9+
10+
<Layout title="Dynamic SSR page">
11+
<h1>Blog post: {slug}</h1>
12+
</Layout>

dev-packages/e2e-tests/test-applications/astro-5/src/pages/index.astro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import Layout from '../layouts/Layout.astro';
1717
<a href="/test-static" title="static page">Static Page</a>
1818
<a href="/server-island">Server Island</a>
1919
<a href="/user-page/myUsername123">Test Parametrized Routes</a>
20+
<a href="/blog/my-post">Route Parametrization override</a>
2021
</ul>
2122
</main>
2223
</Layout>

dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,4 +369,18 @@ test.describe('parametrized vs static paths', () => {
369369
request: { url: expect.stringContaining('/user-page/settings') },
370370
});
371371
});
372+
373+
test('allows for span name override via beforeStartSpan', async ({ page }) => {
374+
const clientPageloadTxnPromise = waitForTransaction('astro-5', txnEvent => {
375+
return txnEvent?.transaction?.startsWith('/blog/') ?? false;
376+
});
377+
378+
await page.goto('/blog/my-post');
379+
380+
const clientPageloadTxn = await clientPageloadTxnPromise;
381+
expect(clientPageloadTxn).toMatchObject({
382+
transaction: '/blog/my-post',
383+
transaction_info: { source: 'custom' },
384+
});
385+
});
372386
});
Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { browserTracingIntegration as originalBrowserTracingIntegration, WINDOW } from '@sentry/browser';
1+
import { browserTracingIntegration as originalBrowserTracingIntegration, startBrowserTracingPageLoadSpan, WINDOW } from '@sentry/browser';
22
import type { Integration, TransactionSource } from '@sentry/core';
3-
import { debug, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core';
3+
import { browserPerformanceTimeOrigin, debug, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core';
44
import { DEBUG_BUILD } from '../debug-build';
55

66
/**
@@ -18,35 +18,53 @@ function getMetaContent(metaName: string): string | undefined {
1818
export function browserTracingIntegration(
1919
options: Parameters<typeof originalBrowserTracingIntegration>[0] = {},
2020
): Integration {
21-
const integration = originalBrowserTracingIntegration(options);
21+
const integration = originalBrowserTracingIntegration({...options, instrumentPageLoad: false});
2222

2323
return {
2424
...integration,
25-
setup(client) {
26-
// Original integration setup call
27-
integration.setup?.(client);
28-
29-
client.on('afterStartPageLoadSpan', pageLoadSpan => {
30-
const routeNameFromMetaTags = getMetaContent('sentry-route-name');
31-
32-
if (routeNameFromMetaTags) {
33-
let decodedRouteName;
34-
try {
35-
decodedRouteName = decodeURIComponent(routeNameFromMetaTags);
36-
} catch {
37-
// We ignore errors here, e.g. if the value cannot be URL decoded.
38-
return;
39-
}
40-
41-
DEBUG_BUILD && debug.log(`[Tracing] Using route name from Sentry HTML meta-tag: ${decodedRouteName}`);
42-
43-
pageLoadSpan.updateName(decodedRouteName);
44-
pageLoadSpan.setAttributes({
45-
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route' as TransactionSource,
46-
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.astro',
25+
afterAllSetup(client) {
26+
// Original integration afterAllSetup call
27+
integration.afterAllSetup?.(client);
28+
29+
if (WINDOW.location) {
30+
if (options.instrumentPageLoad != false) {
31+
const origin = browserPerformanceTimeOrigin();
32+
33+
const { name, source } = getPageloadSpanName();
34+
35+
startBrowserTracingPageLoadSpan(client, {
36+
name,
37+
// pageload should always start at timeOrigin (and needs to be in s, not ms)
38+
startTime: origin ? origin / 1000 : undefined,
39+
attributes: {
40+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,
41+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.astro',
42+
},
4743
});
4844
}
49-
});
50-
},
45+
}
46+
}
47+
};
48+
}
49+
50+
function getPageloadSpanName(): {name: string, source: TransactionSource} {
51+
try {
52+
const routeNameFromMetaTags = getMetaContent('sentry-route-name');
53+
if (routeNameFromMetaTags) {
54+
const decodedRouteName = decodeURIComponent(routeNameFromMetaTags);
55+
56+
DEBUG_BUILD && debug.log(`[Tracing] Using route name from Sentry HTML meta-tag: ${decodedRouteName}`);
57+
58+
return {
59+
name: decodedRouteName,
60+
source: 'route',
61+
};
62+
}
63+
} catch {
64+
// fail silently if decoding or reading the meta tag fails
65+
}
66+
return {
67+
name: WINDOW.location.pathname,
68+
source: 'url',
5169
};
5270
}

0 commit comments

Comments
 (0)