diff --git a/MIGRATION.md b/MIGRATION.md index 0d8396cd6229..7a3853e996bc 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -16,6 +16,7 @@ In v8, the Span class is heavily reworked. The following properties & methods ar * `span.updateWithContext(newSpanContext)`: Update the fields directly instead. * `span.setName(newName)`: Use `span.updateName(newName)` instead. * `span.toTraceparent()`: use `spanToTraceHeader(span)` util instead. +* `span.getTraceContext()`: Use `spanToTraceContext(span)` utility function instead. ## Deprecate `pushScope` & `popScope` in favor of `withScope` diff --git a/packages/core/src/server-runtime-client.ts b/packages/core/src/server-runtime-client.ts index 66d846c23911..68e1eb065d89 100644 --- a/packages/core/src/server-runtime-client.ts +++ b/packages/core/src/server-runtime-client.ts @@ -21,6 +21,7 @@ import { MetricsAggregator } from './metrics/aggregator'; import type { Scope } from './scope'; import { SessionFlusher } from './sessionflusher'; import { addTracingExtensions, getDynamicSamplingContextFromClient } from './tracing'; +import { spanToTraceContext } from './utils/spanUtils'; export interface ServerRuntimeClientOptions extends ClientOptions { platform?: string; @@ -256,7 +257,7 @@ export class ServerRuntimeClient< const span = scope.getSpan(); if (span) { const samplingContext = span.transaction ? span.transaction.getDynamicSamplingContext() : undefined; - return [samplingContext, span.getTraceContext()]; + return [samplingContext, spanToTraceContext(span)]; } const { traceId, spanId, parentSpanId, dsc } = scope.getPropagationContext(); diff --git a/packages/core/src/tracing/span.ts b/packages/core/src/tracing/span.ts index a3496c5d01d0..e30f6e416675 100644 --- a/packages/core/src/tracing/span.ts +++ b/packages/core/src/tracing/span.ts @@ -13,7 +13,7 @@ import type { import { dropUndefinedKeys, logger, timestampInSeconds, uuid4 } from '@sentry/utils'; import { DEBUG_BUILD } from '../debug-build'; -import { spanToTraceHeader } from '../utils/spanUtils'; +import { spanToTraceContext, spanToTraceHeader } from '../utils/spanUtils'; import { ensureTimestampInSeconds } from './utils'; /** @@ -366,17 +366,7 @@ export class Span implements SpanInterface { * @inheritDoc */ public getTraceContext(): TraceContext { - return dropUndefinedKeys({ - data: this._getData(), - description: this.description, - op: this.op, - parent_span_id: this.parentSpanId, - span_id: this.spanId, - status: this.status, - tags: Object.keys(this.tags).length > 0 ? this.tags : undefined, - trace_id: this.traceId, - origin: this.origin, - }); + return spanToTraceContext(this); } /** diff --git a/packages/core/src/tracing/transaction.ts b/packages/core/src/tracing/transaction.ts index 339d8d51e740..4652ab160143 100644 --- a/packages/core/src/tracing/transaction.ts +++ b/packages/core/src/tracing/transaction.ts @@ -14,6 +14,7 @@ import { dropUndefinedKeys, logger, timestampInSeconds } from '@sentry/utils'; import { DEBUG_BUILD } from '../debug-build'; import type { Hub } from '../hub'; import { getCurrentHub } from '../hub'; +import { spanToTraceContext } from '../utils/spanUtils'; import { getDynamicSamplingContextFromClient } from './dynamicSamplingContext'; import { Span as SpanClass, SpanRecorder } from './span'; import { ensureTimestampInSeconds } from './utils'; @@ -283,7 +284,7 @@ export class Transaction extends SpanClass implements TransactionInterface { contexts: { ...this._contexts, // We don't want to override trace context - trace: this.getTraceContext(), + trace: spanToTraceContext(this), }, spans: finishedSpans, start_timestamp: this.startTimestamp, diff --git a/packages/core/src/utils/applyScopeDataToEvent.ts b/packages/core/src/utils/applyScopeDataToEvent.ts index 1dab87aea866..96a85740ef64 100644 --- a/packages/core/src/utils/applyScopeDataToEvent.ts +++ b/packages/core/src/utils/applyScopeDataToEvent.ts @@ -1,5 +1,6 @@ import type { Breadcrumb, Event, PropagationContext, ScopeData, Span } from '@sentry/types'; import { arrayify } from '@sentry/utils'; +import { spanToTraceContext } from './spanUtils'; /** * Applies data from the scope to the event and runs all event processors on it. @@ -161,7 +162,7 @@ function applySdkMetadataToEvent( } function applySpanToEvent(event: Event, span: Span): void { - event.contexts = { trace: span.getTraceContext(), ...event.contexts }; + event.contexts = { trace: spanToTraceContext(span), ...event.contexts }; const transaction = span.transaction; if (transaction) { event.sdkProcessingMetadata = { diff --git a/packages/core/src/utils/spanUtils.ts b/packages/core/src/utils/spanUtils.ts index 17385fb59c3c..2dae21a78fca 100644 --- a/packages/core/src/utils/spanUtils.ts +++ b/packages/core/src/utils/spanUtils.ts @@ -1,5 +1,24 @@ -import type { Span } from '@sentry/types'; -import { generateSentryTraceHeader } from '@sentry/utils'; +import type { Span, TraceContext } from '@sentry/types'; +import { dropUndefinedKeys, generateSentryTraceHeader } from '@sentry/utils'; + +/** + * Convert a span to a trace context, which can be sent as the `trace` context in an event. + */ +export function spanToTraceContext(span: Span): TraceContext { + const { data, description, op, parent_span_id, span_id, status, tags, trace_id, origin } = span.toJSON(); + + return dropUndefinedKeys({ + data, + description, + op, + parent_span_id, + span_id, + status, + tags, + trace_id, + origin, + }); +} /** * Convert a Span to a Sentry trace header. diff --git a/packages/hub/test/scope.test.ts b/packages/hub/test/scope.test.ts index a2be18b0526d..4cb8694b9cca 100644 --- a/packages/hub/test/scope.test.ts +++ b/packages/hub/test/scope.test.ts @@ -361,12 +361,12 @@ describe('Scope', () => { const scope = new Scope(); const span = { fake: 'span', - getTraceContext: () => ({ a: 'b' }), + toJSON: () => ({ origin: 'manual' }), } as any; scope.setSpan(span); const event: Event = {}; const processedEvent = await scope.applyToEvent(event); - expect((processedEvent!.contexts!.trace as any).a).toEqual('b'); + expect(processedEvent!.contexts!.trace as any).toEqual({ origin: 'manual' }); }); test('existing trace context in event should take precedence', async () => { @@ -374,7 +374,7 @@ describe('Scope', () => { const scope = new Scope(); const span = { fake: 'span', - getTraceContext: () => ({ a: 'b' }), + toJSON: () => ({ a: 'b' }), } as any; scope.setSpan(span); const event: Event = { @@ -392,7 +392,7 @@ describe('Scope', () => { const scope = new Scope(); const transaction = { fake: 'span', - getTraceContext: () => ({ a: 'b' }), + toJSON: () => ({ a: 'b' }), name: 'fake transaction', getDynamicSamplingContext: () => ({}), } as any; @@ -410,7 +410,7 @@ describe('Scope', () => { const transaction = { name: 'fake transaction', getDynamicSamplingContext: () => ({}) }; const span = { fake: 'span', - getTraceContext: () => ({ a: 'b' }), + toJSON: () => ({ a: 'b' }), transaction, } as any; scope.setSpan(span); diff --git a/packages/types/src/span.ts b/packages/types/src/span.ts index 8fd384f4ba11..3e625dc7dd9f 100644 --- a/packages/types/src/span.ts +++ b/packages/types/src/span.ts @@ -1,3 +1,4 @@ +import type { TraceContext } from './context'; import type { Instrumenter } from './instrumenter'; import type { Primitive } from './misc'; import type { Transaction } from './transaction'; @@ -243,17 +244,11 @@ export interface Span extends SpanContext { */ updateWithContext(spanContext: SpanContext): this; - /** Convert the object to JSON for w. spans array info only */ - getTraceContext(): { - data?: { [key: string]: any }; - description?: string; - op?: string; - parent_span_id?: string; - span_id: string; - status?: string; - tags?: { [key: string]: Primitive }; - trace_id: string; - }; + /** + * Convert the object to JSON for w. spans array info only. + * @deprecated Use `spanToTraceContext()` util function instead. + */ + getTraceContext(): TraceContext; /** Convert the object to JSON */ toJSON(): { @@ -267,5 +262,6 @@ export interface Span extends SpanContext { tags?: { [key: string]: Primitive }; timestamp?: number; trace_id: string; + origin?: SpanOrigin; }; }