11import { EventProcessor , Hub , Integration , Span , SpanContext , SpanStatus } from '@sentry/types' ;
2- import {
3- addInstrumentationHandler ,
4- fill ,
5- getGlobalObject ,
6- isMatchingPattern ,
7- logger ,
8- supportsNativeFetch ,
9- } from '@sentry/utils' ;
2+ import { addInstrumentationHandler , getGlobalObject , isMatchingPattern , logger } from '@sentry/utils' ;
103
114/**
125 * Options for Tracing integration
@@ -85,13 +78,6 @@ export class Tracing implements Integration {
8578 */
8679 public static id : string = 'Tracing' ;
8780
88- /**
89- * If we have an xhr we need to store the url in the instance.
90- *
91- */
92- // @ts -ignore
93- private _xhrUrl ?: string ;
94-
9581 /**
9682 * Is Tracing enabled, this will be determined once per pageload.
9783 */
@@ -109,7 +95,7 @@ export class Tracing implements Integration {
10995
11096 private static _currentIndex : number = 0 ;
11197
112- private static readonly _activities : { [ key : number ] : Activity } = { } ;
98+ public static readonly _activities : { [ key : number ] : Activity } = { } ;
11399
114100 private static _debounce : number = 0 ;
115101
@@ -124,7 +110,10 @@ export class Tracing implements Integration {
124110 idleTimeout : 500 ,
125111 shouldCreateSpanForRequest ( url : string ) : boolean {
126112 const origins = ( _options && _options . tracingOrigins ) || defaultTracingOrigins ;
127- return origins . some ( ( origin : string | RegExp ) => isMatchingPattern ( url , origin ) ) ;
113+ return (
114+ origins . some ( ( origin : string | RegExp ) => isMatchingPattern ( url , origin ) ) &&
115+ ! isMatchingPattern ( url , 'sentry_key' )
116+ ) ;
128117 } ,
129118 startTransactionOnLocationChange : true ,
130119 traceFetch : true ,
@@ -160,15 +149,13 @@ export class Tracing implements Integration {
160149 callback : xhrCallback ,
161150 type : 'xhr' ,
162151 } ) ;
163- this . _traceXHR ( getCurrentHub ) ;
164152 }
165153 // tslint:disable-next-line: no-non-null-assertion
166154 if ( this . _options ! . traceFetch !== false ) {
167155 addInstrumentationHandler ( {
168156 callback : fetchCallback ,
169157 type : 'fetch' ,
170158 } ) ;
171- this . _traceFetch ( getCurrentHub ) ;
172159 }
173160
174161 // tslint:disable-next-line: no-non-null-assertion
@@ -188,120 +175,6 @@ export class Tracing implements Integration {
188175 }
189176 }
190177
191- /**
192- * JSDoc
193- */
194- private _traceXHR ( getCurrentHub : ( ) => Hub ) : void {
195- if ( ! ( 'XMLHttpRequest' in getGlobalObject < Window > ( ) ) ) {
196- return ;
197- }
198-
199- const xhrproto = XMLHttpRequest . prototype ;
200-
201- fill (
202- xhrproto ,
203- 'open' ,
204- originalOpen =>
205- function ( this : XMLHttpRequest , ...args : any [ ] ) : void {
206- // @ts -ignore
207- const self = getCurrentHub ( ) . getIntegration ( Tracing ) ;
208- if ( self ) {
209- self . _xhrUrl = args [ 1 ] as string ;
210- }
211- // tslint:disable-next-line: no-unsafe-any
212- return originalOpen . apply ( this , args ) ;
213- } ,
214- ) ;
215-
216- fill (
217- xhrproto ,
218- 'send' ,
219- originalSend =>
220- function ( this : XMLHttpRequest , ...args : any [ ] ) : void {
221- // @ts -ignore
222- const self = getCurrentHub ( ) . getIntegration ( Tracing ) ;
223- // tslint:disable-next-line: no-non-null-assertion
224- if ( self && self . _xhrUrl && self . _options ! . tracingOrigins ) {
225- const url = self . _xhrUrl ;
226- const headers = getCurrentHub ( ) . traceHeaders ( ) ;
227- // tslint:disable-next-line: prefer-for-of no-non-null-assertion
228- let isWhitelisted = self . _options ! . tracingOrigins . some ( ( origin : string | RegExp ) =>
229- isMatchingPattern ( url , origin ) ,
230- ) ;
231-
232- if ( isMatchingPattern ( url , 'sentry_key' ) ) {
233- // If sentry_key is in the url, it's an internal store request to sentry
234- // we do not want to add the trace header to store requests
235- isWhitelisted = false ;
236- }
237-
238- if ( isWhitelisted && this . setRequestHeader ) {
239- Object . keys ( headers ) . forEach ( key => {
240- this . setRequestHeader ( key , headers [ key ] ) ;
241- } ) ;
242- }
243- }
244- // tslint:disable-next-line: no-unsafe-any
245- return originalSend . apply ( this , args ) ;
246- } ,
247- ) ;
248- }
249-
250- /**
251- * JSDoc
252- */
253- private _traceFetch ( getCurrentHub : ( ) => Hub ) : void {
254- if ( ! supportsNativeFetch ( ) ) {
255- return ;
256- }
257-
258- // tslint:disable: only-arrow-functions
259- fill ( getGlobalObject < Window > ( ) , 'fetch' , function ( originalFetch : ( ) => void ) : ( ) => void {
260- return function ( ...args : any [ ] ) : void {
261- // @ts -ignore
262- const hub = getCurrentHub ( ) ;
263- const self = hub . getIntegration ( Tracing ) ;
264- // tslint:disable-next-line: no-non-null-assertion
265- if ( self && self . _options ! . tracingOrigins ) {
266- const url = args [ 0 ] as string ;
267- const options = ( args [ 1 ] = ( args [ 1 ] as { [ key : string ] : any } ) || { } ) ;
268-
269- let isWhitelisted = false ;
270- // tslint:disable-next-line: no-non-null-assertion
271- self . _options ! . tracingOrigins . forEach ( ( whiteListUrl : string | RegExp ) => {
272- if ( ! isWhitelisted ) {
273- isWhitelisted = isMatchingPattern ( url , whiteListUrl ) ;
274- }
275- } ) ;
276-
277- if ( isMatchingPattern ( url , 'sentry_key' ) ) {
278- // If sentry_key is in the url, it's an internal store request to sentry
279- // we do not want to add the trace header to store requests
280- isWhitelisted = false ;
281- }
282-
283- if ( isWhitelisted ) {
284- if ( options . headers ) {
285- if ( Array . isArray ( options . headers ) ) {
286- options . headers = [ ...options . headers , ...Object . entries ( hub . traceHeaders ( ) ) ] ;
287- } else {
288- options . headers = {
289- ...options . headers ,
290- ...hub . traceHeaders ( ) ,
291- } ;
292- }
293- } else {
294- options . headers = hub . traceHeaders ( ) ;
295- }
296- }
297- }
298- // tslint:disable-next-line: no-unsafe-any
299- return originalFetch . apply ( getGlobalObject < Window > ( ) , args ) ;
300- } ;
301- } ) ;
302- // tslint:enable: only-arrow-functions
303- }
304-
305178 /**
306179 * Is tracing enabled
307180 */
@@ -508,6 +381,15 @@ function xhrCallback(handlerData: { [key: string]: any }): void {
508381 description : `${ xhr . method } ${ xhr . url } ` ,
509382 op : 'http' ,
510383 } ) ;
384+
385+ // Adding the trace header to the span
386+ const activity = Tracing . _activities [ handlerData . xhr . __sentry_xhr_activity_id__ ] ;
387+ if ( activity ) {
388+ const span = activity . span ;
389+ if ( span && handlerData . xhr . setRequestHeader ) {
390+ handlerData . xhr . setRequestHeader ( 'sentry-trace' , span . toTraceparent ( ) ) ;
391+ }
392+ }
511393 // tslint:enable: no-unsafe-any
512394}
513395
@@ -520,22 +402,42 @@ function fetchCallback(handlerData: { [key: string]: any }): void {
520402 return ;
521403 }
522404
523- if ( handlerData . endTimestamp && handlerData . __activity ) {
524- Tracing . popActivity ( handlerData . __activity , handlerData . fetchData ) ;
405+ if ( ! Tracing . options . shouldCreateSpanForRequest ( handlerData . fetchData . url ) ) {
406+ return ;
407+ }
408+
409+ if ( handlerData . endTimestamp && handlerData . fetchData . __activity ) {
410+ Tracing . popActivity ( handlerData . fetchData . __activity , handlerData . fetchData ) ;
525411 } else {
526- handlerData . __activity = Tracing . pushActivity ( 'fetch' , {
412+ handlerData . fetchData . __activity = Tracing . pushActivity ( 'fetch' , {
527413 data : {
528414 ...handlerData . fetchData ,
529415 type : 'fetch' ,
530416 } ,
531417 description : `${ handlerData . fetchData . method } ${ handlerData . fetchData . url } ` ,
532418 op : 'http' ,
533419 } ) ;
534- }
535420
536- // if (handlerData.error) {
537- // } else {
538- // }
421+ const activity = Tracing . _activities [ handlerData . fetchData . __activity ] ;
422+ if ( activity ) {
423+ const span = activity . span ;
424+ if ( span ) {
425+ const options = ( handlerData . args [ 1 ] = ( handlerData . args [ 1 ] as { [ key : string ] : any } ) || { } ) ;
426+ if ( options . headers ) {
427+ if ( Array . isArray ( options . headers ) ) {
428+ options . headers = [ ...options . headers , { 'sentry-trace' : span . toTraceparent ( ) } ] ;
429+ } else {
430+ options . headers = {
431+ ...options . headers ,
432+ 'sentry-trace' : span . toTraceparent ( ) ,
433+ } ;
434+ }
435+ } else {
436+ options . headers = { 'sentry-trace' : span . toTraceparent ( ) } ;
437+ }
438+ }
439+ }
440+ }
539441 // tslint:enable: no-unsafe-any
540442}
541443
0 commit comments