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
This commit is contained in:
Brian Clozel 2024-01-15 13:51:15 +01:00
parent 8bdaae37b0
commit 46b7bd2f23
9 changed files with 56 additions and 9 deletions

View File

@ -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) {

View File

@ -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 {

View File

@ -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

View File

@ -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": [

View File

@ -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

View File

@ -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)

View File

@ -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].

View File

@ -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 <<actuator#actuator.micrometer-tracing, Micrometer Tracing>>.
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.

View File

@ -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