diff --git a/packages/browser/src/profiling/utils.ts b/packages/browser/src/profiling/utils.ts index 4a9a9af1d658..e720a2152f9f 100644 --- a/packages/browser/src/profiling/utils.ts +++ b/packages/browser/src/profiling/utils.ts @@ -3,7 +3,7 @@ import { DEFAULT_ENVIRONMENT, getCurrentHub } from '@sentry/core'; import type { DebugImage, Envelope, Event, StackFrame, StackParser } from '@sentry/types'; import type { Profile, ThreadCpuProfile } from '@sentry/types/src/profiling'; -import { forEachEnvelopeItem, GLOBAL_OBJ, logger, uuid4 } from '@sentry/utils'; +import { browserPerformanceTimeOrigin, forEachEnvelopeItem, GLOBAL_OBJ, logger, uuid4 } from '@sentry/utils'; import { WINDOW } from '../helpers'; import type { JSSelfProfile, JSSelfProfileStack } from './jsSelfProfiling'; @@ -213,6 +213,13 @@ export function convertJSSelfProfileToSampledFormat(input: JSSelfProfile): Profi // We assert samples.length > 0 above and timestamp should always be present const start = input.samples[0].timestamp; + // The JS SDK might change it's time origin based on some heuristic (see See packages/utils/src/time.ts) + // when that happens, we need to ensure we are correcting the profile timings so the two timelines stay in sync. + // Since JS self profiling time origin is always initialized to performance.timeOrigin, we need to adjust for + // the drift between the SDK selected value and our profile time origin. + const origin = + typeof performance.timeOrigin === 'number' ? performance.timeOrigin : browserPerformanceTimeOrigin || 0; + const adjustForOriginChange = origin - (browserPerformanceTimeOrigin || origin); for (let i = 0; i < input.samples.length; i++) { const jsSample = input.samples[i]; @@ -227,7 +234,7 @@ export function convertJSSelfProfileToSampledFormat(input: JSSelfProfile): Profi profile['samples'][i] = { // convert ms timestamp to ns - elapsed_since_start_ns: ((jsSample.timestamp - start) * MS_TO_NS).toFixed(0), + elapsed_since_start_ns: ((jsSample.timestamp + adjustForOriginChange - start) * MS_TO_NS).toFixed(0), stack_id: EMPTY_STACK_ID, thread_id: THREAD_ID_STRING, }; @@ -260,7 +267,7 @@ export function convertJSSelfProfileToSampledFormat(input: JSSelfProfile): Profi const sample: Profile['profile']['samples'][0] = { // convert ms timestamp to ns - elapsed_since_start_ns: ((jsSample.timestamp - start) * MS_TO_NS).toFixed(0), + elapsed_since_start_ns: ((jsSample.timestamp + adjustForOriginChange - start) * MS_TO_NS).toFixed(0), stack_id: STACK_ID, thread_id: THREAD_ID_STRING, };