Skip to content

Commit 38314d5

Browse files
Assumes that INVALID parent span id is actually null in TraceContext (#720)
* Assumes that INVALID parent span id is actually null in TraceContext - without this change we're returning an INVALID parent span even though we define in the javadocs of TraceContext that we would return null - with this change we're verifying whether the INVALID parent is set in which case we're returning null note: OTel doesn't store parent id for non sampled spans in which case we will return null fixes gh-687
1 parent ed9960d commit 38314d5

File tree

2 files changed

+96
-1
lines changed

2 files changed

+96
-1
lines changed

micrometer-tracing-bridges/micrometer-tracing-bridge-otel/src/main/java/io/micrometer/tracing/otel/bridge/OtelTraceContext.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,11 @@ public String parentId() {
119119
: this.span;
120120
if (spanContextSpanOrSpan instanceof ReadableSpan) {
121121
ReadableSpan readableSpan = (ReadableSpan) spanContextSpanOrSpan;
122-
return readableSpan.toSpanData().getParentSpanId();
122+
String parentSpanId = readableSpan.toSpanData().getParentSpanId();
123+
if (Objects.equals(Span.getInvalid().getSpanContext().getSpanId(), parentSpanId)) {
124+
return null;
125+
}
126+
return parentSpanId;
123127
}
124128
return null;
125129
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* Copyright 2024 the original author or authors.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
* <p>
7+
* https://www.apache.org/licenses/LICENSE-2.0
8+
* <p>
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License
10+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11+
* or implied. See the License for the specific language governing permissions and limitations under
12+
* the License.
13+
*/
14+
package io.micrometer.tracing.otel.bridge;
15+
16+
import io.opentelemetry.api.trace.Span;
17+
import io.opentelemetry.api.trace.Tracer;
18+
import io.opentelemetry.context.Context;
19+
import io.opentelemetry.sdk.OpenTelemetrySdk;
20+
import io.opentelemetry.sdk.OpenTelemetrySdkBuilder;
21+
import io.opentelemetry.sdk.trace.SdkTracerProvider;
22+
import org.junit.jupiter.api.Test;
23+
24+
import static org.assertj.core.api.BDDAssertions.then;
25+
26+
class OtelTraceContextTests {
27+
28+
SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
29+
.setSampler(io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn())
30+
.build();
31+
32+
OpenTelemetrySdkBuilder openTelemetrySdkBuilder = OpenTelemetrySdk.builder().setTracerProvider(sdkTracerProvider);
33+
34+
@Test
35+
void should_return_null_when_parent_invalid() {
36+
37+
try (OpenTelemetrySdk openTelemetrySdk = openTelemetrySdkBuilder.build()) {
38+
Tracer otelTracer = tracer(openTelemetrySdk);
39+
Span span = otelTracer.spanBuilder("foo").startSpan();
40+
41+
OtelTraceContext otelTraceContext = new OtelTraceContext(span);
42+
43+
then(otelTraceContext.parentId()).isNull();
44+
}
45+
46+
}
47+
48+
@Test
49+
void should_return_null_when_spans_not_sampled() { // works differently than Brave
50+
SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
51+
.setSampler(io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOff())
52+
.build();
53+
54+
OpenTelemetrySdkBuilder openTelemetrySdkBuilder = OpenTelemetrySdk.builder()
55+
.setTracerProvider(sdkTracerProvider);
56+
57+
try (OpenTelemetrySdk openTelemetrySdk = openTelemetrySdkBuilder.build()) {
58+
Tracer otelTracer = tracer(openTelemetrySdk);
59+
Span parentSpan = otelTracer.spanBuilder("parent").startSpan();
60+
Span span = otelTracer.spanBuilder("foo")
61+
.setParent(parentSpan.storeInContext(Context.current()))
62+
.startSpan();
63+
64+
OtelTraceContext otelTraceContext = new OtelTraceContext(span);
65+
66+
then(otelTraceContext.parentId()).isNull();
67+
}
68+
69+
}
70+
71+
@Test
72+
void should_return_parentid_when_parent_valid() {
73+
try (OpenTelemetrySdk openTelemetrySdk = openTelemetrySdkBuilder.build()) {
74+
Tracer otelTracer = tracer(openTelemetrySdk);
75+
Span parentSpan = otelTracer.spanBuilder("parent").startSpan();
76+
Span span = otelTracer.spanBuilder("foo")
77+
.setParent(parentSpan.storeInContext(Context.current()))
78+
.startSpan();
79+
80+
OtelTraceContext otelTraceContext = new OtelTraceContext(span);
81+
82+
then(otelTraceContext.parentId()).isEqualTo(parentSpan.getSpanContext().getSpanId());
83+
}
84+
85+
}
86+
87+
private static Tracer tracer(OpenTelemetrySdk openTelemetrySdk) {
88+
return openTelemetrySdk.getTracer("io.micrometer.micrometer-tracing");
89+
}
90+
91+
}

0 commit comments

Comments
 (0)