@@ -74,6 +74,16 @@ interface TracingOptions {
74
74
* Default: 600
75
75
*/
76
76
maxTransactionDuration : number ;
77
+
78
+ /**
79
+ * Flag to discard all spans that occur in background. This includes transactions. Browser background tab timing is
80
+ * not suited towards doing precise measurements of operations. That's why this option discards any active transaction
81
+ * and also doesn't add any spans that happen in the background. Background spans/transaction can mess up your
82
+ * statistics in non deterministic ways that's why we by default recommend leaving this opition enabled.
83
+ *
84
+ * Default: true
85
+ */
86
+ discardBackgroundSpans : boolean ;
77
87
}
78
88
79
89
/** JSDoc */
@@ -114,9 +124,9 @@ export class Tracing implements Integration {
114
124
115
125
private static _activeTransaction ?: Span ;
116
126
117
- private static _currentIndex : number = 0 ;
127
+ private static _currentIndex : number = 1 ;
118
128
119
- public static readonly _activities : { [ key : number ] : Activity } = { } ;
129
+ public static _activities : { [ key : number ] : Activity } = { } ;
120
130
121
131
private static _debounce : number = 0 ;
122
132
@@ -127,8 +137,9 @@ export class Tracing implements Integration {
127
137
*
128
138
* @param _options TracingOptions
129
139
*/
130
- public constructor ( private readonly _options ?: Partial < TracingOptions > ) {
140
+ public constructor ( _options ?: Partial < TracingOptions > ) {
131
141
const defaults = {
142
+ discardBackgroundSpans : true ,
132
143
idleTimeout : 500 ,
133
144
maxTransactionDuration : 600 ,
134
145
shouldCreateSpanForRequest ( url : string ) : boolean {
@@ -148,7 +159,7 @@ export class Tracing implements Integration {
148
159
if ( ! _options || ! Array . isArray ( _options . tracingOrigins ) || _options . tracingOrigins . length === 0 ) {
149
160
this . _emitOptionsWarning = true ;
150
161
}
151
- Tracing . options = this . _options = {
162
+ Tracing . options = {
152
163
...defaults ,
153
164
..._options ,
154
165
} ;
@@ -171,23 +182,21 @@ export class Tracing implements Integration {
171
182
return ;
172
183
}
173
184
174
- // tslint:disable-next-line: no-non-null-assertion
175
- if ( this . _options ! . traceXHR !== false ) {
185
+ if ( Tracing . options . traceXHR ) {
176
186
addInstrumentationHandler ( {
177
187
callback : xhrCallback ,
178
188
type : 'xhr' ,
179
189
} ) ;
180
190
}
181
- // tslint:disable-next-line: no-non-null-assertion
182
- if ( this . _options ! . traceFetch !== false && supportsNativeFetch ( ) ) {
191
+
192
+ if ( Tracing . options . traceFetch && supportsNativeFetch ( ) ) {
183
193
addInstrumentationHandler ( {
184
194
callback : fetchCallback ,
185
195
type : 'fetch' ,
186
196
} ) ;
187
197
}
188
198
189
- // tslint:disable-next-line: no-non-null-assertion
190
- if ( this . _options ! . startTransactionOnLocationChange ) {
199
+ if ( Tracing . options . startTransactionOnLocationChange ) {
191
200
addInstrumentationHandler ( {
192
201
callback : historyCallback ,
193
202
type : 'history' ,
@@ -202,6 +211,16 @@ export class Tracing implements Integration {
202
211
} ) ;
203
212
}
204
213
214
+ if ( Tracing . options . discardBackgroundSpans && global . document ) {
215
+ document . addEventListener ( 'visibilitychange' , ( ) => {
216
+ if ( document . hidden && Tracing . _activeTransaction ) {
217
+ logger . log ( '[Tracing] Discarded active transaction incl. activities since tab moved to the background' ) ;
218
+ Tracing . _activeTransaction = undefined ;
219
+ Tracing . _activities = { } ;
220
+ }
221
+ } ) ;
222
+ }
223
+
205
224
// This EventProcessor makes sure that the transaction is not longer than maxTransactionDuration
206
225
addGlobalEventProcessor ( ( event : Event ) => {
207
226
const self = getCurrentHub ( ) . getIntegration ( Tracing ) ;
@@ -351,6 +370,10 @@ export class Tracing implements Integration {
351
370
// Tracing is not enabled
352
371
return 0 ;
353
372
}
373
+ if ( ! Tracing . _activeTransaction ) {
374
+ logger . log ( `[Tracing] Not pushing activity ${ name } since there is no active transaction` ) ;
375
+ return 0 ;
376
+ }
354
377
355
378
// We want to clear the timeout also here since we push a new activity
356
379
clearTimeout ( Tracing . _debounce ) ;
@@ -389,7 +412,10 @@ export class Tracing implements Integration {
389
412
* Removes activity and finishes the span in case there is one
390
413
*/
391
414
public static popActivity ( id : number , spanData ?: { [ key : string ] : any } ) : void {
392
- if ( ! Tracing . _isEnabled ( ) ) {
415
+ // The !id is on purpose to also fail with 0
416
+ // Since 0 is returned by push activity in case tracing is not enabled
417
+ // or there is no active transaction
418
+ if ( ! Tracing . _isEnabled ( ) || ! id ) {
393
419
// Tracing is not enabled
394
420
return ;
395
421
}
@@ -422,7 +448,7 @@ export class Tracing implements Integration {
422
448
423
449
logger . log ( '[Tracing] activies count' , count ) ;
424
450
425
- if ( count === 0 ) {
451
+ if ( count === 0 && Tracing . _activeTransaction ) {
426
452
const timeout = Tracing . options && Tracing . options . idleTimeout ;
427
453
logger . log ( `[Tracing] Flushing Transaction in ${ timeout } ms` ) ;
428
454
Tracing . _debounce = ( setTimeout ( ( ) => {
0 commit comments