diff --git a/packages/rum-core/src/boot/startRum.ts b/packages/rum-core/src/boot/startRum.ts index a05027882b..238f63f732 100644 --- a/packages/rum-core/src/boot/startRum.ts +++ b/packages/rum-core/src/boot/startRum.ts @@ -70,7 +70,7 @@ export function startRum( ) startLongTaskCollection(lifeCycle, session) - startResourceCollection(lifeCycle) + startResourceCollection(lifeCycle, configuration) const { addTiming, startView } = startViewCollection( lifeCycle, configuration, diff --git a/packages/rum-core/src/domain/rumEventsCollection/resource/resourceCollection.spec.ts b/packages/rum-core/src/domain/rumEventsCollection/resource/resourceCollection.spec.ts index c8e7729804..c3596475a4 100644 --- a/packages/rum-core/src/domain/rumEventsCollection/resource/resourceCollection.spec.ts +++ b/packages/rum-core/src/domain/rumEventsCollection/resource/resourceCollection.spec.ts @@ -8,6 +8,7 @@ import { RumEventType } from '../../../rawRumEvent.types' import { LifeCycleEventType } from '../../lifeCycle' import type { RequestCompleteEvent } from '../../requestCollection' import { TraceIdentifier } from '../../tracing/tracer' +import { validateAndBuildRumConfiguration } from '../../configuration' import { startResourceCollection } from './resourceCollection' describe('resourceCollection', () => { @@ -15,7 +16,10 @@ describe('resourceCollection', () => { beforeEach(() => { setupBuilder = setup().beforeBuild(({ lifeCycle }) => { - startResourceCollection(lifeCycle) + startResourceCollection( + lifeCycle, + validateAndBuildRumConfiguration({ clientToken: 'xxx', applicationId: 'xxx' })! + ) }) }) @@ -186,6 +190,31 @@ describe('resourceCollection', () => { const traceInfo = (rawRumEvents[0].rawRumEvent as RawRumResourceEvent)._dd! expect(traceInfo).not.toBeDefined() }) + + it('should pull tracingSampleRate from config if present', () => { + setupBuilder = setup().beforeBuild(({ lifeCycle }) => { + startResourceCollection( + lifeCycle, + validateAndBuildRumConfiguration({ + clientToken: 'xxx', + applicationId: 'xxx', + tracingSampleRate: 60, + })! + ) + }) + + const { lifeCycle, rawRumEvents } = setupBuilder.build() + lifeCycle.notify( + LifeCycleEventType.REQUEST_COMPLETED, + createCompletedRequest({ + traceSampled: true, + spanId: new TraceIdentifier(), + traceId: new TraceIdentifier(), + }) + ) + const traceInfo = (rawRumEvents[0].rawRumEvent as RawRumResourceEvent)._dd! + expect(traceInfo.rule_psr).toEqual(0.6) + }) }) }) diff --git a/packages/rum-core/src/domain/rumEventsCollection/resource/resourceCollection.ts b/packages/rum-core/src/domain/rumEventsCollection/resource/resourceCollection.ts index d5a78dec5c..1c28ff7023 100644 --- a/packages/rum-core/src/domain/rumEventsCollection/resource/resourceCollection.ts +++ b/packages/rum-core/src/domain/rumEventsCollection/resource/resourceCollection.ts @@ -7,6 +7,7 @@ import { relativeToClocks, assign, } from '@datadog/browser-core' +import type { RumConfiguration } from '../../configuration' import type { RumPerformanceEntry, RumPerformanceResourceTiming } from '../../../browser/performanceCollection' import { supportPerformanceEntry } from '../../../browser/performanceCollection' import type { @@ -28,28 +29,31 @@ import { isRequestKind, } from './resourceUtils' -export function startResourceCollection(lifeCycle: LifeCycle) { +export function startResourceCollection(lifeCycle: LifeCycle, configuration: RumConfiguration) { lifeCycle.subscribe(LifeCycleEventType.REQUEST_COMPLETED, (request: RequestCompleteEvent) => { - lifeCycle.notify(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, processRequest(request)) + lifeCycle.notify(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, processRequest(request, configuration)) }) lifeCycle.subscribe(LifeCycleEventType.PERFORMANCE_ENTRIES_COLLECTED, (entries) => { for (const entry of entries) { if (entry.entryType === 'resource' && !isRequestKind(entry)) { - lifeCycle.notify(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, processResourceEntry(entry)) + lifeCycle.notify(LifeCycleEventType.RAW_RUM_EVENT_COLLECTED, processResourceEntry(entry, configuration)) } } }) } -function processRequest(request: RequestCompleteEvent): RawRumEventCollectedData { +function processRequest( + request: RequestCompleteEvent, + configuration: RumConfiguration +): RawRumEventCollectedData { const type = request.type === RequestType.XHR ? ResourceType.XHR : ResourceType.FETCH const matchingTiming = matchRequestTiming(request) const startClocks = matchingTiming ? relativeToClocks(matchingTiming.startTime) : request.startClocks const correspondingTimingOverrides = matchingTiming ? computePerformanceEntryMetrics(matchingTiming) : undefined - const tracingInfo = computeRequestTracingInfo(request) + const tracingInfo = computeRequestTracingInfo(request, configuration) const resourceEvent = combine( { @@ -81,10 +85,14 @@ function processRequest(request: RequestCompleteEvent): RawRumEventCollectedData } } -function processResourceEntry(entry: RumPerformanceResourceTiming): RawRumEventCollectedData { +function processResourceEntry( + entry: RumPerformanceResourceTiming, + configuration: RumConfiguration +): RawRumEventCollectedData { const type = computeResourceKind(entry) const entryMetrics = computePerformanceEntryMetrics(entry) - const tracingInfo = computeEntryTracingInfo(entry) + + const tracingInfo = computeEntryTracingInfo(entry, configuration) const startClocks = relativeToClocks(entry.startTime) const resourceEvent = combine( @@ -121,7 +129,7 @@ function computePerformanceEntryMetrics(timing: RumPerformanceResourceTiming) { } } -function computeRequestTracingInfo(request: RequestCompleteEvent) { +function computeRequestTracingInfo(request: RequestCompleteEvent, configuration: RumConfiguration) { const hasBeenTraced = request.traceSampled && request.traceId && request.spanId if (!hasBeenTraced) { return undefined @@ -130,12 +138,22 @@ function computeRequestTracingInfo(request: RequestCompleteEvent) { _dd: { span_id: request.spanId!.toDecimalString(), trace_id: request.traceId!.toDecimalString(), + rule_psr: getRulePsr(configuration), }, } } -function computeEntryTracingInfo(entry: RumPerformanceResourceTiming) { - return entry.traceId ? { _dd: { trace_id: entry.traceId } } : undefined +function computeEntryTracingInfo(entry: RumPerformanceResourceTiming, configuration: RumConfiguration) { + const hasBeenTraced = entry.traceId + if (!hasBeenTraced) { + return undefined + } + return { + _dd: { + trace_id: entry.traceId, + rule_psr: getRulePsr(configuration), + }, + } } function toPerformanceEntryRepresentation(entry: RumPerformanceEntry): PerformanceEntryRepresentation { @@ -144,3 +162,10 @@ function toPerformanceEntryRepresentation(entry: RumPerformanceEntry): Performan } return entry as PerformanceEntryRepresentation } + +/** + * @returns number between 0 and 1 which represents tracing sample rate + */ +function getRulePsr(configuration: RumConfiguration) { + return configuration.tracingSampleRate / 100 +} diff --git a/packages/rum-core/src/rawRumEvent.types.ts b/packages/rum-core/src/rawRumEvent.types.ts index 925e73f85c..23336ea8a6 100644 --- a/packages/rum-core/src/rawRumEvent.types.ts +++ b/packages/rum-core/src/rawRumEvent.types.ts @@ -38,6 +38,7 @@ export interface RawRumResourceEvent { _dd?: { trace_id?: string span_id?: string // not available for initial document tracing + rule_psr?: number } } diff --git a/packages/rum-core/src/rumEvent.types.ts b/packages/rum-core/src/rumEvent.types.ts index fdec22ce95..b0c9b37d13 100644 --- a/packages/rum-core/src/rumEvent.types.ts +++ b/packages/rum-core/src/rumEvent.types.ts @@ -48,7 +48,7 @@ export type RumActionEvent = CommonProperties & { /** * Action frustration types */ - readonly type: ('rage_click' | 'dead_click' | 'error_click')[] + readonly type: ('rage_click' | 'dead_click' | 'error_click' | 'rage_tap' | 'error_tap')[] [k: string]: unknown } /** @@ -473,6 +473,10 @@ export type RumResourceEvent = CommonProperties & * trace identifier in decimal format */ readonly trace_id?: string + /** + * tracing sample rate in decimal format + */ + readonly rule_psr?: number [k: string]: unknown } [k: string]: unknown @@ -729,7 +733,7 @@ export interface CommonProperties { /** * The source of this event */ - readonly source?: 'android' | 'ios' | 'browser' | 'flutter' | 'react-native' + readonly source?: 'android' | 'ios' | 'browser' | 'flutter' | 'react-native' | 'roku' /** * View properties */ diff --git a/rum-events-format b/rum-events-format index 7e817ae730..2c30ab56cb 160000 --- a/rum-events-format +++ b/rum-events-format @@ -1 +1 @@ -Subproject commit 7e817ae730589dfb26b43c065d650223ff3999a3 +Subproject commit 2c30ab56cb0e416f4948a992d5adaa344f2437b2