@@ -311,8 +311,7 @@ export function addPerformanceEntries(span: Span, options: AddPerformanceEntries
311
311
312
312
const { op, start_timestamp : transactionStartTime } = spanToJSON ( span ) ;
313
313
314
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
315
- performanceEntries . slice ( _performanceCursor ) . forEach ( ( entry : Record < string , any > ) => {
314
+ performanceEntries . slice ( _performanceCursor ) . forEach ( entry => {
316
315
const startTime = msToSec ( entry . startTime ) ;
317
316
const duration = msToSec (
318
317
// Inexplicably, Chrome sometimes emits a negative duration. We need to work around this.
@@ -328,7 +327,7 @@ export function addPerformanceEntries(span: Span, options: AddPerformanceEntries
328
327
329
328
switch ( entry . entryType ) {
330
329
case 'navigation' : {
331
- _addNavigationSpans ( span , entry , timeOrigin ) ;
330
+ _addNavigationSpans ( span , entry as PerformanceNavigationTiming , timeOrigin ) ;
332
331
break ;
333
332
}
334
333
case 'mark' :
@@ -350,7 +349,7 @@ export function addPerformanceEntries(span: Span, options: AddPerformanceEntries
350
349
break ;
351
350
}
352
351
case 'resource' : {
353
- _addResourceSpans ( span , entry , entry . name as string , startTime , duration , timeOrigin ) ;
352
+ _addResourceSpans ( span , entry as PerformanceResourceTiming , entry . name , startTime , duration , timeOrigin ) ;
354
353
break ;
355
354
}
356
355
default :
@@ -414,8 +413,7 @@ export function addPerformanceEntries(span: Span, options: AddPerformanceEntries
414
413
/** Create measure related spans */
415
414
export function _addMeasureSpans (
416
415
span : Span ,
417
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
418
- entry : Record < string , any > ,
416
+ entry : PerformanceEntry ,
419
417
startTime : number ,
420
418
duration : number ,
421
419
timeOrigin : number ,
@@ -454,30 +452,37 @@ export function _addMeasureSpans(
454
452
}
455
453
456
454
/** Instrument navigation entries */
457
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
458
- function _addNavigationSpans ( span : Span , entry : Record < string , any > , timeOrigin : number ) : void {
459
- [ 'unloadEvent' , 'redirect' , 'domContentLoadedEvent' , 'loadEvent' , 'connect' ] . forEach ( event => {
455
+ function _addNavigationSpans ( span : Span , entry : PerformanceNavigationTiming , timeOrigin : number ) : void {
456
+ ( [ 'unloadEvent' , 'redirect' , 'domContentLoadedEvent' , 'loadEvent' , 'connect' ] as const ) . forEach ( event => {
460
457
_addPerformanceNavigationTiming ( span , entry , event , timeOrigin ) ;
461
458
} ) ;
462
- _addPerformanceNavigationTiming ( span , entry , 'secureConnection' , timeOrigin , 'TLS/SSL' , 'connectEnd' ) ;
463
- _addPerformanceNavigationTiming ( span , entry , 'fetch' , timeOrigin , 'cache' , 'domainLookupStart' ) ;
459
+ _addPerformanceNavigationTiming ( span , entry , 'secureConnection' , timeOrigin , 'TLS/SSL' ) ;
460
+ _addPerformanceNavigationTiming ( span , entry , 'fetch' , timeOrigin , 'cache' ) ;
464
461
_addPerformanceNavigationTiming ( span , entry , 'domainLookup' , timeOrigin , 'DNS' ) ;
462
+
465
463
_addRequest ( span , entry , timeOrigin ) ;
466
464
}
467
465
468
466
/** Create performance navigation related spans */
469
467
function _addPerformanceNavigationTiming (
470
468
span : Span ,
471
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
472
- entry : Record < string , any > ,
473
- event : string ,
469
+ entry : PerformanceNavigationTiming ,
470
+ event :
471
+ | 'secureConnection'
472
+ | 'fetch'
473
+ | 'domainLookup'
474
+ | 'unloadEvent'
475
+ | 'redirect'
476
+ | 'connect'
477
+ | 'domContentLoadedEvent'
478
+ | 'loadEvent' ,
474
479
timeOrigin : number ,
475
480
name ?: string ,
476
- eventEnd ?: string ,
477
481
) : void {
478
- const end = eventEnd ? ( entry [ eventEnd ] as number | undefined ) : ( entry [ `${ event } End` ] as number | undefined ) ;
479
- const start = entry [ `${ event } Start` ] as number | undefined ;
480
- if ( ! start || ! end ) {
482
+ const eventEnd = getEndPropertyNameForNavigationTiming ( event ) ;
483
+ const end = entry [ eventEnd ] ;
484
+ const start = entry [ `${ event } Start` ] ;
485
+ if ( typeof start !== 'number' || typeof end !== 'number' ) {
481
486
return ;
482
487
}
483
488
startAndEndSpan ( span , timeOrigin + msToSec ( start ) , timeOrigin + msToSec ( end ) , {
@@ -489,9 +494,28 @@ function _addPerformanceNavigationTiming(
489
494
} ) ;
490
495
}
491
496
497
+ function getEndPropertyNameForNavigationTiming (
498
+ event :
499
+ | 'secureConnection'
500
+ | 'fetch'
501
+ | 'domainLookup'
502
+ | 'unloadEvent'
503
+ | 'redirect'
504
+ | 'connect'
505
+ | 'domContentLoadedEvent'
506
+ | 'loadEvent' ,
507
+ ) : keyof PerformanceNavigationTiming {
508
+ if ( event === 'secureConnection' ) {
509
+ return 'connectEnd' ;
510
+ }
511
+ if ( event === 'fetch' ) {
512
+ return 'domainLookupStart' ;
513
+ }
514
+ return `${ event } End` ;
515
+ }
516
+
492
517
/** Create request and response related spans */
493
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
494
- function _addRequest ( span : Span , entry : Record < string , any > , timeOrigin : number ) : void {
518
+ function _addRequest ( span : Span , entry : PerformanceNavigationTiming , timeOrigin : number ) : void {
495
519
const requestStartTimestamp = timeOrigin + msToSec ( entry . requestStart as number ) ;
496
520
const responseEndTimestamp = timeOrigin + msToSec ( entry . responseEnd as number ) ;
497
521
const responseStartTimestamp = timeOrigin + msToSec ( entry . responseStart as number ) ;
@@ -518,19 +542,10 @@ function _addRequest(span: Span, entry: Record<string, any>, timeOrigin: number)
518
542
}
519
543
}
520
544
521
- export interface ResourceEntry extends Record < string , unknown > {
522
- initiatorType ?: string ;
523
- transferSize ?: number ;
524
- encodedBodySize ?: number ;
525
- decodedBodySize ?: number ;
526
- renderBlockingStatus ?: string ;
527
- deliveryType ?: string ;
528
- }
529
-
530
545
/** Create resource-related spans */
531
- export function _addResourceSpans (
546
+ function _addResourceSpans (
532
547
span : Span ,
533
- entry : ResourceEntry ,
548
+ entry : PerformanceResourceTiming ,
534
549
resourceUrl : string ,
535
550
startTime : number ,
536
551
duration : number ,
@@ -551,13 +566,19 @@ export function _addResourceSpans(
551
566
setResourceEntrySizeData ( attributes , entry , 'encodedBodySize' , 'http.response_content_length' ) ;
552
567
setResourceEntrySizeData ( attributes , entry , 'decodedBodySize' , 'http.decoded_response_content_length' ) ;
553
568
554
- if ( entry . deliveryType != null ) {
555
- attributes [ 'http.response_delivery_type' ] = entry . deliveryType ;
569
+ // `deliveryType` is experimental and does not exist everywhere
570
+ const deliveryType = ( entry as { deliveryType ?: 'cache' | 'navigational-prefetch' | '' } ) . deliveryType ;
571
+ if ( deliveryType != null ) {
572
+ attributes [ 'http.response_delivery_type' ] = deliveryType ;
556
573
}
557
574
558
- if ( 'renderBlockingStatus' in entry ) {
559
- attributes [ 'resource.render_blocking_status' ] = entry . renderBlockingStatus ;
575
+ // Types do not reflect this property yet
576
+ const renderBlockingStatus = ( entry as { renderBlockingStatus ?: 'render-blocking' | 'non-render-blocking' } )
577
+ . renderBlockingStatus ;
578
+ if ( renderBlockingStatus ) {
579
+ attributes [ 'resource.render_blocking_status' ] = renderBlockingStatus ;
560
580
}
581
+
561
582
if ( parsedUrl . protocol ) {
562
583
attributes [ 'url.scheme' ] = parsedUrl . protocol . split ( ':' ) . pop ( ) ; // the protocol returned by parseUrl includes a :, but OTEL spec does not, so we remove it.
563
584
}
@@ -655,8 +676,8 @@ function _setWebVitalAttributes(span: Span): void {
655
676
656
677
function setResourceEntrySizeData (
657
678
attributes : SpanAttributes ,
658
- entry : ResourceEntry ,
659
- key : keyof Pick < ResourceEntry , 'transferSize' | 'encodedBodySize' | 'decodedBodySize' > ,
679
+ entry : PerformanceResourceTiming ,
680
+ key : keyof Pick < PerformanceResourceTiming , 'transferSize' | 'encodedBodySize' | 'decodedBodySize' > ,
660
681
dataKey : 'http.response_transfer_size' | 'http.response_content_length' | 'http.decoded_response_content_length' ,
661
682
) : void {
662
683
const entryVal = entry [ key ] ;
0 commit comments