Skip to content

Commit ca0e845

Browse files
Do not allocate a tracing context when not fully extracted (#9693)
* OTEL: don't return a span if not valid * suggestions * feat(otel): Improving test Moving missing trace context to a dedicated test (not dependent on other propagation style as it concerns tracecontext only). Adding more tests related to Span.fromContextOrNull() on span activation test suite. --------- Co-authored-by: Bruce Bujon <[email protected]>
1 parent e29d658 commit ca0e845

File tree

3 files changed

+53
-7
lines changed

3 files changed

+53
-7
lines changed

dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/context/OtelContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@ public Scope makeCurrent() {
4545
public <V> V get(ContextKey<V> key) {
4646
if (OTEL_CONTEXT_SPAN_KEY.equals(key.toString())) {
4747
AgentSpan span = AgentSpan.fromContext(delegate);
48-
if (span != null) {
48+
if (span != null && span.isValid()) {
4949
return (V) toOtelSpan(span);
5050
}
5151
// fall-through and check for non-datadog span data
5252
} else if (OTEL_CONTEXT_ROOT_SPAN_KEY.equals(key.toString())) {
5353
AgentSpan span = AgentSpan.fromContext(delegate);
54-
if (span != null) {
54+
if (span != null && span.isValid()) {
5555
return (V) toOtelSpan(span.getLocalRootSpan());
5656
}
5757
// fall-through and check for non-datadog span data

dd-java-agent/instrumentation/opentelemetry/opentelemetry-1.4/src/test/groovy/opentelemetry14/context/ContextTest.groovy

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,33 @@ class ContextTest extends InstrumentationSpecification {
3232

3333
when:
3434
def currentSpan = Span.current()
35+
def currentSpanFromContext = Span.fromContext(Context.current())
36+
def currentSpanFromContextOrNull = Span.fromContextOrNull(Context.current())
3537

36-
then:
38+
then: "current span must be invalid or null"
3739
currentSpan != null
38-
currentSpan.spanContext.traceId == "00000000000000000000000000000000"
39-
currentSpan.spanContext.spanId == "0000000000000000"
40+
!currentSpan.spanContext.valid
41+
currentSpanFromContext != null
42+
!currentSpanFromContext.spanContext.valid
43+
currentSpanFromContextOrNull == null
4044

4145
when:
4246
def scope = otelSpan.makeCurrent()
4347
currentSpan = Span.current()
48+
currentSpanFromContext = Span.fromContext(Context.current())
49+
currentSpanFromContextOrNull = Span.fromContextOrNull(Context.current())
4450

45-
then:
51+
then: "OTel span must be current span"
4652
currentSpan == otelSpan
53+
currentSpanFromContext == otelSpan
54+
currentSpanFromContextOrNull == otelSpan
4755

4856
when:
4957
def ddSpan = TEST_TRACER.startSpan("dd-api", "other-name")
5058
def ddScope = TEST_TRACER.activateManualSpan(ddSpan)
5159
currentSpan = Span.current()
5260

53-
then:
61+
then: "Datadog span must be current span"
5462
currentSpan.spanContext.traceId == ddSpan.traceId.toHexString()
5563
currentSpan.spanContext.spanId == DDSpanId.toHexStringPadded(ddSpan.spanId)
5664

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package opentelemetry14.context.propagation
2+
3+
import datadog.trace.agent.test.InstrumentationSpecification
4+
import io.opentelemetry.api.GlobalOpenTelemetry
5+
import io.opentelemetry.api.trace.Span
6+
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
7+
import io.opentelemetry.context.propagation.TextMapPropagator
8+
9+
import static io.opentelemetry.context.Context.root
10+
11+
class MissingTraceContextPropagatorTest extends InstrumentationSpecification {
12+
@Override
13+
void configurePreAgent() {
14+
super.configurePreAgent()
15+
16+
injectSysConfig("dd.integration.opentelemetry.experimental.enabled", "true")
17+
}
18+
19+
def "extract on missing tracecontext should return an empty context"(TextMapPropagator propagator) {
20+
setup:
21+
def headers = ["User-Agent":"test"]
22+
23+
when:
24+
def context = propagator.extract(root(), headers, TextMap.INSTANCE)
25+
def extractedSpan = Span.fromContext(context)
26+
27+
then: "Should not have a valid tracing context"
28+
extractedSpan != null
29+
!extractedSpan.spanContext.valid
30+
Span.fromContextOrNull(context) == null
31+
32+
where:
33+
propagator << [
34+
GlobalOpenTelemetry.get().getPropagators().getTextMapPropagator(),
35+
W3CTraceContextPropagator.getInstance()
36+
]
37+
}
38+
}

0 commit comments

Comments
 (0)