1- import { WINDOW , captureException } from '@sentry/browser' ;
1+ import { captureException } from '@sentry/browser' ;
22import {
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 */
9837export 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