From 27add2bbe3095805f4bb159f33e9aefd3292df2e Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Fri, 16 Jun 2023 14:09:00 +0200 Subject: [PATCH] Rework @AutoConfigureObservability and tracing auto-configurations @ConditionalOnEnabledTracing is now applied to the minimal amount of beans. The beans which are annotated with it are beans that will lead to span sending to backends. This leaves the majority of the Micrometer Tracing, Brave and OpenTelemetry infrastructure untouched in tests. Closes gh-35354 --- .../tracing/BraveAutoConfiguration.java | 1 - .../MicrometerTracingAutoConfiguration.java | 1 - .../OpenTelemetryAutoConfiguration.java | 1 - .../tracing/otlp/OtlpAutoConfiguration.java | 2 +- .../PrometheusExemplarsAutoConfiguration.java | 2 - .../WavefrontTracingAutoConfiguration.java | 4 +- .../zipkin/ZipkinAutoConfiguration.java | 2 - .../tracing/zipkin/ZipkinConfigurations.java | 3 + .../WavefrontSenderConfiguration.java | 23 +++++ ...intsAutoConfigurationIntegrationTests.java | 5 +- .../tracing/BraveAutoConfigurationTests.java | 6 -- ...crometerTracingAutoConfigurationTests.java | 11 --- .../otlp/OtlpAutoConfigurationTests.java | 10 +++ ...etheusExemplarsAutoConfigurationTests.java | 8 +- ...avefrontTracingAutoConfigurationTests.java | 16 ++-- .../zipkin/ZipkinAutoConfigurationTests.java | 6 -- ...ConfigurationsBraveConfigurationTests.java | 9 ++ ...ationsOpenTelemetryConfigurationTests.java | 9 ++ .../WavefrontSenderConfigurationTests.java | 29 ++++++ ...ObservabilityContextCustomizerFactory.java | 90 ------------------- ...vabilityContextCustomizerFactoryTests.java | 70 --------------- 21 files changed, 100 insertions(+), 208 deletions(-) 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 4001f0e7fad..393ff7dbfa1 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 @@ -76,7 +76,6 @@ import org.springframework.core.env.Environment; @AutoConfiguration(before = MicrometerTracingAutoConfiguration.class) @ConditionalOnClass({ Tracer.class, BraveTracer.class }) @EnableConfigurationProperties(TracingProperties.class) -@ConditionalOnEnabledTracing public class BraveAutoConfiguration { private static final BraveBaggageManager BRAVE_BAGGAGE_MANAGER = new BraveBaggageManager(); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java index e91e41a5b05..149141c887f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java @@ -39,7 +39,6 @@ import org.springframework.core.annotation.Order; */ @AutoConfiguration @ConditionalOnClass(Tracer.class) -@ConditionalOnEnabledTracing public class MicrometerTracingAutoConfiguration { /** 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 6a30b9cbc63..f2ccd0a5a62 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 @@ -75,7 +75,6 @@ import org.springframework.core.env.Environment; * @since 3.0.0 */ @AutoConfiguration(before = MicrometerTracingAutoConfiguration.class) -@ConditionalOnEnabledTracing @ConditionalOnClass({ OtelTracer.class, SdkTracerProvider.class, OpenTelemetry.class }) @EnableConfigurationProperties(TracingProperties.class) public class OpenTelemetryAutoConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfiguration.java index ca2012c20d6..e86b48ae555 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfiguration.java @@ -50,7 +50,6 @@ import org.springframework.context.annotation.Bean; * @since 3.1.0 */ @AutoConfiguration -@ConditionalOnEnabledTracing @ConditionalOnClass({ OtelTracer.class, SdkTracerProvider.class, OpenTelemetry.class, OtlpHttpSpanExporter.class }) @EnableConfigurationProperties(OtlpProperties.class) public class OtlpAutoConfiguration { @@ -59,6 +58,7 @@ public class OtlpAutoConfiguration { @ConditionalOnMissingBean(value = OtlpHttpSpanExporter.class, type = "io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter") @ConditionalOnProperty(prefix = "management.otlp.tracing", name = "endpoint") + @ConditionalOnEnabledTracing OtlpHttpSpanExporter otlpHttpSpanExporter(OtlpProperties properties) { OtlpHttpSpanExporterBuilder builder = OtlpHttpSpanExporter.builder() .setEndpoint(properties.getEndpoint()) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfiguration.java index 9032a0712ad..e669127982c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfiguration.java @@ -22,7 +22,6 @@ import io.prometheus.client.exemplars.tracer.common.SpanContextSupplier; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.tracing.ConditionalOnEnabledTracing; import org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -43,7 +42,6 @@ import org.springframework.util.function.SingletonSupplier; after = MicrometerTracingAutoConfiguration.class) @ConditionalOnBean(Tracer.class) @ConditionalOnClass({ Tracer.class, SpanContextSupplier.class }) -@ConditionalOnEnabledTracing public class PrometheusExemplarsAutoConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java index 81a0dd0863c..f3fab744bcc 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java @@ -52,7 +52,6 @@ import org.springframework.context.annotation.Import; @AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class, WavefrontAutoConfiguration.class }) @ConditionalOnClass({ WavefrontSender.class, WavefrontSpanHandler.class }) -@ConditionalOnEnabledTracing @EnableConfigurationProperties(WavefrontProperties.class) @Import(WavefrontSenderConfiguration.class) public class WavefrontTracingAutoConfiguration { @@ -60,6 +59,7 @@ public class WavefrontTracingAutoConfiguration { @Bean @ConditionalOnMissingBean @ConditionalOnBean(WavefrontSender.class) + @ConditionalOnEnabledTracing WavefrontSpanHandler wavefrontSpanHandler(WavefrontProperties properties, WavefrontSender wavefrontSender, SpanMetrics spanMetrics, ApplicationTags applicationTags) { return new WavefrontSpanHandler(properties.getSender().getMaxQueueSize(), wavefrontSender, spanMetrics, @@ -96,6 +96,7 @@ public class WavefrontTracingAutoConfiguration { @Bean @ConditionalOnMissingBean + @ConditionalOnEnabledTracing WavefrontBraveSpanHandler wavefrontBraveSpanHandler(WavefrontSpanHandler wavefrontSpanHandler) { return new WavefrontBraveSpanHandler(wavefrontSpanHandler); } @@ -108,6 +109,7 @@ public class WavefrontTracingAutoConfiguration { @Bean @ConditionalOnMissingBean + @ConditionalOnEnabledTracing WavefrontOtelSpanExporter wavefrontOtelSpanExporter(WavefrontSpanHandler wavefrontSpanHandler) { return new WavefrontOtelSpanExporter(wavefrontSpanHandler); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java index 971b9d514ec..daff635f863 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfiguration.java @@ -21,7 +21,6 @@ import zipkin2.codec.BytesEncoder; import zipkin2.codec.SpanBytesEncoder; import zipkin2.reporter.Sender; -import org.springframework.boot.actuate.autoconfigure.tracing.ConditionalOnEnabledTracing; import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.BraveConfiguration; import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.OpenTelemetryConfiguration; import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.ReporterConfiguration; @@ -48,7 +47,6 @@ import org.springframework.context.annotation.Import; @ConditionalOnClass(Sender.class) @Import({ SenderConfiguration.class, ReporterConfiguration.class, BraveConfiguration.class, OpenTelemetryConfiguration.class }) -@ConditionalOnEnabledTracing @EnableConfigurationProperties(ZipkinProperties.class) public class ZipkinAutoConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java index 722b502befa..b4a1802b7bc 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurations.java @@ -26,6 +26,7 @@ import zipkin2.reporter.brave.ZipkinSpanHandler; import zipkin2.reporter.urlconnection.URLConnectionSender; import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.actuate.autoconfigure.tracing.ConditionalOnEnabledTracing; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -142,6 +143,7 @@ class ZipkinConfigurations { @Bean @ConditionalOnMissingBean @ConditionalOnBean(Reporter.class) + @ConditionalOnEnabledTracing ZipkinSpanHandler zipkinSpanHandler(Reporter spanReporter) { return (ZipkinSpanHandler) ZipkinSpanHandler.newBuilder(spanReporter).build(); } @@ -155,6 +157,7 @@ class ZipkinConfigurations { @Bean @ConditionalOnMissingBean @ConditionalOnBean(Sender.class) + @ConditionalOnEnabledTracing ZipkinSpanExporter zipkinSpanExporter(BytesEncoder encoder, Sender sender) { return ZipkinSpanExporter.builder().setEncoder(encoder).setSender(sender).build(); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontSenderConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontSenderConfiguration.java index 6cb11ae31df..1416abc72ec 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontSenderConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontSenderConfiguration.java @@ -21,13 +21,17 @@ import java.time.Duration; import com.wavefront.sdk.common.WavefrontSender; import com.wavefront.sdk.common.clients.WavefrontClient.Builder; +import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; import org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront.WavefrontMetricsExportAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.tracing.ConditionalOnEnabledTracing; import org.springframework.boot.actuate.autoconfigure.tracing.wavefront.WavefrontTracingAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.util.unit.DataSize; @@ -46,6 +50,7 @@ public class WavefrontSenderConfiguration { @Bean @ConditionalOnMissingBean + @Conditional(WavefrontTracingOrMetricsCondition.class) public WavefrontSender wavefrontSender(WavefrontProperties properties) { Builder builder = new Builder(properties.getEffectiveUri().toString(), properties.getApiTokenOrThrow()); PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); @@ -57,4 +62,22 @@ public class WavefrontSenderConfiguration { return builder.build(); } + static final class WavefrontTracingOrMetricsCondition extends AnyNestedCondition { + + WavefrontTracingOrMetricsCondition() { + super(ConfigurationPhase.REGISTER_BEAN); + } + + @ConditionalOnEnabledTracing + static class TracingCondition { + + } + + @ConditionalOnEnabledMetricsExport("wavefront") + static class MetricsCondition { + + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java index f2d6c56aca3..33aa8931dd2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java @@ -19,6 +19,8 @@ package org.springframework.boot.actuate.autoconfigure.integrationtest; import org.junit.jupiter.api.Test; import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration; import org.springframework.boot.actuate.health.HealthEndpointWebExtension; import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -80,7 +82,8 @@ class WebEndpointsAutoConfigurationIntegrationTests { MongoReactiveAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class, HazelcastAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class, RedisAutoConfiguration.class, - RedisRepositoriesAutoConfiguration.class }) + RedisRepositoriesAutoConfiguration.class, BraveAutoConfiguration.class, + OpenTelemetryAutoConfiguration.class }) @SpringBootConfiguration static class WebEndpointTestApplication { 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 e51998741ce..073fd9b9687 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 @@ -151,12 +151,6 @@ class BraveAutoConfigurationTests { }); } - @Test - void shouldNotSupplyBeansIfTracingIsDisabled() { - this.contextRunner.withPropertyValues("management.tracing.enabled=false") - .run((context) -> assertThat(context).doesNotHaveBean(BraveAutoConfiguration.class)); - } - @Test void shouldNotSupplyCorrelationScopeDecoratorIfBaggageDisabled() { this.contextRunner.withPropertyValues("management.tracing.baggage.enabled=false") diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java index 6f3c4a373d0..d9f94f46396 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java @@ -111,17 +111,6 @@ class MicrometerTracingAutoConfigurationTests { }); } - @Test - void shouldNotSupplyBeansIfTracingIsDisabled() { - this.contextRunner.withUserConfiguration(TracerConfiguration.class, PropagatorConfiguration.class) - .withPropertyValues("management.tracing.enabled=false") - .run((context) -> { - assertThat(context).doesNotHaveBean(DefaultTracingObservationHandler.class); - assertThat(context).doesNotHaveBean(PropagatingReceiverTracingObservationHandler.class); - assertThat(context).doesNotHaveBean(PropagatingSenderTracingObservationHandler.class); - }); - } - @Configuration(proxyBeanMethods = false) private static class TracerConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfigurationTests.java index f3b3e5b3a5a..0f5fbca25c8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfigurationTests.java @@ -40,6 +40,9 @@ class OtlpAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(OtlpAutoConfiguration.class)); + private final ApplicationContextRunner tracingDisabledContextRunner = this.contextRunner + .withPropertyValues("management.tracing.enabled=false"); + @Test void shouldNotSupplyBeansIfPropertyIsNotSet() { this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(OtlpHttpSpanExporter.class)); @@ -96,6 +99,13 @@ class OtlpAutoConfigurationTests { .hasSingleBean(SpanExporter.class)); } + @Test + void shouldNotSupplyOtlpHttpSpanExporterIfTracingIsDisabled() { + this.tracingDisabledContextRunner + .withPropertyValues("management.otlp.tracing.endpoint=http://localhost:4318/v1/traces") + .run((context) -> assertThat(context).doesNotHaveBean(OtlpHttpSpanExporter.class)); + } + @Configuration(proxyBeanMethods = false) private static class CustomHttpExporterConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfigurationTests.java index 2d2f9d35a53..3bbec4be49f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/prometheus/PrometheusExemplarsAutoConfigurationTests.java @@ -40,7 +40,7 @@ import static org.mockito.Mockito.mock; /** * Tests for {@link PrometheusExemplarsAutoConfiguration}. * - * * @author Jonatan Ivanov + * @author Jonatan Ivanov */ class PrometheusExemplarsAutoConfigurationTests { @@ -52,12 +52,6 @@ class PrometheusExemplarsAutoConfigurationTests { AutoConfigurations.of(PrometheusExemplarsAutoConfiguration.class, ObservationAutoConfiguration.class, BraveAutoConfiguration.class, MicrometerTracingAutoConfiguration.class)); - @Test - void shouldNotSupplyBeansIfTracingIsDisabled() { - this.contextRunner.withPropertyValues("management.tracing.enabled=false") - .run((context) -> assertThat(context).doesNotHaveBean(SpanContextSupplier.class)); - } - @Test void shouldNotSupplyBeansIfPrometheusSupportIsMissing() { this.contextRunner.withClassLoader(new FilteredClassLoader("io.prometheus.client.exemplars")) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java index a75d692772e..8295ed6930f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java @@ -47,6 +47,9 @@ class WavefrontTracingAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration( AutoConfigurations.of(WavefrontAutoConfiguration.class, WavefrontTracingAutoConfiguration.class)); + private final ApplicationContextRunner tracingDisabledContextRunner = this.contextRunner + .withPropertyValues("management.tracing.enabled=false"); + @Test void shouldSupplyBeans() { this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class).run((context) -> { @@ -83,14 +86,11 @@ class WavefrontTracingAutoConfigurationTests { @Test void shouldNotSupplyBeansIfTracingIsDisabled() { - this.contextRunner.withPropertyValues("management.tracing.enabled=false") - .withUserConfiguration(WavefrontSenderConfiguration.class) - .run((context) -> { - assertThat(context).doesNotHaveBean(WavefrontSpanHandler.class); - assertThat(context).doesNotHaveBean(SpanMetrics.class); - assertThat(context).doesNotHaveBean(WavefrontBraveSpanHandler.class); - assertThat(context).doesNotHaveBean(WavefrontOtelSpanExporter.class); - }); + this.tracingDisabledContextRunner.withUserConfiguration(WavefrontSenderConfiguration.class).run((context) -> { + assertThat(context).doesNotHaveBean(WavefrontSpanHandler.class); + assertThat(context).doesNotHaveBean(WavefrontBraveSpanHandler.class); + assertThat(context).doesNotHaveBean(WavefrontOtelSpanExporter.class); + }); } @Test diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java index c647bfbfe2a..1da2e7668a8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinAutoConfigurationTests.java @@ -59,12 +59,6 @@ class ZipkinAutoConfigurationTests { }); } - @Test - void shouldNotSupplyBeansIfTracingIsDisabled() { - this.contextRunner.withPropertyValues("management.tracing.enabled=false") - .run((context) -> assertThat(context).doesNotHaveBean(BytesEncoder.class)); - } - @Test void definesPropertiesBasedConnectionDetailsByDefault() { this.contextRunner.run((context) -> assertThat(context).hasSingleBean(PropertiesZipkinConnectionDetails.class)); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java index 735cd00d0c6..9b488aebe40 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsBraveConfigurationTests.java @@ -42,6 +42,9 @@ class ZipkinConfigurationsBraveConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(BraveConfiguration.class)); + private final ApplicationContextRunner tracingDisabledContextRunner = this.contextRunner + .withPropertyValues("management.tracing.enabled=false"); + @Test void shouldSupplyBeans() { this.contextRunner.withUserConfiguration(ReporterConfiguration.class) @@ -79,6 +82,12 @@ class ZipkinConfigurationsBraveConfigurationTests { }); } + @Test + void shouldNotSupplyZipkinSpanHandlerIfTracingIsDisabled() { + this.tracingDisabledContextRunner.withUserConfiguration(ReporterConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean(ZipkinSpanHandler.class)); + } + @Configuration(proxyBeanMethods = false) private static class ReporterConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java index c3ef5f99c37..5c2a9059c55 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/zipkin/ZipkinConfigurationsOpenTelemetryConfigurationTests.java @@ -43,6 +43,9 @@ class ZipkinConfigurationsOpenTelemetryConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(BaseConfiguration.class, OpenTelemetryConfiguration.class)); + private final ApplicationContextRunner tracingDisabledContextRunner = this.contextRunner + .withPropertyValues("management.tracing.enabled=false"); + @Test void shouldSupplyBeans() { this.contextRunner.withUserConfiguration(SenderConfiguration.class) @@ -70,6 +73,12 @@ class ZipkinConfigurationsOpenTelemetryConfigurationTests { }); } + @Test + void shouldNotSupplyZipkinSpanExporterIfTracingIsDisabled() { + this.tracingDisabledContextRunner.withUserConfiguration(SenderConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean(ZipkinSpanExporter.class)); + } + @Configuration(proxyBeanMethods = false) private static class SenderConfiguration { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontSenderConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontSenderConfigurationTests.java index a75203e4fed..367adebb5c5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontSenderConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontSenderConfigurationTests.java @@ -42,6 +42,17 @@ class WavefrontSenderConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(WavefrontSenderConfiguration.class)); + private final ApplicationContextRunner tracingDisabledContextRunner = this.contextRunner + .withPropertyValues("management.tracing.enabled=false"); + + private final ApplicationContextRunner metricsDisabledContextRunner = this.contextRunner.withPropertyValues( + "management.defaults.metrics.export.enabled=false", "management.simple.metrics.export.enabled=true"); + + // Both metrics and tracing are disabled + private final ApplicationContextRunner observabilityDisabledContextRunner = this.contextRunner.withPropertyValues( + "management.tracing.enabled=false", "management.defaults.metrics.export.enabled=false", + "management.simple.metrics.export.enabled=true"); + @Test void shouldNotFailIfWavefrontIsMissing() { this.contextRunner.withClassLoader(new FilteredClassLoader("com.wavefront")) @@ -83,6 +94,24 @@ class WavefrontSenderConfigurationTests { }); } + @Test + void shouldNotSupplyWavefrontSenderIfObservabilityIsDisabled() { + this.observabilityDisabledContextRunner.withPropertyValues("management.wavefront.api-token=abcde") + .run((context) -> assertThat(context).doesNotHaveBean(WavefrontSender.class)); + } + + @Test + void shouldSupplyWavefrontSenderIfOnlyTracingIsDisabled() { + this.tracingDisabledContextRunner.withPropertyValues("management.wavefront.api-token=abcde") + .run((context) -> assertThat(context).hasSingleBean(WavefrontSender.class)); + } + + @Test + void shouldSupplyWavefrontSenderIfOnlyMetricsAreDisabled() { + this.metricsDisabledContextRunner.withPropertyValues("management.wavefront.api-token=abcde") + .run((context) -> assertThat(context).hasSingleBean(WavefrontSender.class)); + } + @Test void allowsWavefrontSenderToBeCustomized() { this.contextRunner.withUserConfiguration(CustomSenderConfiguration.class) diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactory.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactory.java index 918777baf1e..86a003b6b6e 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactory.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactory.java @@ -19,39 +19,19 @@ package org.springframework.boot.test.autoconfigure.actuate.observability; import java.util.List; import java.util.Objects; -import io.micrometer.tracing.Tracer; - -import org.springframework.aot.AotDetector; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; -import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.ConfigurationClassPostProcessor; -import org.springframework.core.Ordered; import org.springframework.core.env.Environment; import org.springframework.test.context.ContextConfigurationAttributes; import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizerFactory; import org.springframework.test.context.MergedContextConfiguration; import org.springframework.test.context.TestContextAnnotationUtils; -import org.springframework.util.ClassUtils; /** * {@link ContextCustomizerFactory} that globally disables metrics export and tracing in * tests. The behaviour can be controlled with {@link AutoConfigureObservability} on the * test class or via the {@value #AUTO_CONFIGURE_PROPERTY} property. - *

- * Registers {@link Tracer#NOOP} if tracing is disabled, micrometer-tracing is on the - * classpath, and the user hasn't supplied their own {@link Tracer}. * * @author Chris Bono * @author Moritz Halbritter @@ -87,7 +67,6 @@ class ObservabilityContextCustomizerFactory implements ContextCustomizerFactory } if (isTracingDisabled(context.getEnvironment())) { TestPropertyValues.of("management.tracing.enabled=false").applyTo(context); - registerNoopTracer(context); } } @@ -105,25 +84,6 @@ class ObservabilityContextCustomizerFactory implements ContextCustomizerFactory return !environment.getProperty(AUTO_CONFIGURE_PROPERTY, Boolean.class, false); } - private void registerNoopTracer(ConfigurableApplicationContext context) { - if (AotDetector.useGeneratedArtifacts()) { - return; - } - if (!ClassUtils.isPresent("io.micrometer.tracing.Tracer", context.getClassLoader())) { - return; - } - ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); - if (beanFactory instanceof BeanDefinitionRegistry registry) { - registerNoopTracer(registry); - } - } - - private void registerNoopTracer(BeanDefinitionRegistry registry) { - RootBeanDefinition definition = new RootBeanDefinition(NoopTracerRegistrar.class); - definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - registry.registerBeanDefinition(NoopTracerRegistrar.class.getName(), definition); - } - @Override public boolean equals(Object o) { if (this == o) { @@ -143,54 +103,4 @@ class ObservabilityContextCustomizerFactory implements ContextCustomizerFactory } - /** - * {@link BeanDefinitionRegistryPostProcessor} that runs after the - * {@link ConfigurationClassPostProcessor} and adds a {@link Tracer} bean definition - * when a {@link Tracer} hasn't already been registered. - */ - static class NoopTracerRegistrar implements BeanDefinitionRegistryPostProcessor, Ordered, BeanFactoryAware { - - private BeanFactory beanFactory; - - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = beanFactory; - } - - @Override - public int getOrder() { - return Ordered.LOWEST_PRECEDENCE; - } - - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { - if (AotDetector.useGeneratedArtifacts()) { - return; - } - if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors((ListableBeanFactory) this.beanFactory, - Tracer.class, false, false).length == 0) { - registry.registerBeanDefinition("noopTracer", new RootBeanDefinition(NoopTracerFactoryBean.class)); - } - } - - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - } - - } - - static class NoopTracerFactoryBean implements FactoryBean { - - @Override - public Tracer getObject() { - return Tracer.NOOP; - } - - @Override - public Class getObjectType() { - return Tracer.class; - } - - } - } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactoryTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactoryTests.java index d8e46424c52..c8604bf5307 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactoryTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/actuate/observability/ObservabilityContextCustomizerFactoryTests.java @@ -18,22 +18,15 @@ package org.springframework.boot.test.autoconfigure.actuate.observability; import java.util.Collections; -import io.micrometer.tracing.Tracer; import org.junit.jupiter.api.Test; -import org.springframework.boot.context.annotation.UserConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.context.support.GenericApplicationContext; import org.springframework.mock.env.MockEnvironment; import org.springframework.test.context.ContextCustomizer; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; /** * Tests for {@link AutoConfigureObservability} and @@ -82,59 +75,6 @@ class ObservabilityContextCustomizerFactoryTests { assertThatTracingIsEnabled(context); } - @Test - void shouldRegisterNoopTracerIfTracingIsDisabled() { - ContextCustomizer customizer = createContextCustomizer(NoAnnotation.class); - ConfigurableApplicationContext context = new GenericApplicationContext(); - applyCustomizerToContext(customizer, context); - context.refresh(); - Tracer tracer = context.getBean(Tracer.class); - assertThat(tracer).isNotNull(); - assertThat(tracer.nextSpan().isNoop()).isTrue(); - } - - @Test - void shouldNotRegisterNoopTracerIfTracingIsEnabled() { - ContextCustomizer customizer = createContextCustomizer(WithAnnotation.class); - ConfigurableApplicationContext context = new GenericApplicationContext(); - applyCustomizerToContext(customizer, context); - context.refresh(); - assertThat(context.getBeanProvider(Tracer.class).getIfAvailable()).as("Tracer bean").isNull(); - } - - @Test - void shouldNotRegisterNoopTracerIfMicrometerTracingIsNotPresent() throws Exception { - try (FilteredClassLoader filteredClassLoader = new FilteredClassLoader("io.micrometer.tracing")) { - ContextCustomizer customizer = createContextCustomizer(NoAnnotation.class); - new ApplicationContextRunner().withClassLoader(filteredClassLoader) - .withInitializer(applyCustomizer(customizer)) - .run((context) -> { - assertThat(context).doesNotHaveBean(Tracer.class); - assertThatMetricsAreDisabled(context); - assertThatTracingIsDisabled(context); - }); - } - } - - @Test - void shouldBackOffOnCustomTracer() { - ContextCustomizer customizer = createContextCustomizer(NoAnnotation.class); - new ApplicationContextRunner().withConfiguration(UserConfigurations.of(CustomTracer.class)) - .withInitializer(applyCustomizer(customizer)) - .run((context) -> { - assertThat(context).hasSingleBean(Tracer.class); - assertThat(context).hasBean("customTracer"); - }); - } - - @Test - void shouldNotRunIfAotIsEnabled() { - ContextCustomizer customizer = createContextCustomizer(NoAnnotation.class); - new ApplicationContextRunner().withSystemProperties("spring.aot.enabled:true") - .withInitializer(applyCustomizer(customizer)) - .run((context) -> assertThat(context).doesNotHaveBean(Tracer.class)); - } - @Test void notEquals() { ContextCustomizer customizer1 = createContextCustomizer(OnlyMetrics.class); @@ -256,14 +196,4 @@ class ObservabilityContextCustomizerFactoryTests { } - @Configuration(proxyBeanMethods = false) - static class CustomTracer { - - @Bean - Tracer customTracer() { - return mock(Tracer.class); - } - - } - }