Skip to content

Commit

Permalink
feat(sdk-trace-base)!: Add parentSpanContext and remove parentSpanId (#…
Browse files Browse the repository at this point in the history
…5450)

Co-authored-by: Marc Pichler <marc.pichler@dynatrace.com>
  • Loading branch information
JacksonWeber and pichlermarc authored Feb 18, 2025
1 parent 14d55d8 commit 1afa8ba
Show file tree
Hide file tree
Showing 28 changed files with 168 additions and 106 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ For semantic convention package changes, see the [semconv CHANGELOG](packages/se

### :boom: Breaking Change

* feat(sdk-trace-base)!: Add `parentSpanContext` and remove `parentSpanId` from `Span` and `ReadableSpan` [#5450](/~https://github.com/open-telemetry/opentelemetry-js/pull/5450) @JacksonWeber
* (user-facing): the SDK's `Span`s `parentSpanId` was replaced by `parentSpanContext`, to migrate to the new property, please replace `span.parentSpanId` -> `span.parentSpanContext?.spanId`
* feat(sdk-metrics)!: drop deprecated `type` field on `MetricDescriptor` [#5291](/~https://github.com/open-telemetry/opentelemetry-js/pull/5291) @chancancode
* feat(sdk-metrics)!: drop deprecated `InstrumentDescriptor` type; use `MetricDescriptor` instead [#5277](/~https://github.com/open-telemetry/opentelemetry-js/pull/5266) @chancancode
* feat(sdk-metrics)!: bump minimum version of `@opentelemetry/api` peer dependency to 1.9.0 [#5254](/~https://github.com/open-telemetry/opentelemetry-js/pull/5254) @chancancode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ describe('fetch', () => {
const span: tracing.ReadableSpan = exportedSpans[0];

assert.strictEqual(
span.parentSpanId,
span.parentSpanContext?.spanId,
rootSpan!.spanContext().spanId,
'parent span is not root span'
);
Expand Down Expand Up @@ -775,7 +775,7 @@ describe('fetch', () => {
const span: tracing.ReadableSpan = exportedSpans[0];

assert.strictEqual(
span.parentSpanId,
span.parentSpanContext?.spanId,
rootSpan!.spanContext().spanId,
'parent span is not root span'
);
Expand Down Expand Up @@ -1636,7 +1636,7 @@ describe('fetch', () => {
const span: tracing.ReadableSpan = exportedSpans[0];

assert.strictEqual(
span.parentSpanId,
span.parentSpanContext?.spanId,
rootSpan!.spanContext().spanId,
'parent span is not root span'
);
Expand Down Expand Up @@ -1686,7 +1686,7 @@ describe('fetch', () => {
const span: tracing.ReadableSpan = exportedSpans[0];

assert.strictEqual(
span.parentSpanId,
span.parentSpanContext?.spanId,
rootSpan!.spanContext().spanId,
'parent span is not root span'
);
Expand Down Expand Up @@ -1768,7 +1768,7 @@ describe('fetch', () => {
const span: tracing.ReadableSpan = exportedSpans[0];

assert.strictEqual(
span.parentSpanId,
span.parentSpanContext?.spanId,
rootSpan!.spanContext().spanId,
'parent span is not root span'
);
Expand Down Expand Up @@ -1867,7 +1867,7 @@ describe('fetch', () => {
const span: tracing.ReadableSpan = exportedSpans[0];

assert.strictEqual(
span.parentSpanId,
span.parentSpanContext?.spanId,
rootSpan!.spanContext().spanId,
'parent span is not root span'
);
Expand Down Expand Up @@ -1925,7 +1925,7 @@ describe('fetch', () => {
const span: tracing.ReadableSpan = exportedSpans[0];

assert.strictEqual(
span.parentSpanId,
span.parentSpanContext?.spanId,
rootSpan!.spanContext().spanId,
'parent span is not root span'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ export const runTests = (
);
assert.strictEqual(
rootSpan.spanContext().spanId,
clientSpan.parentSpanId
clientSpan.parentSpanContext?.spanId
);
}
})
Expand Down Expand Up @@ -740,7 +740,7 @@ export const runTests = (
);
assert.strictEqual(
rootSpan.spanContext().spanId,
clientSpan.parentSpanId
clientSpan.parentSpanContext?.spanId
);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ export function assertExportedSpans(
rootSpan?.spanContext().traceId,
serverSpan.spanContext().traceId
);
assert.strictEqual(rootSpan?.spanContext().spanId, clientSpan.parentSpanId);
assert.strictEqual(
rootSpan?.spanContext().spanId,
clientSpan.parentSpanContext?.spanId
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ export const assertPropagation = (
const targetSpanContext = incomingSpan.spanContext();
const sourceSpanContext = outgoingSpan.spanContext();
assert.strictEqual(targetSpanContext.traceId, sourceSpanContext.traceId);
assert.strictEqual(incomingSpan.parentSpanId, sourceSpanContext.spanId);
assert.strictEqual(
incomingSpan.parentSpanContext?.spanId,
sourceSpanContext.spanId
);
assert.strictEqual(
targetSpanContext.traceFlags,
sourceSpanContext.traceFlags
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@ export const assertSpan = (
validations.component,
' must have http.scheme attribute'
);
assert.ok(typeof span.parentSpanId === 'string');
assert.ok(isValidSpanId(span.parentSpanId));
assert.ok(typeof span.parentSpanContext?.spanId === 'string');
assert.ok(isValidSpanId(span.parentSpanContext.spanId));
} else if (validations.reqHeaders) {
assert.ok(validations.reqHeaders[DummyPropagation.TRACE_CONTEXT_KEY]);
assert.ok(validations.reqHeaders[DummyPropagation.SPAN_CONTEXT_KEY]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ describe('xhr', () => {
it('should create a span with correct root span', () => {
const span: tracing.ReadableSpan = exportSpy.args[1][0][0];
assert.strictEqual(
span.parentSpanId,
span.parentSpanContext?.spanId,
rootSpan.spanContext().spanId,
'parent span is not root span'
);
Expand Down Expand Up @@ -492,7 +492,7 @@ describe('xhr', () => {
const span: tracing.ReadableSpan = exportSpy.args[0][0][0];
const parentSpan: tracing.ReadableSpan = exportSpy.args[1][0][0];
assert.strictEqual(
span.parentSpanId,
span.parentSpanContext?.spanId,
parentSpan.spanContext().spanId,
'parent span is not root span'
);
Expand Down Expand Up @@ -1586,7 +1586,7 @@ describe('xhr', () => {
it('should create a span with correct root span', () => {
const span: tracing.ReadableSpan = exportSpy.args[1][0][0];
assert.strictEqual(
span.parentSpanId,
span.parentSpanContext?.spanId,
rootSpan.spanContext().spanId,
'parent span is not root span'
);
Expand Down Expand Up @@ -1690,7 +1690,7 @@ describe('xhr', () => {
const span: tracing.ReadableSpan = exportSpy.args[0][0][0];
const parentSpan: tracing.ReadableSpan = exportSpy.args[1][0][0];
assert.strictEqual(
span.parentSpanId,
span.parentSpanContext?.spanId,
parentSpan.spanContext().spanId,
'parent span is not root span'
);
Expand Down
5 changes: 4 additions & 1 deletion experimental/packages/otlp-transformer/src/trace/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,13 @@ import { getOtlpEncoder } from '../common/utils';
export function sdkSpanToOtlpSpan(span: ReadableSpan, encoder: Encoder): ISpan {
const ctx = span.spanContext();
const status = span.status;
const parentSpanId = span.parentSpanContext?.spanId
? encoder.encodeSpanContext(span.parentSpanContext?.spanId)
: undefined;
return {
traceId: encoder.encodeSpanContext(ctx.traceId),
spanId: encoder.encodeSpanContext(ctx.spanId),
parentSpanId: encoder.encodeOptionalSpanContext(span.parentSpanId),
parentSpanId: parentSpanId,
traceState: ctx.traceState?.serialize(),
name: span.name,
// Span kind is offset by 1 because the API does not define a value for unset
Expand Down
19 changes: 12 additions & 7 deletions experimental/packages/otlp-transformer/test/trace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { createExportTraceServiceRequest } from '../src/trace/internal';
import { ProtobufTraceSerializer } from '../src/trace/protobuf';
import { JsonTraceSerializer } from '../src/trace/json';
import { hexToBinary } from '../src/common/hex-to-binary';
import { ISpan } from '../src/trace/internal-types';

function createExpectedSpanJson(options: OtlpEncodingOptions) {
const useHex = options.useHex ?? false;
Expand Down Expand Up @@ -243,7 +244,11 @@ describe('Trace', () => {
isRemote: false,
traceState: new TraceState('span=bar'),
}),
parentSpanId: '0000000000000001',
parentSpanContext: {
spanId: '0000000000000001',
traceId: '00000000000000000000000000000001',
traceFlags: TraceFlags.SAMPLED,
},
attributes: { 'string-attribute': 'some attribute value' },
duration: [1, 300000000],
endTime: [1640715558, 642725388],
Expand Down Expand Up @@ -329,25 +334,27 @@ describe('Trace', () => {
});

it('serializes a span without a parent with useHex = true', () => {
(span as any).parentSpanId = undefined;
(span as any).parentSpanContext.spanId = undefined;
const exportRequest = createExportTraceServiceRequest([span], {
useHex: true,
});
assert.ok(exportRequest);
assert.strictEqual(
exportRequest.resourceSpans?.[0].scopeSpans[0].spans?.[0].parentSpanId,
(exportRequest.resourceSpans?.[0].scopeSpans[0].spans?.[0] as ISpan)
.parentSpanId,
undefined
);
});

it('serializes a span without a parent with useHex = false', () => {
(span as any).parentSpanId = undefined;
(span as any).parentSpanContext.spanId = undefined;
const exportRequest = createExportTraceServiceRequest([span], {
useHex: false,
});
assert.ok(exportRequest);
assert.strictEqual(
exportRequest.resourceSpans?.[0].scopeSpans[0].spans?.[0].parentSpanId,
(exportRequest.resourceSpans?.[0].scopeSpans[0].spans?.[0] as ISpan)
.parentSpanId,
undefined
);
});
Expand Down Expand Up @@ -446,7 +453,6 @@ describe('Trace', () => {
root.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest.decode(
serialized
);

const expected = createExpectedSpanProtobuf();
const decodedObj =
root.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest.toObject(
Expand All @@ -461,7 +467,6 @@ describe('Trace', () => {
bytes: String,
}
);

assert.deepStrictEqual(decodedObj, expected);
});

Expand Down
4 changes: 2 additions & 2 deletions experimental/packages/shim-opencensus/test/ShimSpan.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ describe('ShimSpan', () => {

assert.strictEqual(childSpan.name, 'span');
assert.deepStrictEqual(
childSpan.parentSpanId,
childSpan.parentSpanContext?.spanId,
parentSpan.spanContext().spanId
);
});
Expand All @@ -120,7 +120,7 @@ describe('ShimSpan', () => {

assert.strictEqual(childSpan.name, 'child');
assert.deepStrictEqual(
childSpan.parentSpanId,
childSpan.parentSpanContext?.spanId,
parentSpan.spanContext().spanId
);
});
Expand Down
12 changes: 9 additions & 3 deletions experimental/packages/shim-opencensus/test/ShimTracer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ describe('ShimTracer', () => {
otelSpans[0].spanContext().traceId,
'9e7ecdc193765065fee1efe757fdd874'
);
assert.strictEqual(otelSpans[0].parentSpanId, '4bf6239d37d8b0f0');
assert.strictEqual(
otelSpans[0].parentSpanContext?.spanId,
'4bf6239d37d8b0f0'
);
});

it('should set the span as root span in context', async () => {
Expand Down Expand Up @@ -154,7 +157,7 @@ describe('ShimTracer', () => {
parent.end();
});
assert.strictEqual(
childSpan.parentSpanId,
childSpan.parentSpanContext?.spanId,
parentSpan.spanContext().spanId
);
});
Expand All @@ -171,7 +174,10 @@ describe('ShimTracer', () => {
}
);
});
assert.strictEqual(childSpan.parentSpanId, rootSpan.spanContext().spanId);
assert.strictEqual(
childSpan.parentSpanContext?.spanId,
rootSpan.spanContext().spanId
);
});
});

Expand Down
17 changes: 13 additions & 4 deletions experimental/packages/shim-opencensus/test/otel-sandwich.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ describe('OpenTelemetry sandwich', () => {
childSpan.spanContext().traceId,
parentSpan.spanContext().traceId
);
assert.strictEqual(childSpan.parentSpanId, parentSpan.spanContext().spanId);
assert.strictEqual(
childSpan.parentSpanContext?.spanId,
parentSpan.spanContext().spanId
);
});

it('should maintain parent-child relationship for OC -> OTel', async () => {
Expand All @@ -55,7 +58,10 @@ describe('OpenTelemetry sandwich', () => {
childSpan.spanContext().traceId,
parentSpan.spanContext().traceId
);
assert.strictEqual(childSpan.parentSpanId, parentSpan.spanContext().spanId);
assert.strictEqual(
childSpan.parentSpanContext?.spanId,
parentSpan.spanContext().spanId
);
});

it('should maintain structure for OTel -> OC -> OTel', async () => {
Expand All @@ -80,9 +86,12 @@ describe('OpenTelemetry sandwich', () => {
parentSpan.spanContext().traceId
);
assert.strictEqual(
middleSpan.parentSpanId,
middleSpan.parentSpanContext?.spanId,
parentSpan.spanContext().spanId
);
assert.strictEqual(childSpan.parentSpanId, middleSpan.spanContext().spanId);
assert.strictEqual(
childSpan.parentSpanContext?.spanId,
middleSpan.spanContext().spanId
);
});
});
4 changes: 2 additions & 2 deletions packages/opentelemetry-exporter-jaeger/src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export function spanToThrift(span: ReadableSpan): ThriftSpan {
const traceId = span.spanContext().traceId.padStart(32, '0');
const traceIdHigh = traceId.slice(0, 16);
const traceIdLow = traceId.slice(16);
const parentSpan = span.parentSpanId
? Utils.encodeInt64(span.parentSpanId)
const parentSpan = span.parentSpanContext?.spanId
? Utils.encodeInt64(span.parentSpanContext.spanId)
: ThriftUtils.emptyBuffer;

const tags = Object.keys(span.attributes).map(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,11 @@ describe('transform', () => {
code: api.SpanStatusCode.OK,
},
attributes: {},
parentSpanId: '3e0c63257de34c92',
parentSpanContext: {
traceId: 'a4cda95b652f4a1592b449d5929fda1b',
spanId: '3e0c63257de34c92',
traceFlags: TraceFlags.SAMPLED,
},
links: [
{
context: {
Expand Down
2 changes: 1 addition & 1 deletion packages/opentelemetry-exporter-zipkin/src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export function toZipkinSpan(
): zipkinTypes.Span {
const zipkinSpan: zipkinTypes.Span = {
traceId: span.spanContext().traceId,
parentId: span.parentSpanId,
parentId: span.parentSpanContext?.spanId,
name: span.name,
id: span.spanContext().spanId,
kind: ZIPKIN_SPAN_KIND_MAPPING[span.kind],
Expand Down
Loading

0 comments on commit 1afa8ba

Please sign in to comment.