Skip to content

Commit a634b91

Browse files
authored
[3.x] - Add baggage to Helidon Span (helidon-io#6692)
* Add baggage to Helidon Span
1 parent 0e282b5 commit a634b91

6 files changed

Lines changed: 171 additions & 28 deletions

File tree

dependencies/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@
133133
<version.lib.database.messaging>19.3.0.0</version.lib.database.messaging>
134134
<version.lib.okhttp3>3.14.9</version.lib.okhttp3>
135135
<version.lib.okio>1.17.5</version.lib.okio>
136-
<version.lib.opentelemetry>1.15.0</version.lib.opentelemetry>
137-
<version.lib.opentelemetry.semconv>1.15.0-alpha</version.lib.opentelemetry.semconv>
138-
<version.lib.opentelemetry.opentracing.shim>1.15.0-alpha</version.lib.opentelemetry.opentracing.shim>
136+
<version.lib.opentelemetry>1.22.0</version.lib.opentelemetry>
137+
<version.lib.opentelemetry.semconv>1.22.0-alpha</version.lib.opentelemetry.semconv>
138+
<version.lib.opentelemetry.opentracing.shim>1.22.0-alpha</version.lib.opentelemetry.opentracing.shim>
139139
<version.lib.opentracing>0.33.0</version.lib.opentracing>
140140
<version.lib.opentracing.grpc>0.2.1</version.lib.opentracing.grpc>
141141
<version.lib.opentracing.tracerresolver>0.1.8</version.lib.opentracing.tracerresolver>

tracing/opentelemetry/src/main/java/io/helidon/tracing/opentelemetry/OpenTelemetrySpan.java

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022 Oracle and/or its affiliates.
2+
* Copyright (c) 2022, 2023 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,40 +16,47 @@
1616
package io.helidon.tracing.opentelemetry;
1717

1818
import java.util.Map;
19+
import java.util.Objects;
20+
import java.util.Optional;
1921

22+
import io.helidon.common.context.Contexts;
2023
import io.helidon.tracing.Scope;
24+
import io.helidon.tracing.Span;
2125
import io.helidon.tracing.SpanContext;
2226

27+
import io.opentelemetry.api.baggage.Baggage;
2328
import io.opentelemetry.api.common.Attributes;
2429
import io.opentelemetry.api.common.AttributesBuilder;
25-
import io.opentelemetry.api.trace.Span;
2630
import io.opentelemetry.api.trace.StatusCode;
2731
import io.opentelemetry.context.Context;
2832

29-
class OpenTelemetrySpan implements io.helidon.tracing.Span {
30-
private final Span delegate;
33+
class OpenTelemetrySpan implements Span {
34+
private final io.opentelemetry.api.trace.Span delegate;
3135

32-
OpenTelemetrySpan(Span span) {
36+
OpenTelemetrySpan(io.opentelemetry.api.trace.Span span) {
3337
this.delegate = span;
3438
}
3539

3640
@Override
37-
public void tag(String key, String value) {
41+
public Span tag(String key, String value) {
3842
delegate.setAttribute(key, value);
43+
return this;
3944
}
4045

4146
@Override
42-
public void tag(String key, Boolean value) {
47+
public Span tag(String key, Boolean value) {
4348
delegate.setAttribute(key, value);
49+
return this;
4450
}
4551

4652
@Override
47-
public void tag(String key, Number value) {
53+
public Span tag(String key, Number value) {
4854
if (value instanceof Double || value instanceof Float) {
4955
delegate.setAttribute(key, value.doubleValue());
5056
} else {
5157
delegate.setAttribute(key, value.longValue());
5258
}
59+
return this;
5360
}
5461

5562
@Override
@@ -89,6 +96,33 @@ public Scope activate() {
8996
return new OpenTelemetryScope(delegate.makeCurrent());
9097
}
9198

99+
@Override
100+
public Span baggage(String key, String value) {
101+
Objects.requireNonNull(key, "Baggage Key cannot be null");
102+
Objects.requireNonNull(value, "Baggage Value cannot be null");
103+
104+
Baggage.builder()
105+
.put(key, value)
106+
.build()
107+
.storeInContext(getContext())
108+
.makeCurrent();
109+
return this;
110+
}
111+
112+
@Override
113+
public Optional<String> baggage(String key) {
114+
Objects.requireNonNull(key, "Baggage Key cannot be null");
115+
return Optional.ofNullable(Baggage.fromContext(getContext()).getEntryValue(key));
116+
}
117+
118+
// Check if OTEL Context is already available in Global Helidon Context.
119+
// If not – use Current context.
120+
private static Context getContext() {
121+
return Contexts.context()
122+
.flatMap(ctx -> ctx.get(Context.class))
123+
.orElseGet(Context::current);
124+
}
125+
92126
private Attributes toAttributes(Map<String, ?> attributes) {
93127
AttributesBuilder builder = Attributes.builder();
94128
attributes.forEach((key, value) -> {
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (c) 2023 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.helidon.tracing.opentelemetery;
18+
19+
import java.util.Optional;
20+
21+
import io.helidon.tracing.Span;
22+
import io.helidon.tracing.Tracer;
23+
import io.helidon.tracing.TracerBuilder;
24+
25+
import org.junit.jupiter.api.Test;
26+
27+
import static org.hamcrest.MatcherAssert.assertThat;
28+
import static org.hamcrest.core.Is.is;
29+
import static org.hamcrest.core.IsEqual.equalTo;
30+
import static org.junit.jupiter.api.Assertions.assertThrows;
31+
32+
/**
33+
* Test if baggage is handled correctly.
34+
*/
35+
class BaggageTest {
36+
37+
private final Tracer tracer = TracerBuilder.create("test-service").registerGlobal(false).build();
38+
39+
@Test
40+
void testBaggage(){
41+
Span span = tracer.spanBuilder("test-span").start();
42+
Span spanWithBaggage = span.baggage("key", "value");
43+
Optional<String> result = spanWithBaggage.baggage("key");
44+
span.end();
45+
assertThat(result.isPresent(), is(true));
46+
assertThat(result.get(), equalTo("value"));
47+
}
48+
49+
@Test
50+
void testBadBaggage(){
51+
Span span = tracer.spanBuilder("test-bad-span").start();
52+
assertThrows(NullPointerException.class, () -> span.baggage(null, "value"));
53+
assertThrows(NullPointerException.class, () -> span.baggage("key", null));
54+
assertThrows(NullPointerException.class, () -> span.baggage(null, null));
55+
}
56+
}

tracing/opentracing/src/main/java/io/helidon/tracing/opentracing/OpenTracingSpan.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022 Oracle and/or its affiliates.
2+
* Copyright (c) 2022, 2023 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,8 @@
1717

1818
import java.util.HashMap;
1919
import java.util.Map;
20+
import java.util.Objects;
21+
import java.util.Optional;
2022

2123
import io.helidon.tracing.Scope;
2224
import io.helidon.tracing.Span;
@@ -38,18 +40,21 @@ class OpenTracingSpan implements Span {
3840

3941

4042
@Override
41-
public void tag(String key, String value) {
43+
public Span tag(String key, String value) {
4244
delegate.setTag(key, value);
45+
return this;
4346
}
4447

4548
@Override
46-
public void tag(String key, Boolean value) {
49+
public Span tag(String key, Boolean value) {
4750
delegate.setTag(key, value);
51+
return this;
4852
}
4953

5054
@Override
51-
public void tag(String key, Number value) {
55+
public Span tag(String key, Number value) {
5256
delegate.setTag(key, value);
57+
return this;
5358
}
5459

5560
@Override
@@ -91,6 +96,22 @@ public Scope activate() {
9196
return new OpenTracingScope(tracer.activateSpan(delegate));
9297
}
9398

99+
@Override
100+
public Span baggage(String key, String value) {
101+
Objects.requireNonNull(key, "Baggage Key cannot be null");
102+
Objects.requireNonNull(value, "Baggage Value cannot be null");
103+
104+
delegate.setBaggageItem(key, value);
105+
return this;
106+
}
107+
108+
@Override
109+
public Optional<String> baggage(String key) {
110+
Objects.requireNonNull(key, "Baggage Key cannot be null");
111+
112+
return Optional.ofNullable(delegate.getBaggageItem(key));
113+
}
114+
94115
@Override
95116
public <T> T unwrap(Class<T> spanClass) {
96117
if (spanClass.isAssignableFrom(delegate.getClass())) {

tracing/tracing/src/main/java/io/helidon/tracing/NoOpTracer.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022 Oracle and/or its affiliates.
2+
* Copyright (c) 2022, 2023 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -96,18 +96,18 @@ public Span start(Instant instant) {
9696
private static class Span implements io.helidon.tracing.Span {
9797

9898
@Override
99-
public void tag(String key, String value) {
100-
99+
public io.helidon.tracing.Span tag(String key, String value) {
100+
return this;
101101
}
102102

103103
@Override
104-
public void tag(String key, Boolean value) {
105-
104+
public io.helidon.tracing.Span tag(String key, Boolean value) {
105+
return this;
106106
}
107107

108108
@Override
109-
public void tag(String key, Number value) {
110-
109+
public io.helidon.tracing.Span tag(String key, Number value) {
110+
return this;
111111
}
112112

113113
@Override
@@ -133,9 +133,19 @@ public void end(Throwable t) {
133133
}
134134

135135
@Override
136-
public io.helidon.tracing.Scope activate() {
136+
public Scope activate() {
137137
return SCOPE;
138138
}
139+
140+
@Override
141+
public Span baggage(String key, String value) {
142+
return this;
143+
}
144+
145+
@Override
146+
public Optional<String> baggage(String key) {
147+
return Optional.empty();
148+
}
139149
}
140150

141151
private static class SpanContext implements io.helidon.tracing.SpanContext {

tracing/tracing/src/main/java/io/helidon/tracing/Span.java

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022 Oracle and/or its affiliates.
2+
* Copyright (c) 2022, 2023 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,34 +43,39 @@ static Optional<Span> current() {
4343
* Add a tag to this span.
4444
*
4545
* @param tag tag to add
46+
* @return current span
4647
*/
47-
default void tag(Tag<?> tag) {
48+
default Span tag(Tag<?> tag) {
4849
tag.apply(this);
50+
return this;
4951
}
5052

5153
/**
5254
* Add a string tag.
5355
*
5456
* @param key tag key
5557
* @param value tag value
58+
* @return current span
5659
*/
57-
void tag(String key, String value);
60+
Span tag(String key, String value);
5861

5962
/**
6063
* Add a boolean tag.
6164
*
6265
* @param key tag key
6366
* @param value tag value
67+
* @return current span
6468
*/
65-
void tag(String key, Boolean value);
69+
Span tag(String key, Boolean value);
6670

6771
/**
6872
* Add a numeric tag.
6973
*
7074
* @param key tag key
7175
* @param value tag value
76+
* @return current span
7277
*/
73-
void tag(String key, Number value);
78+
Span tag(String key, Number value);
7479

7580
/**
7681
* Span status, mostly used to configure {@link Status#ERROR}.
@@ -116,6 +121,23 @@ default void tag(Tag<?> tag) {
116121
*/
117122
Scope activate();
118123

124+
/**
125+
* Sets a baggage item in the Span (and its SpanContext) as a key/value pair.
126+
*
127+
* @param key String Key
128+
* @param value String Value
129+
* @return current Span instance
130+
*/
131+
Span baggage(String key, String value);
132+
133+
/**
134+
* Get Baggage Item by key.
135+
*
136+
* @param key String key
137+
* @return {@link Optional} of the value of the baggage item
138+
*/
139+
Optional<String> baggage(String key);
140+
119141
/**
120142
* Add a new event to this span.
121143
*

0 commit comments

Comments
 (0)