Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ [RUMF-1306] Send the tracing sample rate in _dd.rule_psr for resources #1669

Merged
merged 22 commits into from
Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/rum-core/src/boot/startRum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function startRum(
)

startLongTaskCollection(lifeCycle, session)
startResourceCollection(lifeCycle)
startResourceCollection(lifeCycle, configuration)
const { addTiming, startView } = startViewCollection(
lifeCycle,
configuration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ 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', () => {
let setupBuilder: TestSetupBuilder

beforeEach(() => {
setupBuilder = setup().beforeBuild(({ lifeCycle }) => {
startResourceCollection(lifeCycle)
startResourceCollection(
lifeCycle,
validateAndBuildRumConfiguration({ clientToken: 'xxx', applicationId: 'xxx' })!
)
})
})

Expand Down Expand Up @@ -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)
})
})
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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<RawRumResourceEvent> {
function processRequest(
request: RequestCompleteEvent,
configuration: RumConfiguration
): RawRumEventCollectedData<RawRumResourceEvent> {
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(
{
Expand Down Expand Up @@ -81,10 +85,14 @@ function processRequest(request: RequestCompleteEvent): RawRumEventCollectedData
}
}

function processResourceEntry(entry: RumPerformanceResourceTiming): RawRumEventCollectedData<RawRumResourceEvent> {
function processResourceEntry(
entry: RumPerformanceResourceTiming,
configuration: RumConfiguration
): RawRumEventCollectedData<RawRumResourceEvent> {
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(
Expand Down Expand Up @@ -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
Expand All @@ -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 {
Expand All @@ -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
}
1 change: 1 addition & 0 deletions packages/rum-core/src/rawRumEvent.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export interface RawRumResourceEvent {
_dd?: {
trace_id?: string
span_id?: string // not available for initial document tracing
rule_psr?: number
liywjl marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
8 changes: 6 additions & 2 deletions packages/rum-core/src/rumEvent.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
/**
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
*/
Expand Down
2 changes: 1 addition & 1 deletion rum-events-format
Submodule rum-events-format updated 150 files