Skip to content

Commit ddf5bcc

Browse files
committed
introduce activeRootSpan
1 parent 186c5b3 commit ddf5bcc

File tree

1 file changed

+28
-70
lines changed

1 file changed

+28
-70
lines changed

packages/vue/src/router.ts

Lines changed: 28 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,12 @@
1-
import { WINDOW, captureException } from '@sentry/browser';
1+
import { captureException } from '@sentry/browser';
22
import {
33
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
44
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
55
getActiveSpan,
66
getRootSpan,
77
spanToJSON,
88
} from '@sentry/core';
9-
import type { SpanAttributes, Transaction, TransactionContext, TransactionSource } from '@sentry/types';
10-
11-
interface VueRouterInstrumationOptions {
12-
/**
13-
* What to use for route labels.
14-
* By default, we use route.name (if set) and else the path.
15-
*
16-
* Default: 'name'
17-
*/
18-
routeLabel: 'name' | 'path';
19-
}
20-
21-
export type VueRouterInstrumentation = <T extends Transaction>(
22-
startTransaction: (context: TransactionContext) => T | undefined,
23-
startTransactionOnPageLoad?: boolean,
24-
startTransactionOnLocationChange?: boolean,
25-
) => void;
9+
import type { Span, SpanAttributes, TransactionContext, TransactionSource } from '@sentry/types';
2610

2711
// The following type is an intersection of the Route type from VueRouter v2, v3, and v4.
2812
// This is not great, but kinda necessary to make it work with all versions at the same time.
@@ -47,57 +31,18 @@ interface VueRouter {
4731
beforeEach: (fn: (to: Route, from: Route, next?: () => void) => void) => void;
4832
}
4933

50-
/**
51-
* Creates routing instrumentation for Vue Router v2, v3 and v4
52-
*
53-
* You can optionally pass in an options object with the available option:
54-
* * `routeLabel`: Set this to `route` to opt-out of using `route.name` for transaction names.
55-
*
56-
* @param router The Vue Router instance that is used
57-
*
58-
* @deprecated Use `browserTracingIntegration()` from `@sentry/vue` instead - this includes the vue router instrumentation.
59-
*/
60-
export function vueRouterInstrumentation(
61-
router: VueRouter,
62-
options: Partial<VueRouterInstrumationOptions> = {},
63-
): VueRouterInstrumentation {
64-
return (
65-
startTransaction: (context: TransactionContext) => Transaction | undefined,
66-
startTransactionOnPageLoad: boolean = true,
67-
startTransactionOnLocationChange: boolean = true,
68-
) => {
69-
// We have to start the pageload transaction as early as possible (before the router's `beforeEach` hook
70-
// is called) to not miss child spans of the pageload.
71-
// We check that window & window.location exists in order to not run this code in SSR environments.
72-
if (startTransactionOnPageLoad && WINDOW && WINDOW.location) {
73-
startTransaction({
74-
name: WINDOW.location.pathname,
75-
op: 'pageload',
76-
attributes: {
77-
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.vue',
78-
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
79-
},
80-
});
81-
}
82-
83-
instrumentVueRouter(
84-
router,
85-
{
86-
routeLabel: options.routeLabel || 'name',
87-
instrumentNavigation: startTransactionOnLocationChange,
88-
instrumentPageLoad: startTransactionOnPageLoad,
89-
},
90-
startTransaction,
91-
);
92-
};
93-
}
94-
9534
/**
9635
* Instrument the Vue router to create navigation spans.
9736
*/
9837
export function instrumentVueRouter(
9938
router: VueRouter,
10039
options: {
40+
/**
41+
* What to use for route labels.
42+
* By default, we use route.name (if set) and else the path.
43+
*
44+
* Default: 'name'
45+
*/
10146
routeLabel: 'name' | 'path';
10247
instrumentPageLoad: boolean;
10348
instrumentNavigation: boolean;
@@ -143,17 +88,16 @@ export function instrumentVueRouter(
14388
}
14489

14590
if (options.instrumentPageLoad && isPageLoadNavigation) {
146-
const activeSpan = getActiveSpan();
147-
const rootSpan = activeSpan && getRootSpan(activeSpan);
148-
if (rootSpan) {
149-
const existingAttributes = spanToJSON(rootSpan).data || {};
91+
const activeRootSpan = getActiveRootSpan();
92+
if (activeRootSpan) {
93+
const existingAttributes = spanToJSON(activeRootSpan).data || {};
15094
if (existingAttributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] !== 'custom') {
151-
rootSpan.updateName(transactionName);
152-
rootSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, transactionSource);
95+
activeRootSpan.updateName(transactionName);
96+
activeRootSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, transactionSource);
15397
}
15498
// Set router attributes on the existing pageload transaction
15599
// This will override the origin, and add params & query attributes
156-
rootSpan.setAttributes({
100+
activeRootSpan.setAttributes({
157101
...attributes,
158102
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.vue',
159103
});
@@ -178,3 +122,17 @@ export function instrumentVueRouter(
178122
}
179123
});
180124
}
125+
126+
function getActiveRootSpan(): Span | undefined {
127+
const span = getActiveSpan();
128+
const rootSpan = span ? getRootSpan(span) : undefined;
129+
130+
if (!rootSpan) {
131+
return undefined;
132+
}
133+
134+
const op = spanToJSON(rootSpan).op;
135+
136+
// Only use this root span if it is a pageload or navigation span
137+
return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;
138+
}

0 commit comments

Comments
 (0)