MCPcopy Create free account
hub / github.com/getsentry/sentry-javascript / linkTraces

Function linkTraces

packages/browser/src/tracing/linkedTraces.ts:49–126  ·  view source on GitHub ↗
(
  client: Client,
  {
    linkPreviousTrace,
    consistentTraceSampling,
  }: {
    linkPreviousTrace: 'session-storage' | 'in-memory';
    consistentTraceSampling: boolean;
  },
)

Source from the content-addressed store, hash-verified

47 * @param client - Sentry client
48 */
49export function linkTraces(
50 client: Client,
51 {
52 linkPreviousTrace,
53 consistentTraceSampling,
54 }: {
55 linkPreviousTrace: 'session-storage' | 'in-memory';
56 consistentTraceSampling: boolean;
57 },
58): void {
59 const useSessionStorage = linkPreviousTrace === 'session-storage';
60
61 let inMemoryPreviousTraceInfo = useSessionStorage ? getPreviousTraceFromSessionStorage() : undefined;
62
63 client.on('spanStart', span => {
64 if (getRootSpan(span) !== span) {
65 return;
66 }
67
68 const oldPropagationContext = getCurrentScope().getPropagationContext();
69 inMemoryPreviousTraceInfo = addPreviousTraceSpanLink(inMemoryPreviousTraceInfo, span, oldPropagationContext);
70
71 if (useSessionStorage) {
72 storePreviousTraceInSessionStorage(inMemoryPreviousTraceInfo);
73 }
74 });
75
76 let isFirstTraceOnPageload = true;
77 if (consistentTraceSampling) {
78 /*
79 When users opt into `consistentTraceSampling`, we need to ensure that we propagate
80 the previous trace's sample rate and rand to the current trace. This is necessary because otherwise, span
81 metric extrapolation is inaccurate, as we'd propagate too high of a sample rate for the subsequent traces.
82
83 So therefore, we pretend that the previous trace was the parent trace of the newly started trace. To do that,
84 we mutate the propagation context of the current trace and set the sample rate and sample rand of the previous trace.
85 Timing-wise, it is fine because it happens before we even sample the root span.
86
87 @see https://github.com/getsentry/sentry-javascript/issues/15754
88 */
89 client.on('beforeSampling', mutableSamplingContextData => {
90 if (!inMemoryPreviousTraceInfo) {
91 return;
92 }
93
94 const scope = getCurrentScope();
95 const currentPropagationContext = scope.getPropagationContext();
96
97 // We do not want to force-continue the sampling decision if we continue a trace
98 // that was started on the backend. Most prominently, this will happen in MPAs where
99 // users hard-navigate between pages. In this case, the sampling decision of a potentially
100 // started trace on the server takes precedence.
101 // Why? We want to prioritize inter-trace consistency over intra-trace consistency.
102 if (isFirstTraceOnPageload && currentPropagationContext.parentSpanId) {
103 isFirstTraceOnPageload = false;
104 return;
105 }
106

Callers 2

afterAllSetupFunction · 0.90

Calls 9

getRootSpanFunction · 0.85
addPreviousTraceSpanLinkFunction · 0.85
spanContextSampledFunction · 0.85
getPropagationContextMethod · 0.80
setPropagationContextMethod · 0.80
onMethod · 0.65
getCurrentScopeFunction · 0.50

Tested by

no test coverage detected