@sentry/browser
Version:
Official Sentry SDK for browsers
128 lines (125 loc) • 5.03 kB
JavaScript
import { getRootSpan, getCurrentScope, SEMANTIC_ATTRIBUTE_SENTRY_PREVIOUS_TRACE_SAMPLE_RATE, spanToJSON, debug, SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE } from '@sentry/core/browser';
import { DEBUG_BUILD } from '../debug-build.js';
import { WINDOW } from '../helpers.js';
import '@sentry-internal/browser-utils';
import '../stack-parsers.js';
import '../integrations/breadcrumbs.js';
import '../integrations/browserapierrors.js';
import '../integrations/browsersession.js';
import '../integrations/culturecontext.js';
import '../integrations/globalhandlers.js';
import '../integrations/httpcontext.js';
import '../integrations/linkederrors.js';
const PREVIOUS_TRACE_MAX_DURATION = 3600;
const PREVIOUS_TRACE_KEY = "sentry_previous_trace";
const PREVIOUS_TRACE_TMP_SPAN_ATTRIBUTE = "sentry.previous_trace";
function linkTraces(client, {
linkPreviousTrace,
consistentTraceSampling
}) {
const useSessionStorage = linkPreviousTrace === "session-storage";
let inMemoryPreviousTraceInfo = useSessionStorage ? getPreviousTraceFromSessionStorage() : void 0;
client.on("spanStart", (span) => {
if (getRootSpan(span) !== span) {
return;
}
const oldPropagationContext = getCurrentScope().getPropagationContext();
inMemoryPreviousTraceInfo = addPreviousTraceSpanLink(inMemoryPreviousTraceInfo, span, oldPropagationContext);
if (useSessionStorage) {
storePreviousTraceInSessionStorage(inMemoryPreviousTraceInfo);
}
});
let isFirstTraceOnPageload = true;
if (consistentTraceSampling) {
client.on("beforeSampling", (mutableSamplingContextData) => {
if (!inMemoryPreviousTraceInfo) {
return;
}
const scope = getCurrentScope();
const currentPropagationContext = scope.getPropagationContext();
if (isFirstTraceOnPageload && currentPropagationContext.parentSpanId) {
isFirstTraceOnPageload = false;
return;
}
scope.setPropagationContext({
...currentPropagationContext,
dsc: {
...currentPropagationContext.dsc,
sample_rate: String(inMemoryPreviousTraceInfo.sampleRate),
sampled: String(spanContextSampled(inMemoryPreviousTraceInfo.spanContext))
},
sampleRand: inMemoryPreviousTraceInfo.sampleRand
});
mutableSamplingContextData.parentSampled = spanContextSampled(inMemoryPreviousTraceInfo.spanContext);
mutableSamplingContextData.parentSampleRate = inMemoryPreviousTraceInfo.sampleRate;
mutableSamplingContextData.spanAttributes = {
...mutableSamplingContextData.spanAttributes,
[SEMANTIC_ATTRIBUTE_SENTRY_PREVIOUS_TRACE_SAMPLE_RATE]: inMemoryPreviousTraceInfo.sampleRate
};
});
}
}
function addPreviousTraceSpanLink(previousTraceInfo, span, oldPropagationContext) {
const spanJson = spanToJSON(span);
function getSampleRate() {
try {
return Number(oldPropagationContext.dsc?.sample_rate) ?? Number(spanJson.data?.[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]);
} catch {
return 0;
}
}
const updatedPreviousTraceInfo = {
spanContext: span.spanContext(),
startTimestamp: spanJson.start_timestamp,
sampleRate: getSampleRate(),
sampleRand: oldPropagationContext.sampleRand
};
if (!previousTraceInfo) {
return updatedPreviousTraceInfo;
}
const previousTraceSpanCtx = previousTraceInfo.spanContext;
if (previousTraceSpanCtx.traceId === spanJson.trace_id) {
return previousTraceInfo;
}
if (Date.now() / 1e3 - previousTraceInfo.startTimestamp <= PREVIOUS_TRACE_MAX_DURATION) {
if (DEBUG_BUILD) {
debug.log(
`Adding previous_trace \`${JSON.stringify(previousTraceSpanCtx)}\` link to span \`${JSON.stringify({
op: spanJson.op,
...span.spanContext()
})}\``
);
}
span.addLink({
context: previousTraceSpanCtx,
attributes: {
[SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE]: "previous_trace"
}
});
span.setAttribute(
PREVIOUS_TRACE_TMP_SPAN_ATTRIBUTE,
`${previousTraceSpanCtx.traceId}-${previousTraceSpanCtx.spanId}-${spanContextSampled(previousTraceSpanCtx) ? 1 : 0}`
);
}
return updatedPreviousTraceInfo;
}
function storePreviousTraceInSessionStorage(previousTraceInfo) {
try {
WINDOW.sessionStorage.setItem(PREVIOUS_TRACE_KEY, JSON.stringify(previousTraceInfo));
} catch (e) {
DEBUG_BUILD && debug.warn("Could not store previous trace in sessionStorage", e);
}
}
function getPreviousTraceFromSessionStorage() {
try {
const previousTraceInfo = WINDOW.sessionStorage?.getItem(PREVIOUS_TRACE_KEY);
return JSON.parse(previousTraceInfo);
} catch {
return void 0;
}
}
function spanContextSampled(ctx) {
return ctx.traceFlags === 1;
}
export { PREVIOUS_TRACE_KEY, PREVIOUS_TRACE_MAX_DURATION, PREVIOUS_TRACE_TMP_SPAN_ATTRIBUTE, addPreviousTraceSpanLink, getPreviousTraceFromSessionStorage, linkTraces, spanContextSampled, storePreviousTraceInSessionStorage };
//# sourceMappingURL=linkedTraces.js.map