From 46b7bd2f23adc85e795a96d680893a10e4f1f3b3 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Mon, 15 Jan 2024 13:51:15 +0100 Subject: [PATCH] Add configuration property to enable micrometer annotations Prior to this commit, the Micrometer annotations support (`@Timed`, `@Counted`...) was guarded by the presence of both Micrometer and AspectJ on the classpath. This signal is too weak, considering the startup performance impact and the fact that the AspectJ dependency can be brought transitively in many cases. This commit adds a new `micrometer.observations.annotations.enabled` property that is set to `false` by default to only process the annotations support when this property is enabled. Fixes gh-39128 --- .../DocumentConfigurationProperties.java | 1 + .../MetricsAspectsAutoConfiguration.java | 4 +++- .../MicrometerTracingAutoConfiguration.java | 4 +++- ...itional-spring-configuration-metadata.json | 6 +++++ .../MetricsAspectsAutoConfigurationTests.java | 24 ++++++++++++++----- ...crometerTracingAutoConfigurationTests.java | 14 +++++++++++ .../src/docs/asciidoc/actuator/metrics.adoc | 3 ++- .../docs/asciidoc/actuator/observability.adoc | 8 +++++++ .../src/docs/asciidoc/attributes.adoc | 1 + 9 files changed, 56 insertions(+), 9 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java b/buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java index 6245d5b9da..e3bce2d4f4 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java @@ -215,6 +215,7 @@ public class DocumentConfigurationProperties extends DefaultTask { private void actuatorPrefixes(Config prefix) { prefix.accept("management"); + prefix.accept("micrometer"); } private void dockerComposePrefixes(Config prefix) { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfiguration.java index dbeeb8b27d..1541778479 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; /** @@ -39,6 +40,7 @@ import org.springframework.context.annotation.Bean; */ @AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class }) @ConditionalOnClass({ MeterRegistry.class, Advice.class }) +@ConditionalOnProperty(prefix = "micrometer.observations.annotations", name = "enabled", havingValue = "true") @ConditionalOnBean(MeterRegistry.class) public class MetricsAspectsAutoConfiguration { 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 93d8acaa0e..1ef058236f 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -35,6 +35,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -96,6 +97,7 @@ public class MicrometerTracingAutoConfiguration { @Configuration(proxyBeanMethods = false) @ConditionalOnClass(Advice.class) + @ConditionalOnProperty(prefix = "micrometer.observations.annotations", name = "enabled", havingValue = "true") static class SpanAspectConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index bfdc19a944..90eef215d6 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -2229,6 +2229,12 @@ "defaultValue": [ "W3C" ] + }, + { + "name": "micrometer.observations.annotations.enabled", + "type": "java.lang.Boolean", + "description": "Whether auto-configuration of Micrometer annotations is enabled.", + "defaultValue": false } ], "hints": [ diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfigurationTests.java index 215eba7b48..d2ecaf6f06 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAspectsAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 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. @@ -41,8 +41,19 @@ import static org.assertj.core.api.Assertions.assertThat; class MetricsAspectsAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) + .withPropertyValues("micrometer.observations.annotations.enabled=true") .withConfiguration(AutoConfigurations.of(MetricsAspectsAutoConfiguration.class)); + @Test + void shouldNotConfigureAspectsByDefault() { + new ApplicationContextRunner().with(MetricsRun.simple()) + .withConfiguration(AutoConfigurations.of(MetricsAspectsAutoConfiguration.class)) + .run((context) -> { + assertThat(context).doesNotHaveBean(CountedAspect.class); + assertThat(context).doesNotHaveBean(TimedAspect.class); + }); + } + @Test void shouldConfigureAspects() { this.contextRunner.run((context) -> { @@ -78,11 +89,12 @@ class MetricsAspectsAutoConfigurationTests { @Test void shouldNotConfigureAspectsIfMeterRegistryBeanIsMissing() { - new ApplicationContextRunner().run((context) -> { - assertThat(context).doesNotHaveBean(MeterRegistry.class); - assertThat(context).doesNotHaveBean(CountedAspect.class); - assertThat(context).doesNotHaveBean(TimedAspect.class); - }); + new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(MetricsAspectsAutoConfiguration.class)) + .run((context) -> { + assertThat(context).doesNotHaveBean(MeterRegistry.class); + assertThat(context).doesNotHaveBean(CountedAspect.class); + assertThat(context).doesNotHaveBean(TimedAspect.class); + }); } @Test 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 0d2ce0396f..f671d49415 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 @@ -47,15 +47,18 @@ import static org.mockito.Mockito.mock; * * @author Moritz Halbritter * @author Jonatan Ivanov + * @author Brian Clozel */ class MicrometerTracingAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withPropertyValues("micrometer.observations.annotations.enabled=true") .withConfiguration(AutoConfigurations.of(MicrometerTracingAutoConfiguration.class)); @Test void shouldSupplyBeans() { this.contextRunner.withUserConfiguration(TracerConfiguration.class, PropagatorConfiguration.class) + .withPropertyValues("micrometer.observations.annotations.enabled=true") .run((context) -> { assertThat(context).hasSingleBean(DefaultTracingObservationHandler.class); assertThat(context).hasSingleBean(PropagatingReceiverTracingObservationHandler.class); @@ -127,6 +130,17 @@ class MicrometerTracingAutoConfigurationTests { }); } + @Test + void shouldNotSupplyAspectBeansIfPropertyIsDisabled() { + this.contextRunner.withUserConfiguration(TracerConfiguration.class, PropagatorConfiguration.class) + .withPropertyValues("micrometer.observations.annotations.enabled=false") + .run((context) -> { + assertThat(context).doesNotHaveBean(DefaultNewSpanParser.class); + assertThat(context).doesNotHaveBean(ImperativeMethodInvocationProcessor.class); + assertThat(context).doesNotHaveBean(SpanAspect.class); + }); + } + @Test void shouldNotSupplyBeansIfAspectjIsMissing() { this.contextRunner.withUserConfiguration(TracerConfiguration.class) diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc index f31a807d82..f0e4f9c984 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc @@ -1067,7 +1067,8 @@ Metrics for Jetty's `Connector` instances are bound by using Micrometer's `Jetty [[actuator.metrics.supported.timed-annotation]] ==== @Timed Annotation Support -To use `@Timed` where it is not directly supported by Spring Boot, refer to the {micrometer-concepts-docs}#_the_timed_annotation[Micrometer documentation]. +To enable scanning of `@Timed` annotations, you will need to set the configprop:micrometer.observations.annotations.enabled[] property to `true`. +Please refer to the {micrometer-concepts-docs}#_the_timed_annotation[Micrometer documentation]. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/observability.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/observability.adoc index dbf2e32597..68187d9429 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/observability.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/observability.adoc @@ -85,3 +85,11 @@ NOTE: Spring Boot does not provide auto-configuration for OpenTelemetry metrics OpenTelemetry tracing is only auto-configured when used together with <>. The next sections will provide more details about logging, metrics and traces. + + + +[[actuator.observability.annotations]] +=== Micrometer Observation Annotations support + +To enable scanning of metrics and tracing annotations like `@Timed`, `@Counted`, `@MeterTag` and `@NewSpan` annotations, you will need to set the configprop:micrometer.observations.annotations.enabled[] property to `true`. +This feature is supported Micrometer directly, please refer to the {micrometer-concepts-docs}#_the_timed_annotation[Micrometer] and {micrometer-tracing-docs}/api.html#_aspect_oriented_programming[Micrometer Tracing] reference docs. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/attributes.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/attributes.adoc index ed3f880e0c..f3457ddb09 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/attributes.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/attributes.adoc @@ -109,6 +109,7 @@ :micrometer-docs: https://micrometer.io/docs :micrometer-concepts-docs: {micrometer-docs}/concepts :micrometer-registry-docs: {micrometer-docs}/registry +:micrometer-tracing-docs: https://docs.micrometer.io/tracing/reference :tomcat-docs: https://tomcat.apache.org/tomcat-{tomcat-version}-doc :graal-version: 22.3 :graal-native-image-docs: https://www.graalvm.org/{graal-version}/reference-manual/native-image