diff --git a/packages/rum-core/src/browser/performanceObservable.ts b/packages/rum-core/src/browser/performanceObservable.ts index 7585d9697f..9c6d17e467 100644 --- a/packages/rum-core/src/browser/performanceObservable.ts +++ b/packages/rum-core/src/browser/performanceObservable.ts @@ -59,6 +59,7 @@ export interface RumPerformanceResourceTiming { decodedBodySize: number encodedBodySize: number transferSize: number + nextHopProtocol?: string renderBlockingStatus?: string traceId?: string toJSON(): Omit diff --git a/packages/rum-core/src/domain/resource/resourceCollection.spec.ts b/packages/rum-core/src/domain/resource/resourceCollection.spec.ts index 76316b3563..e36417cb59 100644 --- a/packages/rum-core/src/domain/resource/resourceCollection.spec.ts +++ b/packages/rum-core/src/domain/resource/resourceCollection.spec.ts @@ -79,6 +79,7 @@ describe('resourceCollection', () => { download: jasmine.any(Object), first_byte: jasmine.any(Object), status_code: 200, + protocol: 'HTTP/1.0', render_blocking_status: 'blocking', }, type: RumEventType.RESOURCE, @@ -116,6 +117,7 @@ describe('resourceCollection', () => { duration: (100 * 1e6) as ServerDuration, method: 'GET', status_code: 200, + protocol: undefined, type: ResourceType.XHR, url: 'https://resource.com/valid', }, @@ -229,6 +231,7 @@ describe('resourceCollection', () => { duration: (100 * 1e6) as ServerDuration, method: 'GET', status_code: 200, + protocol: undefined, type: ResourceType.FETCH, url: 'https://resource.com/valid', }, diff --git a/packages/rum-core/src/domain/resource/resourceCollection.ts b/packages/rum-core/src/domain/resource/resourceCollection.ts index cb5c2e171e..f3e7bb8a71 100644 --- a/packages/rum-core/src/domain/resource/resourceCollection.ts +++ b/packages/rum-core/src/domain/resource/resourceCollection.ts @@ -30,6 +30,7 @@ import { computeResourceEntryDuration, computeResourceEntryType, computeResourceEntrySize, + computeResourceEntryProtocol, isResourceEntryRequestType, isLongDataUrl, sanitizeDataUrl, @@ -104,6 +105,7 @@ function processRequest( duration, method: request.method, status_code: request.status, + protocol: matchingTiming && computeResourceEntryProtocol(matchingTiming), url: isLongDataUrl(request.url) ? sanitizeDataUrl(request.url) : request.url, }, type: RumEventType.RESOURCE as const, @@ -152,6 +154,7 @@ function processResourceEntry( type, url: entry.name, status_code: discardZeroStatus(entry.responseStatus), + protocol: computeResourceEntryProtocol(entry), }, type: RumEventType.RESOURCE as const, _dd: { diff --git a/packages/rum-core/src/domain/resource/resourceUtils.ts b/packages/rum-core/src/domain/resource/resourceUtils.ts index 0b9d5886cc..68571cf2e4 100644 --- a/packages/rum-core/src/domain/resource/resourceUtils.ts +++ b/packages/rum-core/src/domain/resource/resourceUtils.ts @@ -177,6 +177,15 @@ function formatTiming(origin: RelativeTime, start: RelativeTime, end: RelativeTi } } +/** + * The 'nextHopProtocol' is an empty string for cross-origin resources without CORS headers, + * meaning the protocol is unknown, and we shouldn't report it. + * https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/nextHopProtocol#cross-origin_resources + */ +export function computeResourceEntryProtocol(entry: RumPerformanceResourceTiming) { + return entry.nextHopProtocol === '' ? undefined : entry.nextHopProtocol +} + export function computeResourceEntrySize(entry: RumPerformanceResourceTiming) { // Make sure a request actually occurred if (entry.startTime < entry.responseStart) { diff --git a/packages/rum-core/src/rawRumEvent.types.ts b/packages/rum-core/src/rawRumEvent.types.ts index 29a57f3d95..15f545431c 100644 --- a/packages/rum-core/src/rawRumEvent.types.ts +++ b/packages/rum-core/src/rawRumEvent.types.ts @@ -48,6 +48,7 @@ export interface RawRumResourceEvent { ssl?: ResourceEntryDetailsElement first_byte?: ResourceEntryDetailsElement download?: ResourceEntryDetailsElement + protocol?: string } _dd: { trace_id?: string diff --git a/packages/rum-core/src/rumEvent.types.ts b/packages/rum-core/src/rumEvent.types.ts index c77a947b26..a927a5defa 100644 --- a/packages/rum-core/src/rumEvent.types.ts +++ b/packages/rum-core/src/rumEvent.types.ts @@ -702,6 +702,10 @@ export type RumResourceEvent = CommonProperties & readonly start: number [k: string]: unknown } + /** + * Network protocol used to fetch the resource (e.g., 'http/1.1', 'h2') + */ + readonly protocol?: string /** * The provider for this resource */ diff --git a/packages/rum-core/test/fixtures.ts b/packages/rum-core/test/fixtures.ts index 2b74b77f3d..346959ea49 100644 --- a/packages/rum-core/test/fixtures.ts +++ b/packages/rum-core/test/fixtures.ts @@ -259,6 +259,7 @@ export function createPerformanceEntry( secureConnectionStart: 200 as RelativeTime, startTime: 200 as RelativeTime, responseStatus: 200, + nextHopProtocol: 'HTTP/1.0', }, overrides ) as EntryTypeToReturnType[T] diff --git a/rum-events-format b/rum-events-format index ba50d0c05d..e1c6dde379 160000 --- a/rum-events-format +++ b/rum-events-format @@ -1 +1 @@ -Subproject commit ba50d0c05dcdd374bb962f40fc8f82db992da319 +Subproject commit e1c6dde3793714453b5b49f17790a24e9ff9b77b