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 6245d5b9da5..e3bce2d4f41 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 dbeeb8b27d6..1541778479a 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 93d8acaa0e3..1ef058236f8 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 bfdc19a9445..90eef215d6c 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 215eba7b481..d2ecaf6f06d 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 0d2ce0396f8..f671d494159 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 f31a807d829..f0e4f9c984e 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 dbf2e325976..68187d94296 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 ed3f880e0cb..f3457ddb097 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