diff --git a/micrometer-tracing-bridges/micrometer-tracing-bridge-otel/src/main/java/io/micrometer/tracing/otel/bridge/OtelBaggageInScope.java b/micrometer-tracing-bridges/micrometer-tracing-bridge-otel/src/main/java/io/micrometer/tracing/otel/bridge/OtelBaggageInScope.java index f2c295f7..d3ff60e2 100644 --- a/micrometer-tracing-bridges/micrometer-tracing-bridge-otel/src/main/java/io/micrometer/tracing/otel/bridge/OtelBaggageInScope.java +++ b/micrometer-tracing-bridges/micrometer-tracing-bridge-otel/src/main/java/io/micrometer/tracing/otel/bridge/OtelBaggageInScope.java @@ -43,6 +43,8 @@ class OtelBaggageInScope implements io.micrometer.tracing.Baggage, BaggageInScop private final AtomicReference entry = new AtomicReference<>(); + private final AtomicReference contextWithBaggage = new AtomicReference<>(null); + private final AtomicReference scope = new AtomicReference<>(); OtelBaggageInScope(OtelBaggageManager otelBaggageManager, CurrentTraceContext currentTraceContext, @@ -73,17 +75,18 @@ public String get(TraceContext traceContext) { } @Override + @Deprecated public io.micrometer.tracing.Baggage set(String value) { return doSet(this.currentTraceContext.context(), value); } private io.micrometer.tracing.Baggage doSet(TraceContext context, String value) { - Context current = Context.current(); - Span currentSpan = Span.current(); - io.opentelemetry.api.baggage.Baggage baggage; if (context == null) { return this; } + Context current = Context.current(); + Span currentSpan = Span.current(); + io.opentelemetry.api.baggage.Baggage baggage; OtelTraceContext ctx = (OtelTraceContext) context; Context storedCtx = ctx.context(); Baggage fromContext = Baggage.fromContext(storedCtx); @@ -97,7 +100,7 @@ private io.micrometer.tracing.Baggage doSet(TraceContext context, String value) current = current.with(baggage); Context withBaggage = current.with(baggage); ctx.updateContext(withBaggage); - this.scope.set(withBaggage.makeCurrent()); + contextWithBaggage.set(withBaggage); if (this.tagFields.stream().map(String::toLowerCase).anyMatch(s -> s.equals(entry().getKey()))) { currentSpan.setAttribute(entry().getKey(), value); } @@ -111,21 +114,24 @@ private Entry entry() { } @Override + @Deprecated public io.micrometer.tracing.Baggage set(TraceContext traceContext, String value) { return doSet(traceContext, value); } @Override public BaggageInScope makeCurrent() { - if (this.scope.get() == null) { - return this; - } - close(); Entry entry = entry(); - Scope scope = Baggage.builder() + Context context = contextWithBaggage.get(); + if (context == null) { + context = Context.current(); + } + Baggage baggage = Baggage.fromContext(context) + .toBuilder() .put(entry.getKey(), entry.getValue(), entry.getMetadata()) - .build() - .makeCurrent(); + .build(); + Context updated = context.with(baggage); + Scope scope = updated.makeCurrent(); this.scope.set(scope); return this; } diff --git a/micrometer-tracing-bridges/micrometer-tracing-bridge-otel/src/test/java/io/micrometer/tracing/otel/bridge/BaggageTests.java b/micrometer-tracing-bridges/micrometer-tracing-bridge-otel/src/test/java/io/micrometer/tracing/otel/bridge/BaggageTests.java index 6f88941a..55d71c6a 100644 --- a/micrometer-tracing-bridges/micrometer-tracing-bridge-otel/src/test/java/io/micrometer/tracing/otel/bridge/BaggageTests.java +++ b/micrometer-tracing-bridges/micrometer-tracing-bridge-otel/src/test/java/io/micrometer/tracing/otel/bridge/BaggageTests.java @@ -48,6 +48,10 @@ class BaggageTests { public static final String VALUE_1 = "value1"; + public static final String KEY_2 = "key2"; + + public static final String VALUE_2 = "value2"; + SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() .setSampler(io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn()) .build(); @@ -79,10 +83,12 @@ void canSetAndGetBaggage() { Span span = tracer.nextSpan().start(); try (Tracer.SpanInScope spanInScope = tracer.withSpan(span)) { // WHEN - this.tracer.getBaggage(KEY_1).set(VALUE_1); - - // THEN - then(tracer.getBaggage(KEY_1).get()).isEqualTo(VALUE_1); + try (BaggageInScope bs1 = this.tracer.createBaggage(KEY_1, VALUE_1).makeCurrent(); + BaggageInScope bs2 = this.tracer.createBaggage(KEY_2, VALUE_2).makeCurrent()) { + // THEN + then(tracer.getBaggage(KEY_1).get()).isEqualTo(VALUE_1); + then(tracer.getBaggage(KEY_2).get()).isEqualTo(VALUE_2); + } } } @@ -93,13 +99,14 @@ void injectAndExtractKeepsTheBaggage() { Span span = tracer.nextSpan().start(); try (Tracer.SpanInScope spanInScope = tracer.withSpan(span)) { - this.tracer.createBaggage(KEY_1, VALUE_1); + try (BaggageInScope scope = this.tracer.createBaggage(KEY_1, VALUE_1).makeCurrent()) { + // WHEN + this.propagator.inject(tracer.currentTraceContext().context(), carrier, Map::put); - // WHEN - this.propagator.inject(tracer.currentTraceContext().context(), carrier, Map::put); + // THEN + then(carrier.get(KEY_1)).isEqualTo(VALUE_1); + } - // THEN - then(carrier.get(KEY_1)).isEqualTo(VALUE_1); } // WHEN diff --git a/micrometer-tracing-bridges/micrometer-tracing-bridge-otel/src/test/java/io/micrometer/tracing/otel/bridge/OtelTracingApiTests.java b/micrometer-tracing-bridges/micrometer-tracing-bridge-otel/src/test/java/io/micrometer/tracing/otel/bridge/OtelTracingApiTests.java index 27135f8a..23c11190 100644 --- a/micrometer-tracing-bridges/micrometer-tracing-bridge-otel/src/test/java/io/micrometer/tracing/otel/bridge/OtelTracingApiTests.java +++ b/micrometer-tracing-bridges/micrometer-tracing-bridge-otel/src/test/java/io/micrometer/tracing/otel/bridge/OtelTracingApiTests.java @@ -206,11 +206,13 @@ void should_work_with_baggage() { // Assuming that there's no span in scope Baggage baggageFour = tracer.createBaggage("from_span_in_scope 1", "value 1"); - // When there's no span in scope, there will never be any baggage - even if you - // make it current + then(tracer.currentSpan()).isNull(); + + // When there's no span in scope, baggage can still be there (that's incosistent + // with Brave) try (BaggageInScope baggage = baggageFour.makeCurrent()) { - then(baggageFour.get()).as("[Out of span scope] Baggage 1").isNull(); - then(tracer.getBaggage("from_span_in_scope 1").get()).as("[Out of span scope] Baggage 1").isNull(); + then(baggage.get()).as("[Out of span scope] Baggage 1").isNotNull(); + then(tracer.getBaggage("from_span_in_scope 1").get()).as("[Out of span scope] Baggage 1").isNotNull(); } then(tracer.getBaggage("from_span_in_scope 1").get()).as("[Out of scope] Baggage 1").isNull(); then(tracer.getBaggage("from_span_in_scope 2").get()).as("[Out of scope] Baggage 2").isNull();