Skip to content

Commit e087afe

Browse files
authored
ref(tracing): Extract propagation context from meta tags (#8430)
This PR makes sure the `BrowserTracing` integration updates the propagation context based on meta tags. To ensure we don't keep the same propagation context, we continuously update it every time a route change should happen (navigation).
1 parent f8e07ef commit e087afe

File tree

6 files changed

+43
-28
lines changed

6 files changed

+43
-28
lines changed

packages/tracing-internal/src/browser/browsertracing.ts

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
/* eslint-disable max-lines */
22
import type { Hub, IdleTransaction } from '@sentry/core';
3-
import {
4-
addTracingExtensions,
5-
extractTraceparentData,
6-
getActiveTransaction,
7-
startIdleTransaction,
8-
TRACING_DEFAULTS,
9-
} from '@sentry/core';
3+
import { addTracingExtensions, getActiveTransaction, startIdleTransaction, TRACING_DEFAULTS } from '@sentry/core';
104
import type { EventProcessor, Integration, Transaction, TransactionContext, TransactionSource } from '@sentry/types';
11-
import { baggageHeaderToDynamicSamplingContext, getDomElement, logger } from '@sentry/utils';
5+
import { getDomElement, logger, tracingContextFromHeaders } from '@sentry/utils';
126

137
import { registerBackgroundTabDetection } from './backgroundtab';
148
import {
@@ -297,24 +291,25 @@ export class BrowserTracing implements Integration {
297291
return undefined;
298292
}
299293

294+
const hub = this._getCurrentHub();
295+
300296
const { beforeNavigate, idleTimeout, finalTimeout, heartbeatInterval } = this.options;
301297

302298
const isPageloadTransaction = context.op === 'pageload';
303299

304-
const sentryTraceMetaTagValue = isPageloadTransaction ? getMetaContent('sentry-trace') : null;
305-
const baggageMetaTagValue = isPageloadTransaction ? getMetaContent('baggage') : null;
306-
307-
const traceParentData = sentryTraceMetaTagValue ? extractTraceparentData(sentryTraceMetaTagValue) : undefined;
308-
const dynamicSamplingContext = baggageMetaTagValue
309-
? baggageHeaderToDynamicSamplingContext(baggageMetaTagValue)
310-
: undefined;
300+
const sentryTrace = isPageloadTransaction ? getMetaContent('sentry-trace') : '';
301+
const baggage = isPageloadTransaction ? getMetaContent('baggage') : '';
302+
const { traceparentData, dynamicSamplingContext, propagationContext } = tracingContextFromHeaders(
303+
sentryTrace,
304+
baggage,
305+
);
311306

312307
const expandedContext: TransactionContext = {
313308
...context,
314-
...traceParentData,
309+
...traceparentData,
315310
metadata: {
316311
...context.metadata,
317-
dynamicSamplingContext: traceParentData && !dynamicSamplingContext ? {} : dynamicSamplingContext,
312+
dynamicSamplingContext: traceparentData && !dynamicSamplingContext ? {} : dynamicSamplingContext,
318313
},
319314
trimEnd: true,
320315
};
@@ -341,7 +336,6 @@ export class BrowserTracing implements Integration {
341336

342337
__DEBUG_BUILD__ && logger.log(`[Tracing] Starting ${finalContext.op} transaction on scope`);
343338

344-
const hub = this._getCurrentHub();
345339
const { location } = WINDOW;
346340

347341
const idleTransaction = startIdleTransaction(
@@ -353,6 +347,24 @@ export class BrowserTracing implements Integration {
353347
{ location }, // for use in the tracesSampler
354348
heartbeatInterval,
355349
);
350+
351+
const scope = hub.getScope();
352+
353+
// If it's a pageload and there is a meta tag set
354+
// use the traceparentData as the propagation context
355+
if (isPageloadTransaction && traceparentData) {
356+
scope.setPropagationContext(propagationContext);
357+
} else {
358+
// Navigation transactions should set a new propagation context based on the
359+
// created idle transaction.
360+
scope.setPropagationContext({
361+
traceId: idleTransaction.traceId,
362+
spanId: idleTransaction.spanId,
363+
parentSpanId: idleTransaction.parentSpanId,
364+
sampled: !!idleTransaction.sampled,
365+
});
366+
}
367+
356368
idleTransaction.registerBeforeFinishCallback(transaction => {
357369
this._collectWebVitals();
358370
addPerformanceEntries(transaction);
@@ -424,11 +436,11 @@ export class BrowserTracing implements Integration {
424436
}
425437

426438
/** Returns the value of a meta tag */
427-
export function getMetaContent(metaName: string): string | null {
439+
export function getMetaContent(metaName: string): string | undefined {
428440
// Can't specify generic to `getDomElement` because tracing can be used
429441
// in a variety of environments, have to disable `no-unsafe-member-access`
430442
// as a result.
431443
const metaTag = getDomElement(`meta[name=${metaName}]`);
432444
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
433-
return metaTag ? metaTag.getAttribute('content') : null;
445+
return metaTag ? metaTag.getAttribute('content') : undefined;
434446
}

packages/tracing-internal/src/browser/request.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ export function shouldAttachHeaders(url: string, tracePropagationTargets: (strin
214214
*
215215
* @returns Span if a span was created, otherwise void.
216216
*/
217-
function fetchCallback(
217+
export function fetchCallback(
218218
handlerData: FetchData,
219219
shouldCreateSpan: (url: string) => boolean,
220220
shouldAttachHeaders: (url: string) => boolean,
@@ -364,7 +364,7 @@ export function addTracingHeadersToFetchRequest(
364364
*
365365
* @returns Span if a span was created, otherwise void.
366366
*/
367-
function xhrCallback(
367+
export function xhrCallback(
368368
handlerData: XHRData,
369369
shouldCreateSpan: (url: string) => boolean,
370370
shouldAttachHeaders: (url: string) => boolean,

packages/tracing-internal/test/browser/browsertracing.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ describe('BrowserTracing', () => {
9494
const browserTracing = createBrowserTracing();
9595

9696
expect(browserTracing.options).toEqual({
97-
_experiments: {},
9897
enableLongTask: true,
9998
...TRACING_DEFAULTS,
10099
markBackgroundTransactions: true,
@@ -113,16 +112,16 @@ describe('BrowserTracing', () => {
113112
});
114113

115114
expect(browserTracing.options).toEqual({
116-
_experiments: {
117-
enableLongTask: false,
118-
},
119115
enableLongTask: false,
120116
...TRACING_DEFAULTS,
121117
markBackgroundTransactions: true,
122118
routingInstrumentation: instrumentRoutingWithDefaults,
123119
startTransactionOnLocationChange: true,
124120
startTransactionOnPageLoad: true,
125121
...defaultRequestInstrumentationOptions,
122+
_experiments: {
123+
enableLongTask: false,
124+
},
126125
});
127126
});
128127

@@ -132,7 +131,6 @@ describe('BrowserTracing', () => {
132131
});
133132

134133
expect(browserTracing.options).toEqual({
135-
_experiments: {},
136134
enableLongTask: false,
137135
...TRACING_DEFAULTS,
138136
markBackgroundTransactions: true,
@@ -248,6 +246,7 @@ describe('BrowserTracing', () => {
248246
traceFetch: true,
249247
traceXHR: true,
250248
tracePropagationTargets: ['something'],
249+
_experiments: {},
251250
});
252251
});
253252

@@ -261,6 +260,7 @@ describe('BrowserTracing', () => {
261260
});
262261

263262
expect(instrumentOutgoingRequestsMock).toHaveBeenCalledWith({
263+
_experiments: {},
264264
traceFetch: true,
265265
traceXHR: true,
266266
tracePropagationTargets: ['something-else'],
@@ -546,7 +546,7 @@ describe('BrowserTracing', () => {
546546
document.head.innerHTML = '<meta name="cat-cafe">';
547547

548548
const metaTagValue = getMetaContent('dogpark');
549-
expect(metaTagValue).toBe(null);
549+
expect(metaTagValue).toBe(undefined);
550550
});
551551

552552
it('can pick the correct tag out of multiple options', () => {

packages/tracing-internal/test/browser/metrics/index.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ describe('_addMeasureSpans', () => {
1414
name: 'measure-1',
1515
duration: 10,
1616
startTime: 12,
17+
detail: undefined,
1718
};
1819

1920
const timeOrigin = 100;

packages/tracing-internal/test/browser/request.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ describe('callbacks', () => {
240240
expect(finishedSpan.data).toEqual({
241241
'http.response_content_length': 123,
242242
'http.method': 'GET',
243+
'http.response.status_code': 404,
243244
type: 'fetch',
244245
url: 'http://dogs.are.great/',
245246
});

packages/tracing-internal/test/browser/router.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ describe('instrumentRoutingWithDefaults', () => {
4646
name: 'blank',
4747
op: 'pageload',
4848
metadata: { source: 'url' },
49+
startTimestamp: expect.any(Number),
4950
});
5051
});
5152

0 commit comments

Comments
 (0)