From f483c594992680113513cadf2bcc3e80e4c0a11f Mon Sep 17 00:00:00 2001 From: JonasBa Date: Thu, 20 Jul 2023 16:00:22 -0400 Subject: [PATCH 1/3] fix(profiling): align timelines --- packages/browser/src/profiling/utils.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/browser/src/profiling/utils.ts b/packages/browser/src/profiling/utils.ts index 4a9a9af1d658..d9d065ef49b1 100644 --- a/packages/browser/src/profiling/utils.ts +++ b/packages/browser/src/profiling/utils.ts @@ -5,6 +5,7 @@ import type { DebugImage, Envelope, Event, StackFrame, StackParser } from '@sent import type { Profile, ThreadCpuProfile } from '@sentry/types/src/profiling'; import { forEachEnvelopeItem, GLOBAL_OBJ, logger, uuid4 } from '@sentry/utils'; +import { browserPerformanceTimeOrigin } from '../../../utils/src/time'; import { WINDOW } from '../helpers'; import type { JSSelfProfile, JSSelfProfileStack } from './jsSelfProfiling'; @@ -213,6 +214,11 @@ 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 adjustForOriginChange = performance.timeOrigin - (browserPerformanceTimeOrigin || performance.timeOrigin); for (let i = 0; i < input.samples.length; i++) { const jsSample = input.samples[i]; @@ -227,7 +233,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 +266,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, }; From 56784649a9204c8e0aa7a8ed94ce69d9a34a2d75 Mon Sep 17 00:00:00 2001 From: JonasBa Date: Thu, 20 Jul 2023 16:01:37 -0400 Subject: [PATCH 2/3] fix(profiling): import from correct package --- packages/browser/src/profiling/utils.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/browser/src/profiling/utils.ts b/packages/browser/src/profiling/utils.ts index d9d065ef49b1..d14539f48b60 100644 --- a/packages/browser/src/profiling/utils.ts +++ b/packages/browser/src/profiling/utils.ts @@ -3,9 +3,8 @@ 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 { browserPerformanceTimeOrigin } from '../../../utils/src/time'; import { WINDOW } from '../helpers'; import type { JSSelfProfile, JSSelfProfileStack } from './jsSelfProfiling'; From 7b283ef02311681f5deada6cbb3568b73edd10ea Mon Sep 17 00:00:00 2001 From: JonasBa Date: Thu, 20 Jul 2023 16:25:36 -0400 Subject: [PATCH 3/3] fix(timeOrigin): handle undefined timeOrigin --- packages/browser/src/profiling/utils.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/browser/src/profiling/utils.ts b/packages/browser/src/profiling/utils.ts index d14539f48b60..e720a2152f9f 100644 --- a/packages/browser/src/profiling/utils.ts +++ b/packages/browser/src/profiling/utils.ts @@ -217,7 +217,9 @@ export function convertJSSelfProfileToSampledFormat(input: JSSelfProfile): Profi // 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 adjustForOriginChange = performance.timeOrigin - (browserPerformanceTimeOrigin || performance.timeOrigin); + 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];