Skip to content

Commit 6cf8609

Browse files
committed
feat(opentelemetry): Ignore propagation context when not continuing trace
1 parent b3dad24 commit 6cf8609

File tree

2 files changed

+19
-22
lines changed

2 files changed

+19
-22
lines changed

packages/opentelemetry/src/trace.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,17 @@ function ensureTimestampInMilliseconds(timestamp: number): number {
176176

177177
function getContext(scope: Scope | undefined, forceTransaction: boolean | undefined): Context {
178178
const ctx = getContextForScope(scope);
179-
const actualScope = getScopesFromContext(ctx)?.scope;
180-
181179
const parentSpan = trace.getSpan(ctx);
182180

183181
// In the case that we have no parent span, we need to "simulate" one to ensure the propagation context is correct
184182
if (!parentSpan) {
185-
const client = getClient();
186-
187-
if (actualScope && client) {
188-
const propagationContext = actualScope.getPropagationContext();
183+
const actualScope = getScopesFromContext(ctx)?.scope;
184+
const propagationContext = actualScope && actualScope.getPropagationContext();
189185

186+
// If we are continuing an incoming trace, we use it
187+
// This is signified by the presence of `parentSpanId` -
188+
// if this is not set, then we are not continuing an incoming trace
189+
if (propagationContext && propagationContext.parentSpanId) {
190190
// We store the DSC as OTEL trace state on the span context
191191
const traceState = makeTraceState({
192192
parentSpanId: propagationContext.parentSpanId,
@@ -197,7 +197,7 @@ function getContext(scope: Scope | undefined, forceTransaction: boolean | undefi
197197

198198
const spanOptions: SpanContext = {
199199
traceId: propagationContext.traceId,
200-
spanId: propagationContext.parentSpanId || propagationContext.spanId,
200+
spanId: propagationContext.parentSpanId,
201201
isRemote: true,
202202
traceFlags: propagationContext.sampled ? TraceFlags.SAMPLED : TraceFlags.NONE,
203203
traceState,
@@ -207,7 +207,8 @@ function getContext(scope: Scope | undefined, forceTransaction: boolean | undefi
207207
return trace.setSpanContext(ctx, spanOptions);
208208
}
209209

210-
// if we have no scope or client, we just return the context as-is
210+
// if we have no scope, or the propagationContext is not continuing an incoming trace,
211+
// we just let OTEL start a new trace
211212
return ctx;
212213
}
213214

packages/opentelemetry/test/trace.test.ts

+10-14
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,7 @@ describe('trace', () => {
329329
it('allows to pass parentSpan=null', () => {
330330
startSpan({ name: 'GET users/[id' }, () => {
331331
startSpan({ name: 'child', parentSpan: null }, span => {
332-
// Due to the way we propagate the scope in OTEL,
333-
// the parent_span_id is not actually undefined here, but comes from the propagation context
334-
expect(spanToJSON(span).parent_span_id).toBe(getCurrentScope().getPropagationContext().spanId);
332+
expect(spanToJSON(span).parent_span_id).toBe(undefined);
335333
});
336334
});
337335
});
@@ -591,10 +589,7 @@ describe('trace', () => {
591589
it('allows to pass parentSpan=null', () => {
592590
startSpan({ name: 'outer' }, () => {
593591
const span = startInactiveSpan({ name: 'test span', parentSpan: null });
594-
595-
// Due to the way we propagate the scope in OTEL,
596-
// the parent_span_id is not actually undefined here, but comes from the propagation context
597-
expect(spanToJSON(span).parent_span_id).toBe(getCurrentScope().getPropagationContext().spanId);
592+
expect(spanToJSON(span).parent_span_id).toBe(undefined);
598593
span.end();
599594
});
600595
});
@@ -881,9 +876,7 @@ describe('trace', () => {
881876
it('allows to pass parentSpan=null', () => {
882877
startSpan({ name: 'outer' }, () => {
883878
startSpanManual({ name: 'GET users/[id]', parentSpan: null }, span => {
884-
// Due to the way we propagate the scope in OTEL,
885-
// the parent_span_id is not actually undefined here, but comes from the propagation context
886-
expect(spanToJSON(span).parent_span_id).toBe(getCurrentScope().getPropagationContext().spanId);
879+
expect(spanToJSON(span).parent_span_id).toBe(undefined);
887880
span.end();
888881
});
889882
});
@@ -1016,20 +1009,23 @@ describe('trace', () => {
10161009
});
10171010

10181011
describe('propagation', () => {
1019-
it('picks up the trace context from the scope, if there is no parent', () => {
1012+
it('ignores the trace context from the scope, if there is no parent & no propagationContext.parentSpanId', () => {
10201013
withScope(scope => {
10211014
const propagationContext = scope.getPropagationContext();
10221015
const span = startInactiveSpan({ name: 'test span' });
10231016

10241017
expect(span).toBeDefined();
1025-
expect(spanToJSON(span).trace_id).toEqual(propagationContext.traceId);
1026-
expect(spanToJSON(span).parent_span_id).toEqual(propagationContext.spanId);
1018+
expect(spanToJSON(span).trace_id).toMatch(/^[0-9a-f]{32}$/);
1019+
expect(spanToJSON(span).trace_id).not.toEqual(propagationContext.traceId);
1020+
expect(spanToJSON(span).parent_span_id).toEqual(undefined);
10271021

10281022
expect(getDynamicSamplingContextFromSpan(span)).toEqual({
1029-
...getDynamicSamplingContextFromClient(propagationContext.traceId, getClient()!),
1023+
environment: 'production',
1024+
public_key: 'username',
10301025
sample_rate: '1',
10311026
sampled: 'true',
10321027
transaction: 'test span',
1028+
trace_id: spanToJSON(span).trace_id,
10331029
});
10341030
});
10351031
});

0 commit comments

Comments
 (0)