1
- import { WINDOW , captureException } from '@sentry/browser' ;
2
- import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN , SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , spanToJSON } from '@sentry/core' ;
3
- import type { SpanAttributes , Transaction , TransactionContext , TransactionSource } from '@sentry/types' ;
4
-
5
- import { getActiveTransaction } from './tracing' ;
6
-
7
- interface VueRouterInstrumationOptions {
8
- /**
9
- * What to use for route labels.
10
- * By default, we use route.name (if set) and else the path.
11
- *
12
- * Default: 'name'
13
- */
14
- routeLabel : 'name' | 'path' ;
15
- }
16
-
17
- export type VueRouterInstrumentation = < T extends Transaction > (
18
- startTransaction : ( context : TransactionContext ) => T | undefined ,
19
- startTransactionOnPageLoad ?: boolean ,
20
- startTransactionOnLocationChange ?: boolean ,
21
- ) => void ;
1
+ import { captureException } from '@sentry/browser' ;
2
+ import {
3
+ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ,
4
+ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ,
5
+ getActiveSpan ,
6
+ getRootSpan ,
7
+ spanToJSON ,
8
+ } from '@sentry/core' ;
9
+ import type { Span , SpanAttributes , TransactionContext , TransactionSource } from '@sentry/types' ;
22
10
23
11
// The following type is an intersection of the Route type from VueRouter v2, v3, and v4.
24
12
// This is not great, but kinda necessary to make it work with all versions at the same time.
@@ -43,57 +31,18 @@ interface VueRouter {
43
31
beforeEach : ( fn : ( to : Route , from : Route , next ?: ( ) => void ) => void ) => void ;
44
32
}
45
33
46
- /**
47
- * Creates routing instrumentation for Vue Router v2, v3 and v4
48
- *
49
- * You can optionally pass in an options object with the available option:
50
- * * `routeLabel`: Set this to `route` to opt-out of using `route.name` for transaction names.
51
- *
52
- * @param router The Vue Router instance that is used
53
- *
54
- * @deprecated Use `browserTracingIntegration()` from `@sentry/vue` instead - this includes the vue router instrumentation.
55
- */
56
- export function vueRouterInstrumentation (
57
- router : VueRouter ,
58
- options : Partial < VueRouterInstrumationOptions > = { } ,
59
- ) : VueRouterInstrumentation {
60
- return (
61
- startTransaction : ( context : TransactionContext ) => Transaction | undefined ,
62
- startTransactionOnPageLoad : boolean = true ,
63
- startTransactionOnLocationChange : boolean = true ,
64
- ) => {
65
- // We have to start the pageload transaction as early as possible (before the router's `beforeEach` hook
66
- // is called) to not miss child spans of the pageload.
67
- // We check that window & window.location exists in order to not run this code in SSR environments.
68
- if ( startTransactionOnPageLoad && WINDOW && WINDOW . location ) {
69
- startTransaction ( {
70
- name : WINDOW . location . pathname ,
71
- op : 'pageload' ,
72
- attributes : {
73
- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.pageload.vue' ,
74
- [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'url' ,
75
- } ,
76
- } ) ;
77
- }
78
-
79
- instrumentVueRouter (
80
- router ,
81
- {
82
- routeLabel : options . routeLabel || 'name' ,
83
- instrumentNavigation : startTransactionOnLocationChange ,
84
- instrumentPageLoad : startTransactionOnPageLoad ,
85
- } ,
86
- startTransaction ,
87
- ) ;
88
- } ;
89
- }
90
-
91
34
/**
92
35
* Instrument the Vue router to create navigation spans.
93
36
*/
94
37
export function instrumentVueRouter (
95
38
router : VueRouter ,
96
39
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
+ */
97
46
routeLabel : 'name' | 'path' ;
98
47
instrumentPageLoad : boolean ;
99
48
instrumentNavigation : boolean ;
@@ -139,17 +88,16 @@ export function instrumentVueRouter(
139
88
}
140
89
141
90
if ( options . instrumentPageLoad && isPageLoadNavigation ) {
142
- // eslint-disable-next-line deprecation/deprecation
143
- const pageloadTransaction = getActiveTransaction ( ) ;
144
- if ( pageloadTransaction ) {
145
- const existingAttributes = spanToJSON ( pageloadTransaction ) . data || { } ;
91
+ const activeRootSpan = getActiveRootSpan ( ) ;
92
+ if ( activeRootSpan ) {
93
+ const existingAttributes = spanToJSON ( activeRootSpan ) . data || { } ;
146
94
if ( existingAttributes [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] !== 'custom' ) {
147
- pageloadTransaction . updateName ( transactionName ) ;
148
- pageloadTransaction . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , transactionSource ) ;
95
+ activeRootSpan . updateName ( transactionName ) ;
96
+ activeRootSpan . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , transactionSource ) ;
149
97
}
150
98
// Set router attributes on the existing pageload transaction
151
- // This will the origin, and add params & query attributes
152
- pageloadTransaction . setAttributes ( {
99
+ // This will override the origin, and add params & query attributes
100
+ activeRootSpan . setAttributes ( {
153
101
...attributes ,
154
102
[ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.pageload.vue' ,
155
103
} ) ;
@@ -158,6 +106,7 @@ export function instrumentVueRouter(
158
106
159
107
if ( options . instrumentNavigation && ! isPageLoadNavigation ) {
160
108
attributes [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] = transactionSource ;
109
+ attributes [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] = 'auto.navigation.vue' ;
161
110
startNavigationSpanFn ( {
162
111
name : transactionName ,
163
112
op : 'navigation' ,
@@ -173,3 +122,17 @@ export function instrumentVueRouter(
173
122
}
174
123
} ) ;
175
124
}
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