diff --git a/packages/tracing-internal/src/browser/browserTracingIntegration.ts b/packages/tracing-internal/src/browser/browserTracingIntegration.ts index 574dca4c5131..d17ceebe7a9a 100644 --- a/packages/tracing-internal/src/browser/browserTracingIntegration.ts +++ b/packages/tracing-internal/src/browser/browserTracingIntegration.ts @@ -114,6 +114,15 @@ export interface BrowserTracingOptions extends RequestInstrumentationOptions { */ enableInp: boolean; + /** + * Sample rate to determine interaction span sampling. + * interactionsSampleRate is applied on top of the global tracesSampleRate. + * ie a tracesSampleRate of 0.1 and interactionsSampleRate of 0.5 will result in a 0.05 sample rate for interactions. + * + * Default: 1 + */ + interactionsSampleRate: number; + /** * _metricOptions allows the user to send options to change how metrics are collected. * @@ -154,6 +163,7 @@ const DEFAULT_BROWSER_TRACING_OPTIONS: BrowserTracingOptions = { markBackgroundSpan: true, enableLongTask: true, enableInp: false, + interactionsSampleRate: 1, _experiments: {}, ...defaultRequestInstrumentationOptions, }; @@ -196,7 +206,7 @@ export const browserTracingIntegration = ((_options: Partial void { +export function startTrackingINP( + interactionIdtoRouteNameMapping: InteractionRouteNameMapping, + interactionsSampleRate: number, +): () => void { const performance = getBrowserPerformanceAPI(); if (performance && browserPerformanceTimeOrigin) { - const inpCallback = _trackINP(interactionIdtoRouteNameMapping); + const inpCallback = _trackINP(interactionIdtoRouteNameMapping, interactionsSampleRate); return (): void => { inpCallback(); @@ -247,7 +250,10 @@ const INP_ENTRY_MAP: Record = { }; /** Starts tracking the Interaction to Next Paint on the current page. */ -function _trackINP(interactionIdToRouteNameMapping: InteractionRouteNameMapping): () => void { +function _trackINP( + interactionIdToRouteNameMapping: InteractionRouteNameMapping, + interactionsSampleRate: number, +): () => void { return addInpInstrumentationHandler(({ metric }) => { if (metric.value === undefined) { return; @@ -293,7 +299,8 @@ function _trackINP(interactionIdToRouteNameMapping: InteractionRouteNameMapping) }); /** Check to see if the span should be sampled */ - const sampleRate = getSampleRate(parentContext, options); + const sampleRate = getSampleRate(parentContext, options, interactionsSampleRate); + if (!sampleRate) { return; } @@ -690,7 +697,11 @@ function _addTtfbRequestTimeToMeasurements(_measurements: Measurements): void { } /** Taken from @sentry/core sampling.ts */ -function getSampleRate(transactionContext: TransactionContext | undefined, options: ClientOptions): number | boolean { +function getSampleRate( + transactionContext: TransactionContext | undefined, + options: ClientOptions, + interactionsSampleRate: number, +): number | boolean { if (!hasTracingEnabled(options)) { return false; } @@ -715,8 +726,13 @@ function getSampleRate(transactionContext: TransactionContext | undefined, optio sampleRate = 1; } if (!isValidSampleRate(sampleRate)) { - DEBUG_BUILD && logger.warn('[Tracing] Discarding transaction because of invalid sample rate.'); + DEBUG_BUILD && logger.warn('[Tracing] Discarding interaction span because of invalid sample rate.'); return false; } - return sampleRate; + if (sampleRate === true) { + return interactionsSampleRate; + } else if (sampleRate === false) { + return 0; + } + return sampleRate * interactionsSampleRate; } diff --git a/packages/tracing-internal/test/browser/browsertracing.test.ts b/packages/tracing-internal/test/browser/browsertracing.test.ts index 777704785d55..1c61cdbce62f 100644 --- a/packages/tracing-internal/test/browser/browsertracing.test.ts +++ b/packages/tracing-internal/test/browser/browsertracing.test.ts @@ -92,6 +92,7 @@ conditionalTest({ min: 10 })('BrowserTracing', () => { expect(browserTracing.options).toEqual({ enableInp: false, + interactionsSampleRate: 1, enableLongTask: true, _experiments: {}, ...TRACING_DEFAULTS, @@ -112,6 +113,7 @@ conditionalTest({ min: 10 })('BrowserTracing', () => { expect(browserTracing.options).toEqual({ enableInp: false, + interactionsSampleRate: 1, enableLongTask: false, ...TRACING_DEFAULTS, markBackgroundTransactions: true, @@ -132,6 +134,7 @@ conditionalTest({ min: 10 })('BrowserTracing', () => { expect(browserTracing.options).toEqual({ enableInp: false, + interactionsSampleRate: 1, enableLongTask: false, _experiments: {}, ...TRACING_DEFAULTS,