Skip to content

Commit e21c3bc

Browse files
authored
fix(opentelemetry): Ignore invalid parent spans (#14512)
We do not align with how OTEL traces and the default samplers handle invalid span contexts today. If a span context is invalid, e.g. the span ID or trace ID are invalid, then the span is ignored for new spans as a parent, and the new span will start a new trace. This change aligns our own sampling strategy with this, to ensure that invalid parent span contexts are ignored.
1 parent 1f08b3b commit e21c3bc

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

packages/opentelemetry/src/sampler.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export class SentrySampler implements Sampler {
4848
): SamplingResult {
4949
const options = this._client.getOptions();
5050

51-
const parentSpan = trace.getSpan(context);
51+
const parentSpan = getValidSpan(context);
5252
const parentContext = parentSpan?.spanContext();
5353

5454
if (!hasTracingEnabled(options)) {
@@ -210,3 +210,12 @@ function getBaseTraceState(context: Context, spanAttributes: SpanAttributes): Tr
210210

211211
return traceState;
212212
}
213+
214+
/**
215+
* If the active span is invalid, we want to ignore it as parent.
216+
* This aligns with how otel tracers and default samplers handle these cases.
217+
*/
218+
function getValidSpan(context: Context): Span | undefined {
219+
const span = trace.getSpan(context);
220+
return span && isSpanContextValid(span.spanContext()) ? span : undefined;
221+
}

packages/opentelemetry/test/trace.test.ts

+21
Original file line numberDiff line numberDiff line change
@@ -1450,6 +1450,27 @@ describe('trace (sampling)', () => {
14501450
},
14511451
});
14521452
});
1453+
1454+
it('ignores parent span context if it is invalid', () => {
1455+
mockSdkInit({ tracesSampleRate: 1 });
1456+
const traceId = 'd4cda95b652f4a1592b449d5929fda1b';
1457+
1458+
const spanContext = {
1459+
traceId,
1460+
spanId: 'INVALID',
1461+
traceFlags: TraceFlags.SAMPLED,
1462+
};
1463+
1464+
context.with(trace.setSpanContext(ROOT_CONTEXT, spanContext), () => {
1465+
startSpan({ name: 'outer' }, span => {
1466+
expect(span.isRecording()).toBe(true);
1467+
expect(span.spanContext().spanId).not.toBe('INVALID');
1468+
expect(span.spanContext().spanId).toMatch(/[a-f0-9]{16}/);
1469+
expect(span.spanContext().traceId).not.toBe(traceId);
1470+
expect(span.spanContext().traceId).toMatch(/[a-f0-9]{32}/);
1471+
});
1472+
});
1473+
});
14531474
});
14541475

14551476
describe('HTTP methods (sampling)', () => {

0 commit comments

Comments
 (0)