@@ -54,8 +54,8 @@ interface IntegrationOptions {
54
54
logErrors : boolean ;
55
55
56
56
/**
57
- * When set to `false `, disables tracking of components lifecycle performance.
58
- * By default, it tracks only when `Tracing` integration is also enabled.
57
+ * When set to `true `, enables tracking of components lifecycle performance.
58
+ * It requires `Tracing` integration to be also enabled.
59
59
*/
60
60
tracing : boolean ;
61
61
@@ -75,9 +75,10 @@ interface TracingOptions {
75
75
timeout : number ;
76
76
/**
77
77
* List of hooks to keep track of during component lifecycle.
78
- * Available hooks: https://vuejs.org/v2/api/#Options-Lifecycle-Hooks
78
+ * Available hooks: 'activate' | 'create' | 'destroy' | 'mount' | 'update'
79
+ * Based on https://vuejs.org/v2/api/#Options-Lifecycle-Hooks
79
80
*/
80
- hooks : Hook [ ] ;
81
+ hooks : Operation [ ] ;
81
82
}
82
83
83
84
/** Optional metadata attached to Sentry Event */
@@ -103,19 +104,13 @@ type Hook =
103
104
104
105
type Operation = 'activate' | 'create' | 'destroy' | 'mount' | 'update' ;
105
106
106
- // Mappings from lifecycle hook to corresponding operation,
107
- // used to track already started measurements.
108
- const OPERATIONS : { [ key in Hook ] : Operation } = {
109
- activated : 'activate' ,
110
- beforeCreate : 'create' ,
111
- beforeDestroy : 'destroy' ,
112
- beforeMount : 'mount' ,
113
- beforeUpdate : 'update' ,
114
- created : 'create' ,
115
- deactivated : 'activate' ,
116
- destroyed : 'destroy' ,
117
- mounted : 'mount' ,
118
- updated : 'update' ,
107
+ // Mappings from operation to corresponding lifecycle hook.
108
+ const HOOKS : { [ key in Operation ] : Hook [ ] } = {
109
+ activate : [ 'activated' , 'deactivated' ] ,
110
+ create : [ 'beforeCreate' , 'created' ] ,
111
+ destroy : [ 'beforeDestroy' , 'destroyed' ] ,
112
+ mount : [ 'beforeMount' , 'mounted' ] ,
113
+ update : [ 'beforeUpdate' , 'updated' ] ,
119
114
} ;
120
115
121
116
const COMPONENT_NAME_REGEXP = / (?: ^ | [ - _ / ] ) ( \w ) / g;
@@ -152,10 +147,10 @@ export class Vue implements Integration {
152
147
Vue : getGlobalObject < any > ( ) . Vue , // tslint:disable-line:no-unsafe-any
153
148
attachProps : true ,
154
149
logErrors : false ,
155
- tracing : true ,
150
+ tracing : false ,
156
151
...options ,
157
152
tracingOptions : {
158
- hooks : [ 'beforeMount ' , 'mounted' , 'beforeUpdate' , 'updated '] ,
153
+ hooks : [ 'mount ' , 'update ' ] ,
159
154
timeout : 2000 ,
160
155
trackComponents : false ,
161
156
...options . tracingOptions ,
@@ -252,19 +247,18 @@ export class Vue implements Integration {
252
247
}
253
248
} ;
254
249
255
- const childHandler = ( hook : Hook ) => {
250
+ const childHandler = ( hook : Hook , operation : Operation ) => {
256
251
// Skip components that we don't want to track to minimize the noise and give a more granular control to the user
257
252
const shouldTrack = Array . isArray ( this . _options . tracingOptions . trackComponents )
258
- ? this . _options . tracingOptions . trackComponents . includes ( name )
253
+ ? this . _options . tracingOptions . trackComponents . indexOf ( name ) > - 1
259
254
: this . _options . tracingOptions . trackComponents ;
260
255
261
256
if ( ! this . _rootSpan || ! shouldTrack ) {
262
257
return ;
263
258
}
264
259
265
260
const now = timestampWithMs ( ) ;
266
- const op = OPERATIONS [ hook ] ;
267
- const span = spans [ op ] ;
261
+ const span = spans [ operation ] ;
268
262
269
263
// On the first handler call (before), it'll be undefined, as `$once` will add it in the future.
270
264
// However, on the second call (after), it'll be already in place.
@@ -274,27 +268,40 @@ export class Vue implements Integration {
274
268
} else {
275
269
vm . $once ( `hook:${ hook } ` , ( ) => {
276
270
if ( this . _rootSpan ) {
277
- spans [ op ] = this . _rootSpan . startChild ( {
271
+ spans [ operation ] = this . _rootSpan . startChild ( {
278
272
description : `Vue <${ name } >` ,
279
- op,
273
+ op : operation ,
280
274
} ) ;
281
275
}
282
276
} ) ;
283
277
}
284
278
} ;
285
279
286
280
// Each compomnent has it's own scope, so all activities are only related to one of them
287
- this . _options . tracingOptions . hooks . forEach ( hook => {
288
- const handler = rootMount ? rootHandler . bind ( this , hook ) : childHandler . bind ( this , hook ) ;
289
- const currentValue = vm . $options [ hook ] ;
290
-
291
- if ( Array . isArray ( currentValue ) ) {
292
- vm . $options [ hook ] = [ handler , ...currentValue ] ;
293
- } else if ( typeof currentValue === 'function' ) {
294
- vm . $options [ hook ] = [ handler , currentValue ] ;
295
- } else {
296
- vm . $options [ hook ] = [ handler ] ;
281
+ this . _options . tracingOptions . hooks . forEach ( operation => {
282
+ // Retrieve corresponding hooks from Vue lifecycle.
283
+ // eg. mount => ['beforeMount', 'mounted']
284
+ const internalHooks = HOOKS [ operation ] ;
285
+
286
+ if ( ! internalHooks ) {
287
+ logger . warn ( `Unknown hook: ${ operation } ` ) ;
288
+ return ;
297
289
}
290
+
291
+ internalHooks . forEach ( internalHook => {
292
+ const handler = rootMount
293
+ ? rootHandler . bind ( this , internalHook )
294
+ : childHandler . bind ( this , internalHook , operation ) ;
295
+ const currentValue = vm . $options [ internalHook ] ;
296
+
297
+ if ( Array . isArray ( currentValue ) ) {
298
+ vm . $options [ internalHook ] = [ handler , ...currentValue ] ;
299
+ } else if ( typeof currentValue === 'function' ) {
300
+ vm . $options [ internalHook ] = [ handler , currentValue ] ;
301
+ } else {
302
+ vm . $options [ internalHook ] = [ handler ] ;
303
+ }
304
+ } ) ;
298
305
} ) ;
299
306
} ;
300
307
0 commit comments