Skip to content

Commit 2e08107

Browse files
bdibonclaude
andcommitted
✨ Support { includeDefaults: true } in trackResourceHeaders
Allow including the default tracked resource headers within a custom trackResourceHeaders array via a `{ includeDefaults: true }` entry, removing the need to spread DEFAULT_TRACKED_RESOURCE_HEADERS manually. Deprecate the DEFAULT_TRACKED_RESOURCE_HEADERS field on the DD_RUM public API in favor of the new sentinel (kept to avoid a breaking change). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 8af9fbf commit 2e08107

3 files changed

Lines changed: 33 additions & 6 deletions

File tree

packages/browser-rum-core/src/boot/rumPublicApi.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,9 @@ export interface RumPublicApi extends PublicApi {
586586
failFeatureOperation: (name: string, failureReason: FailureReason, options?: FeatureOperationOptions) => void
587587

588588
/**
589-
* List of default headers used by the {@link RumInitConfiguration.trackResourceHeaders | trackResourceHeaders} option. See configuration example for extending them.
589+
* List of default headers used by the {@link RumInitConfiguration.trackResourceHeaders | trackResourceHeaders} option.
590+
*
591+
* @deprecated Use `{ includeDefaults: true }` as an entry in the `trackResourceHeaders` array instead.
590592
*/
591593
DEFAULT_TRACKED_RESOURCE_HEADERS: typeof DEFAULT_TRACKED_RESOURCE_HEADERS
592594
}

packages/browser-rum-core/src/domain/configuration/configuration.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,24 @@ describe('validateAndBuildRumConfiguration', () => {
434434
expect(result).toEqual(DEFAULT_TRACKED_RESOURCE_HEADERS.map((name) => ({ name })))
435435
})
436436

437+
it('expands { includeDefaults: true } to the default headers', () => {
438+
const result = validateAndBuildRumConfiguration({
439+
...DEFAULT_INIT_CONFIGURATION,
440+
trackResourceHeaders: [{ includeDefaults: true }],
441+
})!.trackResourceHeaders
442+
443+
expect(result).toEqual(DEFAULT_TRACKED_RESOURCE_HEADERS.map((name) => ({ name })))
444+
})
445+
446+
it('combines { includeDefaults: true } with custom matchers in array order', () => {
447+
const result = validateAndBuildRumConfiguration({
448+
...DEFAULT_INIT_CONFIGURATION,
449+
trackResourceHeaders: [{ includeDefaults: true }, { name: 'x-custom' }],
450+
})!.trackResourceHeaders
451+
452+
expect(result).toEqual([...DEFAULT_TRACKED_RESOURCE_HEADERS.map((name) => ({ name })), { name: 'x-custom' }])
453+
})
454+
437455
it('accepts a MatchHeader with only name', () => {
438456
const result = validateAndBuildRumConfiguration({
439457
...DEFAULT_INIT_CONFIGURATION,

packages/browser-rum-core/src/domain/configuration/configuration.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ export interface RumInitConfiguration extends InitConfiguration {
284284
* (`url`), value extraction (`extractor`), and `location`. By default, both request and
285285
* response headers are captured; set `location` to `'request'` or `'response'` to restrict
286286
* to one.
287+
* - `{ includeDefaults: true }` (as an array entry): expands to {@link DEFAULT_TRACKED_RESOURCE_HEADERS}
288+
* in place, so the defaults can be combined with custom matchers without listing them manually.
287289
*
288290
* Headers whose names match a built-in sensitive-data pattern are always dropped, regardless
289291
* of the configured matchers. The pattern blocks headers whose names contain: `token`, `cookie`,
@@ -294,18 +296,15 @@ export interface RumInitConfiguration extends InitConfiguration {
294296
* @defaultValue false (disabled)
295297
* @example
296298
* // Collect default headers plus custom ones for all URLs
297-
* trackResourceHeaders: [
298-
* ...DEFAULT_TRACKED_RESOURCE_HEADERS.map((h) => ({ name: h })),
299-
* { name: 'x-request-id' },
300-
* ]
299+
* trackResourceHeaders: [{ includeDefaults: true }, { name: 'x-request-id' }]
301300
* @example
302301
* // URL-scoped rule: capture specific response headers only for calls to /api
303302
* trackResourceHeaders: [{ url: /\/api\//, name: 'cache-control', location: 'response' }]
304303
* @example
305304
* // Extract a partial value from a header
306305
* trackResourceHeaders: [{ url: /\/api\//, name: 'server-timing', extractor: /dur=(\d+)/, location: 'response' }]
307306
*/
308-
trackResourceHeaders?: boolean | MatchHeader[] | undefined
307+
trackResourceHeaders?: boolean | Array<MatchHeader | { includeDefaults: true }> | undefined
309308

310309
/**
311310
* Enables collection of long task events.
@@ -576,6 +575,10 @@ function validateAndBuildGraphQlOptions(initConfiguration: RumInitConfiguration)
576575

577576
const VALID_HEADER_LOCATIONS = ['request', 'response', 'any']
578577

578+
function shouldIncludeDefaultHeaders(item: MatchHeader | { includeDefaults: true }) {
579+
return isIndexableObject(item) && item.includeDefaults === true
580+
}
581+
579582
function validateAndBuildTrackResourceHeaders(initConfiguration: RumInitConfiguration): MatchHeader[] {
580583
const option = initConfiguration.trackResourceHeaders
581584

@@ -600,6 +603,10 @@ function validateAndBuildTrackResourceHeaders(initConfiguration: RumInitConfigur
600603
const result: MatchHeader[] = []
601604

602605
option.forEach((item, index) => {
606+
if (shouldIncludeDefaultHeaders(item)) {
607+
DEFAULT_TRACKED_RESOURCE_HEADERS.forEach((name) => result.push({ name }))
608+
return
609+
}
603610
if (!isIndexableObject(item) || !isMatchOption(item.name)) {
604611
display.warn(`trackResourceHeaders[${index}] should be a MatchHeader object with a 'name' property`)
605612
return

0 commit comments

Comments
 (0)