From 02347abefb6aab7f386b7cc629ff48e2a3437b5c Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Tue, 5 Dec 2023 10:58:04 +0100 Subject: [PATCH] Disable propagation of traces if tracing is disabled Closes gh-38641 --- .../tracing/BraveAutoConfiguration.java | 125 +----------- .../BravePropagationConfigurations.java | 178 ++++++++++++++++++ .../tracing/CompositePropagationFactory.java | 9 + .../OpenTelemetryAutoConfiguration.java | 47 +---- ...penTelemetryPropagationConfigurations.java | 105 +++++++++++ .../tracing/BraveAutoConfigurationTests.java | 10 + .../OpenTelemetryAutoConfigurationTests.java | 9 + 7 files changed, 320 insertions(+), 163 deletions(-) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BravePropagationConfigurations.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryPropagationConfigurations.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java index 47d65fe69cbc..9e1c8a6bd413 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfiguration.java @@ -24,22 +24,10 @@ import brave.Tracing; import brave.Tracing.Builder; import brave.TracingCustomizer; -import brave.baggage.BaggageField; -import brave.baggage.BaggagePropagation; -import brave.baggage.BaggagePropagation.FactoryBuilder; -import brave.baggage.BaggagePropagationConfig; -import brave.baggage.BaggagePropagationCustomizer; -import brave.baggage.CorrelationScopeConfig.SingleCorrelationField; -import brave.baggage.CorrelationScopeCustomizer; -import brave.baggage.CorrelationScopeDecorator; -import brave.context.slf4j.MDCScopeDecorator; import brave.handler.SpanHandler; import brave.propagation.CurrentTraceContext; -import brave.propagation.CurrentTraceContext.ScopeDecorator; import brave.propagation.CurrentTraceContextCustomizer; -import brave.propagation.Propagation; import brave.propagation.Propagation.Factory; -import brave.propagation.Propagation.KeyFactory; import brave.propagation.ThreadLocalCurrentTraceContext; import brave.sampler.Sampler; import io.micrometer.tracing.brave.bridge.BraveBaggageManager; @@ -53,17 +41,15 @@ import io.micrometer.tracing.exporter.SpanReporter; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Baggage.Correlation; import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Propagation.PropagationType; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.IncompatibleConfigurationException; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.core.env.Environment; @@ -79,9 +65,12 @@ @AutoConfiguration(before = MicrometerTracingAutoConfiguration.class) @ConditionalOnClass({ Tracer.class, BraveTracer.class }) @EnableConfigurationProperties(TracingProperties.class) +@Import({ BravePropagationConfigurations.PropagationWithoutBaggage.class, + BravePropagationConfigurations.PropagationWithBaggage.class, + BravePropagationConfigurations.NoPropagation.class }) public class BraveAutoConfiguration { - private static final BraveBaggageManager BRAVE_BAGGAGE_MANAGER = new BraveBaggageManager(); + static final BraveBaggageManager BRAVE_BAGGAGE_MANAGER = new BraveBaggageManager(); /** * Default value for application name if {@code spring.application.name} is not set. @@ -182,108 +171,4 @@ BraveSpanCustomizer braveSpanCustomizer(SpanCustomizer spanCustomizer) { return new BraveSpanCustomizer(spanCustomizer); } - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(value = "management.tracing.baggage.enabled", havingValue = "false") - static class BraveNoBaggageConfiguration { - - @Bean - @ConditionalOnMissingBean - Factory propagationFactory(TracingProperties properties) { - return CompositePropagationFactory.create(properties.getPropagation()); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(value = "management.tracing.baggage.enabled", matchIfMissing = true) - static class BraveBaggageConfiguration { - - private final TracingProperties tracingProperties; - - BraveBaggageConfiguration(TracingProperties tracingProperties) { - this.tracingProperties = tracingProperties; - } - - @Bean - @ConditionalOnMissingBean - BaggagePropagation.FactoryBuilder propagationFactoryBuilder( - ObjectProvider baggagePropagationCustomizers) { - // There's a chicken-and-egg problem here: to create a builder, we need a - // factory. But the CompositePropagationFactory needs data from the builder. - // We create a throw-away builder with a throw-away factory, and then copy the - // config to the real builder. - FactoryBuilder throwAwayBuilder = BaggagePropagation.newFactoryBuilder(createThrowAwayFactory()); - baggagePropagationCustomizers.orderedStream() - .forEach((customizer) -> customizer.customize(throwAwayBuilder)); - CompositePropagationFactory propagationFactory = CompositePropagationFactory.create( - this.tracingProperties.getPropagation(), BRAVE_BAGGAGE_MANAGER, - LocalBaggageFields.extractFrom(throwAwayBuilder)); - FactoryBuilder builder = BaggagePropagation.newFactoryBuilder(propagationFactory); - throwAwayBuilder.configs().forEach(builder::add); - return builder; - } - - @SuppressWarnings("deprecation") - private Factory createThrowAwayFactory() { - return new Factory() { - - @Override - public Propagation create(KeyFactory keyFactory) { - return null; - } - - }; - } - - @Bean - @Order(0) - BaggagePropagationCustomizer remoteFieldsBaggagePropagationCustomizer() { - return (builder) -> { - List remoteFields = this.tracingProperties.getBaggage().getRemoteFields(); - for (String fieldName : remoteFields) { - builder.add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create(fieldName))); - } - }; - } - - @Bean - @ConditionalOnMissingBean - Factory propagationFactory(BaggagePropagation.FactoryBuilder factoryBuilder) { - return factoryBuilder.build(); - } - - @Bean - @ConditionalOnMissingBean - CorrelationScopeDecorator.Builder mdcCorrelationScopeDecoratorBuilder( - ObjectProvider correlationScopeCustomizers) { - CorrelationScopeDecorator.Builder builder = MDCScopeDecorator.newBuilder(); - correlationScopeCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); - return builder; - } - - @Bean - @Order(0) - @ConditionalOnProperty(prefix = "management.tracing.baggage.correlation", name = "enabled", - matchIfMissing = true) - CorrelationScopeCustomizer correlationFieldsCorrelationScopeCustomizer() { - return (builder) -> { - Correlation correlationProperties = this.tracingProperties.getBaggage().getCorrelation(); - for (String field : correlationProperties.getFields()) { - BaggageField baggageField = BaggageField.create(field); - SingleCorrelationField correlationField = SingleCorrelationField.newBuilder(baggageField) - .flushOnUpdate() - .build(); - builder.add(correlationField); - } - }; - } - - @Bean - @ConditionalOnMissingBean(CorrelationScopeDecorator.class) - ScopeDecorator correlationScopeDecorator(CorrelationScopeDecorator.Builder builder) { - return builder.build(); - } - - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BravePropagationConfigurations.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BravePropagationConfigurations.java new file mode 100644 index 000000000000..17bc93021945 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/BravePropagationConfigurations.java @@ -0,0 +1,178 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.tracing; + +import java.util.List; + +import brave.baggage.BaggageField; +import brave.baggage.BaggagePropagation; +import brave.baggage.BaggagePropagation.FactoryBuilder; +import brave.baggage.BaggagePropagationConfig; +import brave.baggage.BaggagePropagationCustomizer; +import brave.baggage.CorrelationScopeConfig.SingleCorrelationField; +import brave.baggage.CorrelationScopeCustomizer; +import brave.baggage.CorrelationScopeDecorator; +import brave.context.slf4j.MDCScopeDecorator; +import brave.propagation.CurrentTraceContext.ScopeDecorator; +import brave.propagation.Propagation; +import brave.propagation.Propagation.Factory; +import brave.propagation.Propagation.KeyFactory; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.actuate.autoconfigure.tracing.TracingProperties.Baggage.Correlation; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +/** + * Brave propagation configurations. They are imported by {@link BraveAutoConfiguration}. + * + * @author Moritz Halbritter + */ +class BravePropagationConfigurations { + + /** + * Propagates traces but no baggage. + */ + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(value = "management.tracing.baggage.enabled", havingValue = "false") + static class PropagationWithoutBaggage { + + @Bean + @ConditionalOnMissingBean(Factory.class) + @ConditionalOnEnabledTracing + CompositePropagationFactory propagationFactory(TracingProperties properties) { + return CompositePropagationFactory.create(properties.getPropagation()); + } + + } + + /** + * Propagates traces and baggage. + */ + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(value = "management.tracing.baggage.enabled", matchIfMissing = true) + @EnableConfigurationProperties(TracingProperties.class) + static class PropagationWithBaggage { + + private final TracingProperties tracingProperties; + + PropagationWithBaggage(TracingProperties tracingProperties) { + this.tracingProperties = tracingProperties; + } + + @Bean + @ConditionalOnMissingBean + BaggagePropagation.FactoryBuilder propagationFactoryBuilder( + ObjectProvider baggagePropagationCustomizers) { + // There's a chicken-and-egg problem here: to create a builder, we need a + // factory. But the CompositePropagationFactory needs data from the builder. + // We create a throw-away builder with a throw-away factory, and then copy the + // config to the real builder. + FactoryBuilder throwAwayBuilder = BaggagePropagation.newFactoryBuilder(createThrowAwayFactory()); + baggagePropagationCustomizers.orderedStream() + .forEach((customizer) -> customizer.customize(throwAwayBuilder)); + CompositePropagationFactory propagationFactory = CompositePropagationFactory.create( + this.tracingProperties.getPropagation(), BraveAutoConfiguration.BRAVE_BAGGAGE_MANAGER, + LocalBaggageFields.extractFrom(throwAwayBuilder)); + FactoryBuilder builder = BaggagePropagation.newFactoryBuilder(propagationFactory); + throwAwayBuilder.configs().forEach(builder::add); + return builder; + } + + @SuppressWarnings("deprecation") + private Factory createThrowAwayFactory() { + return new Factory() { + + @Override + public Propagation create(KeyFactory keyFactory) { + return null; + } + + }; + } + + @Bean + @Order(0) + BaggagePropagationCustomizer remoteFieldsBaggagePropagationCustomizer() { + return (builder) -> { + List remoteFields = this.tracingProperties.getBaggage().getRemoteFields(); + for (String fieldName : remoteFields) { + builder.add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create(fieldName))); + } + }; + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnEnabledTracing + Factory propagationFactory(BaggagePropagation.FactoryBuilder factoryBuilder) { + return factoryBuilder.build(); + } + + @Bean + @ConditionalOnMissingBean + CorrelationScopeDecorator.Builder mdcCorrelationScopeDecoratorBuilder( + ObjectProvider correlationScopeCustomizers) { + CorrelationScopeDecorator.Builder builder = MDCScopeDecorator.newBuilder(); + correlationScopeCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); + return builder; + } + + @Bean + @Order(0) + @ConditionalOnProperty(prefix = "management.tracing.baggage.correlation", name = "enabled", + matchIfMissing = true) + CorrelationScopeCustomizer correlationFieldsCorrelationScopeCustomizer() { + return (builder) -> { + Correlation correlationProperties = this.tracingProperties.getBaggage().getCorrelation(); + for (String field : correlationProperties.getFields()) { + BaggageField baggageField = BaggageField.create(field); + SingleCorrelationField correlationField = SingleCorrelationField.newBuilder(baggageField) + .flushOnUpdate() + .build(); + builder.add(correlationField); + } + }; + } + + @Bean + @ConditionalOnMissingBean(CorrelationScopeDecorator.class) + ScopeDecorator correlationScopeDecorator(CorrelationScopeDecorator.Builder builder) { + return builder.build(); + } + + } + + /** + * Propagates neither traces nor baggage. + */ + @Configuration(proxyBeanMethods = false) + static class NoPropagation { + + @Bean + @ConditionalOnMissingBean(Factory.class) + CompositePropagationFactory noopPropagationFactory() { + return CompositePropagationFactory.noop(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactory.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactory.java index 4e3b09b1e915..14ec2aea1e66 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactory.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/CompositePropagationFactory.java @@ -17,6 +17,7 @@ package org.springframework.boot.actuate.autoconfigure.tracing; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.function.Predicate; import java.util.stream.Stream; @@ -84,6 +85,14 @@ public TraceContext decorate(TraceContext context) { .orElse(context); } + /** + * Creates a new {@link CompositePropagationFactory} which doesn't do any propagation. + * @return the {@link CompositePropagationFactory} + */ + static CompositePropagationFactory noop() { + return new CompositePropagationFactory(Collections.emptyList(), Collections.emptyList()); + } + /** * Creates a new {@link CompositePropagationFactory}. * @param properties the propagation properties diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java index 92e75afc0761..9673ec0f25fe 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfiguration.java @@ -32,9 +32,7 @@ import io.micrometer.tracing.otel.bridge.OtelSpanCustomizer; import io.micrometer.tracing.otel.bridge.OtelTracer; import io.micrometer.tracing.otel.bridge.OtelTracer.EventPublisher; -import io.micrometer.tracing.otel.bridge.Slf4JBaggageEventListener; import io.micrometer.tracing.otel.bridge.Slf4JEventListener; -import io.micrometer.tracing.otel.propagation.BaggageTextMapPropagator; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.api.trace.Tracer; @@ -56,10 +54,9 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; /** * {@link EnableAutoConfiguration Auto-configuration} for OpenTelemetry tracing. @@ -72,6 +69,9 @@ @AutoConfiguration(value = "openTelemetryTracingAutoConfiguration", before = MicrometerTracingAutoConfiguration.class) @ConditionalOnClass({ OtelTracer.class, SdkTracerProvider.class, OpenTelemetry.class }) @EnableConfigurationProperties(TracingProperties.class) +@Import({ OpenTelemetryPropagationConfigurations.PropagationWithoutBaggage.class, + OpenTelemetryPropagationConfigurations.PropagationWithBaggage.class, + OpenTelemetryPropagationConfigurations.NoPropagation.class }) public class OpenTelemetryAutoConfiguration { private final TracingProperties tracingProperties; @@ -172,45 +172,6 @@ OtelSpanCustomizer otelSpanCustomizer() { return new OtelSpanCustomizer(); } - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(prefix = "management.tracing.baggage", name = "enabled", matchIfMissing = true) - static class BaggageConfiguration { - - private final TracingProperties tracingProperties; - - BaggageConfiguration(TracingProperties tracingProperties) { - this.tracingProperties = tracingProperties; - } - - @Bean - TextMapPropagator textMapPropagatorWithBaggage(OtelCurrentTraceContext otelCurrentTraceContext) { - List remoteFields = this.tracingProperties.getBaggage().getRemoteFields(); - BaggageTextMapPropagator baggagePropagator = new BaggageTextMapPropagator(remoteFields, - new OtelBaggageManager(otelCurrentTraceContext, remoteFields, Collections.emptyList())); - return CompositeTextMapPropagator.create(this.tracingProperties.getPropagation(), baggagePropagator); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnProperty(prefix = "management.tracing.baggage.correlation", name = "enabled", - matchIfMissing = true) - Slf4JBaggageEventListener otelSlf4JBaggageEventListener() { - return new Slf4JBaggageEventListener(this.tracingProperties.getBaggage().getCorrelation().getFields()); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(prefix = "management.tracing.baggage", name = "enabled", havingValue = "false") - static class NoBaggageConfiguration { - - @Bean - TextMapPropagator textMapPropagator(TracingProperties properties) { - return CompositeTextMapPropagator.create(properties.getPropagation(), null); - } - - } - static class OTelEventPublisher implements EventPublisher { private final List listeners; diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryPropagationConfigurations.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryPropagationConfigurations.java new file mode 100644 index 000000000000..4b9fcad16613 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryPropagationConfigurations.java @@ -0,0 +1,105 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.tracing; + +import java.util.Collections; +import java.util.List; + +import io.micrometer.tracing.otel.bridge.OtelBaggageManager; +import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext; +import io.micrometer.tracing.otel.bridge.Slf4JBaggageEventListener; +import io.micrometer.tracing.otel.propagation.BaggageTextMapPropagator; +import io.opentelemetry.context.propagation.TextMapPropagator; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * OpenTelemetry propagation configurations. They are imported by + * {@link OpenTelemetryAutoConfiguration}. + * + * @author Moritz Halbritter + */ +class OpenTelemetryPropagationConfigurations { + + /** + * Propagates traces but no baggage. + */ + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(prefix = "management.tracing.baggage", name = "enabled", havingValue = "false") + @EnableConfigurationProperties(TracingProperties.class) + static class PropagationWithoutBaggage { + + @Bean + @ConditionalOnEnabledTracing + TextMapPropagator textMapPropagator(TracingProperties properties) { + return CompositeTextMapPropagator.create(properties.getPropagation(), null); + } + + } + + /** + * Propagates traces and baggage. + */ + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(prefix = "management.tracing.baggage", name = "enabled", matchIfMissing = true) + @EnableConfigurationProperties(TracingProperties.class) + static class PropagationWithBaggage { + + private final TracingProperties tracingProperties; + + PropagationWithBaggage(TracingProperties tracingProperties) { + this.tracingProperties = tracingProperties; + } + + @Bean + @ConditionalOnEnabledTracing + TextMapPropagator textMapPropagatorWithBaggage(OtelCurrentTraceContext otelCurrentTraceContext) { + List remoteFields = this.tracingProperties.getBaggage().getRemoteFields(); + BaggageTextMapPropagator baggagePropagator = new BaggageTextMapPropagator(remoteFields, + new OtelBaggageManager(otelCurrentTraceContext, remoteFields, Collections.emptyList())); + return CompositeTextMapPropagator.create(this.tracingProperties.getPropagation(), baggagePropagator); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnProperty(prefix = "management.tracing.baggage.correlation", name = "enabled", + matchIfMissing = true) + Slf4JBaggageEventListener otelSlf4JBaggageEventListener() { + return new Slf4JBaggageEventListener(this.tracingProperties.getBaggage().getCorrelation().getFields()); + } + + } + + /** + * Propagates neither traces nor baggage. + */ + @Configuration(proxyBeanMethods = false) + static class NoPropagation { + + @Bean + @ConditionalOnMissingBean + TextMapPropagator noopTextMapPropagator() { + return TextMapPropagator.noop(); + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java index 1637f2901289..246a6a184c10 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/BraveAutoConfigurationTests.java @@ -344,6 +344,16 @@ void compositeSpanHandlerUsesFilterPredicateAndReportersInOrder() { }); } + @Test + void shouldDisablePropagationIfTracingIsDisabled() { + this.contextRunner.withPropertyValues("management.tracing.enabled=false").run((context) -> { + assertThat(context).hasSingleBean(Factory.class); + Factory factory = context.getBean(Factory.class); + Propagation propagation = factory.get(); + assertThat(propagation.keys()).isEmpty(); + }); + } + private void injectToMap(Map map, String key, String value) { map.put(key, value); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfigurationTests.java index 64bb18571381..0d7d8b171bed 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/OpenTelemetryAutoConfigurationTests.java @@ -290,6 +290,15 @@ void defaultSpanProcessorShouldUseMeterProviderIfAvailable() { }); } + @Test + void shouldDisablePropagationIfTracingIsDisabled() { + this.contextRunner.withPropertyValues("management.tracing.enabled=false").run((context) -> { + assertThat(context).hasSingleBean(TextMapPropagator.class); + TextMapPropagator propagator = context.getBean(TextMapPropagator.class); + assertThat(propagator.fields()).isEmpty(); + }); + } + private List getInjectors(TextMapPropagator propagator) { assertThat(propagator).as("propagator").isNotNull(); if (propagator instanceof CompositeTextMapPropagator compositePropagator) {