Skip to content

Commit

Permalink
feat(apm): Update Span timing from absolute ref (#2479)
Browse files Browse the repository at this point in the history
Use performance.timeOrigin as the absolute reference to update Span
start and end timestamps.

Where performance.timeOrigin is not available, fallback to
performance.timing.navigationStart.
  • Loading branch information
rhcarvalho authored Mar 9, 2020
1 parent cda040f commit 76da9e7
Showing 1 changed file with 37 additions and 21 deletions.
58 changes: 37 additions & 21 deletions packages/apm/src/integrations/tracing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,19 @@ interface Activity {
const global = getGlobalObject<Window>();
const defaultTracingOrigins = ['localhost', /^\//];

if (global.performance) {
// Polyfill for performance.timeOrigin.
//
// While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin
// is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing.
// tslint:disable-next-line:strict-type-predicates
if (performance.timeOrigin === undefined) {
// @ts-ignore
// tslint:disable-next-line:deprecation
performance.timeOrigin = performance.timing.navigationStart;
}
}

/**
* Tracing Integration
*/
Expand Down Expand Up @@ -382,15 +395,11 @@ export class Tracing implements Integration {
// Gatekeeper if performance API not available
return;
}

logger.log('[Tracing] Adding & adjusting spans using Performance API');
let navigationOffset = 0;
if (
transactionSpan.op === 'navigation' &&
transactionSpan.data &&
typeof transactionSpan.data.offset === 'number'
) {
navigationOffset = transactionSpan.data.offset;
}

const timeOrigin = Tracing._msToSec(performance.timeOrigin);

// tslint:disable-next-line: completed-docs
function addSpan(span: SpanClass): void {
if (transactionSpan.spanRecorder) {
Expand All @@ -404,8 +413,8 @@ export class Tracing implements Integration {
description: event,
op: 'browser',
});
span.startTimestamp = parent.startTimestamp + Tracing._msToSec(entry[`${event}Start`]);
span.timestamp = parent.startTimestamp + Tracing._msToSec(entry[`${event}End`]);
span.startTimestamp = timeOrigin + Tracing._msToSec(entry[`${event}Start`]);
span.timestamp = timeOrigin + Tracing._msToSec(entry[`${event}End`]);
addSpan(span);
}

Expand All @@ -415,15 +424,15 @@ export class Tracing implements Integration {
description: 'request',
op: 'browser',
});
request.startTimestamp = parent.startTimestamp + Tracing._msToSec(entry.requestStart);
request.timestamp = parent.startTimestamp + Tracing._msToSec(entry.responseEnd);
request.startTimestamp = timeOrigin + Tracing._msToSec(entry.requestStart);
request.timestamp = timeOrigin + Tracing._msToSec(entry.responseEnd);
addSpan(request);
const response = parent.child({
description: 'response',
op: 'browser',
});
response.startTimestamp = parent.startTimestamp + Tracing._msToSec(entry.responseStart);
response.timestamp = parent.startTimestamp + Tracing._msToSec(entry.responseEnd);
response.startTimestamp = timeOrigin + Tracing._msToSec(entry.responseStart);
response.timestamp = timeOrigin + Tracing._msToSec(entry.responseEnd);
addSpan(response);
}

Expand Down Expand Up @@ -469,7 +478,7 @@ export class Tracing implements Integration {
description: `${entry.entryType} ${entry.name}`,
op: 'mark',
});
mark.startTimestamp = transactionSpan.startTimestamp + startTime - navigationOffset;
mark.startTimestamp = timeOrigin + startTime;
mark.timestamp = mark.startTimestamp + duration;
if (tracingInitMarkStartTime === undefined && entry.name === 'sentry-tracing-init') {
tracingInitMarkStartTime = mark.startTimestamp;
Expand All @@ -483,7 +492,7 @@ export class Tracing implements Integration {
if (transactionSpan.spanRecorder) {
transactionSpan.spanRecorder.finishedSpans.map((finishedSpan: SpanClass) => {
if (finishedSpan.description && finishedSpan.description.indexOf(resourceName) !== -1) {
finishedSpan.startTimestamp = transactionSpan.startTimestamp + startTime - navigationOffset;
finishedSpan.startTimestamp = timeOrigin + startTime;
finishedSpan.timestamp = finishedSpan.startTimestamp + duration;
}
});
Expand All @@ -493,7 +502,7 @@ export class Tracing implements Integration {
description: `${entry.initiatorType} ${resourceName}`,
op: `resource`,
});
resource.startTimestamp = transactionSpan.startTimestamp + startTime - navigationOffset;
resource.startTimestamp = timeOrigin + startTime;
resource.timestamp = resource.startTimestamp + duration;
// We remember the entry script end time to calculate the difference to the first init mark
if (entryScriptStartEndTime === undefined && (entryScriptSrc || '').includes(resourceName)) {
Expand Down Expand Up @@ -649,10 +658,17 @@ export class Tracing implements Integration {
});
}
span.finish();
// If there is an offset in data, we need to shift timestamps towards it
if (span.data && typeof span.data.offset === 'number' && typeof span.timestamp === 'number') {
span.startTimestamp += span.data.offset;
span.timestamp += span.data.offset;
// If there is an offset in data, update timestamps accordingly
if (
global.performance &&
span.data &&
typeof span.data.offset === 'number' &&
typeof span.timestamp === 'number'
) {
const timeOrigin = Tracing._msToSec(performance.timeOrigin);
const duration = span.timestamp - span.startTimestamp;
span.startTimestamp = timeOrigin + span.data.offset;
span.timestamp = timeOrigin + duration;
}
}
// tslint:disable-next-line: no-dynamic-delete
Expand Down

0 comments on commit 76da9e7

Please sign in to comment.