Skip to content

Commit 17396a1

Browse files
authored
feat(core): Deprecate spanId on propagationContext (#14482)
This PR deprecates setting & reading the `spanId` on the propagation context, as well as `generatePropagationContext()`. Instead, you can/should now omit the spanId: `scope.setPropagationContext({ traceId: generateTraceId() })`, which will under the hood generate a new random span ID for the time being. This PR does not change any behavior about using the spanId, but adds comments for where we want to replace this in v9 - there, we'll just generate new span IDs on the fly in these cases instead of using the one from propagation context. The propagation context will only hold traceId & parentSpanId (optionally). Closes #14255
1 parent a4138e9 commit 17396a1

File tree

17 files changed

+67
-18
lines changed

17 files changed

+67
-18
lines changed

docs/migration/draft-v9-migration-guide.md

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
- Deprecated `debugIntegration`. To log outgoing events, use [Hook Options](https://docs.sentry.io/platforms/javascript/configuration/options/#hooks) (`beforeSend`, `beforeSendTransaction`, ...).
4444
- Deprecated `sessionTimingIntegration`. To capture session durations alongside events, use [Context](https://docs.sentry.io/platforms/javascript/enriching-events/context/) (`Sentry.setContext()`).
4545
- Deprecated `addTracingHeadersToFetchRequest` method - this was only meant for internal use and is not needed anymore.
46+
- Deprecated `generatePropagationContext()` in favor of using `generateTraceId()` directly.
47+
- Deprecated `spanId` field on `propagationContext` - this field will be removed in v9, and should neither be read or set anymore.
4648

4749
## `@sentry/nestjs`
4850

packages/browser/src/tracing/browserTracingIntegration.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
1515
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
1616
TRACING_DEFAULTS,
17+
generateTraceId,
1718
getActiveSpan,
1819
getClient,
1920
getCurrentScope,
@@ -28,7 +29,6 @@ import {
2829
import {
2930
GLOBAL_OBJ,
3031
browserPerformanceTimeOrigin,
31-
generatePropagationContext,
3232
getDomElement,
3333
logger,
3434
propagationContextFromHeaders,
@@ -452,8 +452,8 @@ export function startBrowserTracingPageLoadSpan(
452452
* This will only do something if a browser tracing integration has been setup.
453453
*/
454454
export function startBrowserTracingNavigationSpan(client: Client, spanOptions: StartSpanOptions): Span | undefined {
455-
getIsolationScope().setPropagationContext(generatePropagationContext());
456-
getCurrentScope().setPropagationContext(generatePropagationContext());
455+
getIsolationScope().setPropagationContext({ traceId: generateTraceId() });
456+
getCurrentScope().setPropagationContext({ traceId: generateTraceId() });
457457

458458
client.emit('startNavigationSpan', spanOptions);
459459

packages/browser/test/tracing/browserTracingIntegration.test.ts

+2
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,7 @@ describe('browserTracingIntegration', () => {
688688

689689
const propCtxAfterEnd = getCurrentScope().getPropagationContext();
690690
expect(propCtxAfterEnd).toStrictEqual({
691+
// eslint-disable-next-line deprecation/deprecation
691692
spanId: propCtxBeforeEnd.spanId,
692693
traceId: propCtxBeforeEnd.traceId,
693694
sampled: true,
@@ -727,6 +728,7 @@ describe('browserTracingIntegration', () => {
727728

728729
const propCtxAfterEnd = getCurrentScope().getPropagationContext();
729730
expect(propCtxAfterEnd).toStrictEqual({
731+
// eslint-disable-next-line deprecation/deprecation
730732
spanId: propCtxBeforeEnd.spanId,
731733
traceId: propCtxBeforeEnd.traceId,
732734
sampled: false,

packages/core/src/currentScopes.ts

+2
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ export function getClient<C extends Client>(): C | undefined {
128128
export function getTraceContextFromScope(scope: Scope): TraceContext {
129129
const propagationContext = scope.getPropagationContext();
130130

131+
// TODO(v9): Use generateSpanId() instead of spanId
132+
// eslint-disable-next-line deprecation/deprecation
131133
const { traceId, spanId, parentSpanId } = propagationContext;
132134

133135
const traceContext: TraceContext = dropUndefinedKeys({

packages/core/src/scope.ts

+14-5
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { updateSession } from './session';
2626
import { isPlainObject } from './utils-hoist/is';
2727
import { logger } from './utils-hoist/logger';
2828
import { uuid4 } from './utils-hoist/misc';
29-
import { generatePropagationContext } from './utils-hoist/propagationContext';
29+
import { generateSpanId, generateTraceId } from './utils-hoist/propagationContext';
3030
import { dateTimestampInSeconds } from './utils-hoist/time';
3131
import { merge } from './utils/merge';
3232
import { _getSpanForScope, _setSpanForScope } from './utils/spanOnScope';
@@ -115,7 +115,10 @@ class ScopeClass implements ScopeInterface {
115115
this._extra = {};
116116
this._contexts = {};
117117
this._sdkProcessingMetadata = {};
118-
this._propagationContext = generatePropagationContext();
118+
this._propagationContext = {
119+
traceId: generateTraceId(),
120+
spanId: generateSpanId(),
121+
};
119122
}
120123

121124
/**
@@ -398,7 +401,7 @@ class ScopeClass implements ScopeInterface {
398401
this._session = undefined;
399402
_setSpanForScope(this, undefined);
400403
this._attachments = [];
401-
this._propagationContext = generatePropagationContext();
404+
this.setPropagationContext({ traceId: generateTraceId() });
402405

403406
this._notifyScopeListeners();
404407
return this;
@@ -491,8 +494,14 @@ class ScopeClass implements ScopeInterface {
491494
/**
492495
* @inheritDoc
493496
*/
494-
public setPropagationContext(context: PropagationContext): this {
495-
this._propagationContext = context;
497+
public setPropagationContext(
498+
context: Omit<PropagationContext, 'spanId'> & Partial<Pick<PropagationContext, 'spanId'>>,
499+
): this {
500+
this._propagationContext = {
501+
// eslint-disable-next-line deprecation/deprecation
502+
spanId: generateSpanId(),
503+
...context,
504+
};
496505
return this;
497506
}
498507

packages/core/src/tracing/trace.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { getAsyncContextStrategy } from '../asyncContext';
1010
import { DEBUG_BUILD } from '../debug-build';
1111
import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '../semanticAttributes';
1212
import { logger } from '../utils-hoist/logger';
13-
import { generatePropagationContext } from '../utils-hoist/propagationContext';
13+
import { generateTraceId } from '../utils-hoist/propagationContext';
1414
import { propagationContextFromHeaders } from '../utils-hoist/tracing';
1515
import { handleCallbackErrors } from '../utils/handleCallbackErrors';
1616
import { hasTracingEnabled } from '../utils/hasTracingEnabled';
@@ -260,7 +260,7 @@ export function suppressTracing<T>(callback: () => T): T {
260260
*/
261261
export function startNewTrace<T>(callback: () => T): T {
262262
return withScope(scope => {
263-
scope.setPropagationContext(generatePropagationContext());
263+
scope.setPropagationContext({ traceId: generateTraceId() });
264264
DEBUG_BUILD && logger.info(`Starting a new trace with id ${scope.getPropagationContext().traceId}`);
265265
return withActiveSpan(null, callback);
266266
});

packages/core/src/utils-hoist/index.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,12 @@ export { makeFifoCache } from './cache';
166166
export { eventFromMessage, eventFromUnknownInput, exceptionFromError, parseStackFrames } from './eventbuilder';
167167
export { callFrameToStackFrame, watchdogTimer } from './anr';
168168
export { LRUMap } from './lru';
169-
export { generatePropagationContext } from './propagationContext';
169+
export {
170+
// eslint-disable-next-line deprecation/deprecation
171+
generatePropagationContext,
172+
generateTraceId,
173+
generateSpanId,
174+
} from './propagationContext';
170175
export { vercelWaitUntil } from './vercelWaitUntil';
171176
export { SDK_VERSION } from './version';
172177
export { getDebugImagesForResources, getFilenameToDebugIdMap } from './debug-ids';

packages/core/src/utils-hoist/propagationContext.ts

+19-3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,27 @@ import type { PropagationContext } from '@sentry/types';
22
import { uuid4 } from './misc';
33

44
/**
5-
* Returns a new minimal propagation context
5+
* Returns a new minimal propagation context.
6+
*
7+
* @deprecated Use `generateTraceId` and `generateSpanId` instead.
68
*/
79
export function generatePropagationContext(): PropagationContext {
810
return {
9-
traceId: uuid4(),
10-
spanId: uuid4().substring(16),
11+
traceId: generateTraceId(),
12+
spanId: generateSpanId(),
1113
};
1214
}
15+
16+
/**
17+
* Generate a random, valid trace ID.
18+
*/
19+
export function generateTraceId(): string {
20+
return uuid4();
21+
}
22+
23+
/**
24+
* Generate a random, valid span ID.
25+
*/
26+
export function generateSpanId(): string {
27+
return uuid4().substring(16);
28+
}

packages/core/src/utils-hoist/tracing.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { PropagationContext, TraceparentData } from '@sentry/types';
22

33
import { baggageHeaderToDynamicSamplingContext } from './baggage';
44
import { uuid4 } from './misc';
5-
import { generatePropagationContext } from './propagationContext';
5+
import { generateSpanId, generateTraceId } from './propagationContext';
66

77
// eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- RegExp is used for readability here
88
export const TRACEPARENT_REGEXP = new RegExp(
@@ -56,12 +56,12 @@ export function propagationContextFromHeaders(
5656
const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(baggage);
5757

5858
if (!traceparentData || !traceparentData.traceId) {
59-
return generatePropagationContext();
59+
return { traceId: generateTraceId(), spanId: generateSpanId() };
6060
}
6161

6262
const { traceId, parentSpanId, parentSampled } = traceparentData;
6363

64-
const virtualSpanId = uuid4().substring(16);
64+
const virtualSpanId = generateSpanId();
6565

6666
return {
6767
traceId,

packages/core/src/utils/traceData.ts

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ export function getTraceData(options: { span?: Span } = {}): SerializedTraceData
5454
* Get a sentry-trace header value for the given scope.
5555
*/
5656
function scopeToTraceHeader(scope: Scope): string {
57+
// TODO(v9): Use generateSpanId() instead of spanId
58+
// eslint-disable-next-line deprecation/deprecation
5759
const { traceId, sampled, spanId } = scope.getPropagationContext();
5860
return generateSentryTraceHeader(traceId, spanId, sampled);
5961
}

packages/core/test/utils-hoist/proagationContext.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { generatePropagationContext } from '../../src/utils-hoist/propagationCon
22

33
describe('generatePropagationContext', () => {
44
it('generates a new minimal propagation context', () => {
5+
// eslint-disable-next-line deprecation/deprecation
56
expect(generatePropagationContext()).toEqual({
67
traceId: expect.stringMatching(/^[0-9a-f]{32}$/),
78
spanId: expect.stringMatching(/^[0-9a-f]{16}$/),

packages/node/src/integrations/anr/worker.ts

+2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ function applyScopeToEvent(event: Event, scope: ScopeData): void {
121121
applyScopeDataToEvent(event, scope);
122122

123123
if (!event.contexts?.trace) {
124+
// TODO(v9): Use generateSpanId() instead of spanId
125+
// eslint-disable-next-line deprecation/deprecation
124126
const { traceId, spanId, parentSpanId } = scope.propagationContext;
125127
event.contexts = {
126128
trace: {

packages/opentelemetry/src/propagator.ts

+2
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ export function getInjectionData(context: Context): {
220220
return {
221221
dynamicSamplingContext,
222222
traceId: propagationContext.traceId,
223+
// TODO(v9): Use generateSpanId() instead
224+
// eslint-disable-next-line deprecation/deprecation
223225
spanId: propagationContext.spanId,
224226
sampled: propagationContext.sampled,
225227
};

packages/opentelemetry/src/trace.ts

+1
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ function getContext(scope: Scope | undefined, forceTransaction: boolean | undefi
201201

202202
const spanOptions: SpanContext = {
203203
traceId: propagationContext.traceId,
204+
// eslint-disable-next-line deprecation/deprecation
204205
spanId: propagationContext.parentSpanId || propagationContext.spanId,
205206
isRemote: true,
206207
traceFlags: propagationContext.sampled ? TraceFlags.SAMPLED : TraceFlags.NONE,

packages/types/src/scope.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,9 @@ export interface Scope {
226226
/**
227227
* Add propagation context to the scope, used for distributed tracing
228228
*/
229-
setPropagationContext(context: PropagationContext): this;
229+
setPropagationContext(
230+
context: Omit<PropagationContext, 'spanId'> & Partial<Pick<PropagationContext, 'spanId'>>,
231+
): this;
230232

231233
/**
232234
* Get propagation context from the scope, used for distributed tracing

packages/types/src/tracing.ts

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export interface PropagationContext {
2020
* particular execution context when performance monitoring is disabled.
2121
*
2222
* The ID of a current span (if one exists) should have precedence over this value when propagating trace data.
23+
*
24+
* @deprecated This value will not be used anymore in the future, and should not be set or read anymore.
2325
*/
2426
spanId: string;
2527
/**

packages/utils/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ export const watchdogTimer = watchdogTimer_imported;
517517
export const LRUMap = LRUMap_imported;
518518

519519
/** @deprecated Import from `@sentry/core` instead. */
520+
// eslint-disable-next-line deprecation/deprecation
520521
export const generatePropagationContext = generatePropagationContext_imported;
521522

522523
/** @deprecated Import from `@sentry/core` instead. */

0 commit comments

Comments
 (0)