diff --git a/packages/core/src/domain/telemetry/telemetryEvent.types.ts b/packages/core/src/domain/telemetry/telemetryEvent.types.ts index 29746ddab2..2ba79a50ea 100644 --- a/packages/core/src/domain/telemetry/telemetryEvent.types.ts +++ b/packages/core/src/domain/telemetry/telemetryEvent.types.ts @@ -392,9 +392,9 @@ export type TelemetryConfigurationEvent = CommonTelemetryProperties & { */ is_main_process?: boolean /** - * The list of events that include feature flags collection + * The list of events that include feature flags collection. The tracking is always enabled for views and errors. */ - collect_feature_flags_on?: ('view' | 'error' | 'vital')[] + track_feature_flags_for_events?: ('vital' | 'resource' | 'action' | 'long_task')[] /** * Whether the anonymous users are tracked */ @@ -433,6 +433,7 @@ export type TelemetryCommonFeaturesUsage = | AddError | SetGlobalContext | SetUser + | SetAccount | AddFeatureFlagEvaluation /** * Schema of browser specific features usage @@ -623,6 +624,13 @@ export interface SetUser { feature: 'set-user' [k: string]: unknown } +export interface SetAccount { + /** + * setAccount, setAccountProperty APIs + */ + feature: 'set-account' + [k: string]: unknown +} export interface AddFeatureFlagEvaluation { /** * addFeatureFlagEvaluation API diff --git a/packages/rum-core/src/domain/view/viewCollection.spec.ts b/packages/rum-core/src/domain/view/viewCollection.spec.ts index ebb2128726..6acb49e3b7 100644 --- a/packages/rum-core/src/domain/view/viewCollection.spec.ts +++ b/packages/rum-core/src/domain/view/viewCollection.spec.ts @@ -167,6 +167,30 @@ describe('viewCollection', () => { long_task: { count: 10, }, + performance: { + cls: { + score: 1, + timestamp: (100 * 1e6) as ServerDuration, + target_selector: undefined, + }, + fcp: { + timestamp: (10 * 1e6) as ServerDuration, + }, + fid: { + duration: (12 * 1e6) as ServerDuration, + timestamp: (10 * 1e6) as ServerDuration, + target_selector: undefined, + }, + inp: { + duration: (10 * 1e6) as ServerDuration, + timestamp: (100 * 1e6) as ServerDuration, + target_selector: undefined, + }, + lcp: { + timestamp: (10 * 1e6) as ServerDuration, + target_selector: undefined, + }, + }, resource: { count: 10, }, diff --git a/packages/rum-core/src/domain/view/viewCollection.ts b/packages/rum-core/src/domain/view/viewCollection.ts index aeecb300a1..53eb6987b4 100644 --- a/packages/rum-core/src/domain/view/viewCollection.ts +++ b/packages/rum-core/src/domain/view/viewCollection.ts @@ -2,7 +2,7 @@ import type { Duration, ServerDuration, Observable } from '@datadog/browser-core import { isEmptyObject, mapValues, toServerDuration } from '@datadog/browser-core' import { discardNegativeDuration } from '../discardNegativeDuration' import type { RecorderApi } from '../../boot/rumPublicApi' -import type { RawRumViewEvent } from '../../rawRumEvent.types' +import type { RawRumViewEvent, ViewPerformanceData } from '../../rawRumEvent.types' import { RumEventType } from '../../rawRumEvent.types' import type { LifeCycle, RawRumEventCollectedData } from '../lifeCycle' import { LifeCycleEventType } from '../lifeCycle' @@ -12,6 +12,8 @@ import type { FeatureFlagContexts } from '../contexts/featureFlagContext' import type { PageStateHistory } from '../contexts/pageStateHistory' import type { ViewEvent, ViewOptions } from './trackViews' import { trackViews } from './trackViews' +import type { CommonViewMetrics } from './viewMetrics/trackCommonViewMetrics' +import type { InitialViewMetrics } from './viewMetrics/trackInitialViewMetrics' export function startViewCollection( lifeCycle: LifeCycle, @@ -98,6 +100,7 @@ function processViewUpdate( long_task: { count: view.eventCounts.longTaskCount, }, + performance: computeViewPerformanceData(view.commonViewMetrics, view.initialViewMetrics), resource: { count: view.eventCounts.resourceCount, }, @@ -137,3 +140,31 @@ function processViewUpdate( }, } } + +function computeViewPerformanceData( + { cumulativeLayoutShift, interactionToNextPaint }: CommonViewMetrics, + { firstContentfulPaint, firstInput, largestContentfulPaint }: InitialViewMetrics +): ViewPerformanceData { + return { + cls: cumulativeLayoutShift && { + score: cumulativeLayoutShift.value, + timestamp: toServerDuration(cumulativeLayoutShift.time), + target_selector: cumulativeLayoutShift.targetSelector, + }, + fcp: firstContentfulPaint && { timestamp: toServerDuration(firstContentfulPaint) }, + fid: firstInput && { + duration: toServerDuration(firstInput.delay), + timestamp: toServerDuration(firstInput.time), + target_selector: firstInput.targetSelector, + }, + inp: interactionToNextPaint && { + duration: toServerDuration(interactionToNextPaint.value), + timestamp: toServerDuration(interactionToNextPaint.time), + target_selector: interactionToNextPaint.targetSelector, + }, + lcp: largestContentfulPaint && { + timestamp: toServerDuration(largestContentfulPaint.value), + target_selector: largestContentfulPaint.targetSelector, + }, + } +} diff --git a/packages/rum-core/src/rawRumEvent.types.ts b/packages/rum-core/src/rawRumEvent.types.ts index 0993ab552e..bfc2717d19 100644 --- a/packages/rum-core/src/rawRumEvent.types.ts +++ b/packages/rum-core/src/rawRumEvent.types.ts @@ -123,6 +123,7 @@ export interface RawRumViewEvent { long_task: Count resource: Count frustration: Count + performance?: ViewPerformanceData } session: { has_replay: true | undefined @@ -152,6 +153,31 @@ interface ViewDisplay { } } +export interface ViewPerformanceData { + cls?: { + score: number + timestamp?: ServerDuration + target_selector?: string + } + fcp?: { + timestamp: number + } + fid?: { + duration: ServerDuration + timestamp: ServerDuration + target_selector?: string + } + inp?: { + duration: ServerDuration + timestamp?: ServerDuration + target_selector?: string + } + lcp?: { + timestamp: ServerDuration + target_selector?: string + } +} + export type PageStateServerEntry = { state: PageState; start: ServerDuration } export const enum ViewLoadingType { diff --git a/packages/rum-core/src/rumEvent.types.ts b/packages/rum-core/src/rumEvent.types.ts index fc49e472a5..aadff45b1f 100644 --- a/packages/rum-core/src/rumEvent.types.ts +++ b/packages/rum-core/src/rumEvent.types.ts @@ -1057,6 +1057,10 @@ export type RumViewEvent = CommonProperties & * The JavaScript refresh rate for React Native */ js_refresh_rate?: RumPerfMetric + /** + * Performance data. (Web Vitals, etc.) + */ + performance?: ViewPerformanceData [k: string]: unknown } /** @@ -1169,10 +1173,6 @@ export type RumViewEvent = CommonProperties & } [k: string]: unknown } - /** - * Performance data. (Web Vitals, etc.) - */ - performance?: ViewPerformanceData [k: string]: unknown } /** @@ -1343,6 +1343,20 @@ export interface CommonProperties { readonly anonymous_id?: string [k: string]: unknown } + /** + * Account properties + */ + readonly account?: { + /** + * Identifier of the account + */ + readonly id: string + /** + * Name of the account + */ + readonly name?: string + [k: string]: unknown + } /** * Device connectivity properties */ @@ -1630,6 +1644,14 @@ export interface ViewPerformanceData { * CSS selector path of the first element (in document order) of the largest layout shift contributing to CLS */ readonly target_selector?: string + /** + * Bounding client rect of the element before the layout shift + */ + previous_rect?: RumRect + /** + * Bounding client rect of the element after the layout shift + */ + current_rect?: RumRect [k: string]: unknown } /** @@ -1694,3 +1716,25 @@ export interface ViewPerformanceData { } [k: string]: unknown } +/** + * Schema for DOMRect-like rectangles describing an element's bounding client rect + */ +export interface RumRect { + /** + * The x coordinate of the element's origin + */ + readonly x: number + /** + * The y coordinate of the element's origin + */ + readonly y: number + /** + * The element's width + */ + readonly width: number + /** + * The element's height + */ + readonly height: number + [k: string]: unknown +} diff --git a/rum-events-format b/rum-events-format index adcc82d93c..a48cdd6c5d 160000 --- a/rum-events-format +++ b/rum-events-format @@ -1 +1 @@ -Subproject commit adcc82d93c4ff75d5843014fa60afcc5f5b3a5e2 +Subproject commit a48cdd6c5dac83b144519fa9d29615ea87d36905