Add auto-configuration for ObservedAspect

This adds support for auto-configuring `ObservedAspect` when AspectJ is
on the classpath, which enables the usage of `@Observed`.

See gh-35191
This commit is contained in:
Vedran Pavic 2023-04-28 11:13:59 +02:00 committed by Stephane Nicoll
parent 31db1d8125
commit 0dae89e837
2 changed files with 31 additions and 0 deletions

View File

@ -27,9 +27,11 @@ import io.micrometer.observation.ObservationFilter;
import io.micrometer.observation.ObservationHandler;
import io.micrometer.observation.ObservationPredicate;
import io.micrometer.observation.ObservationRegistry;
import io.micrometer.observation.aop.ObservedAspect;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler;
import io.micrometer.tracing.handler.TracingObservationHandler;
import org.aspectj.weaver.Advice;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
@ -51,6 +53,7 @@ import org.springframework.core.annotation.Order;
* @author Moritz Halbritter
* @author Brian Clozel
* @author Jonatan Ivanov
* @author Vedran Pavic
* @since 3.0.0
*/
@AutoConfiguration(after = { CompositeMeterRegistryAutoConfiguration.class, MicrometerTracingAutoConfiguration.class })
@ -149,4 +152,16 @@ public class ObservationAutoConfiguration {
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Advice.class)
static class ObservedAspectConfiguration {
@Bean
@ConditionalOnMissingBean
ObservedAspect observedAspect(ObservationRegistry observationRegistry) {
return new ObservedAspect(observationRegistry);
}
}
}

View File

@ -34,9 +34,11 @@ import io.micrometer.observation.ObservationHandler.AllMatchingCompositeObservat
import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler;
import io.micrometer.observation.ObservationPredicate;
import io.micrometer.observation.ObservationRegistry;
import io.micrometer.observation.aop.ObservedAspect;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler;
import io.micrometer.tracing.handler.TracingObservationHandler;
import org.aspectj.weaver.Advice;
import org.junit.jupiter.api.Test;
import org.mockito.Answers;
@ -58,6 +60,7 @@ import static org.mockito.Mockito.mock;
*
* @author Moritz Halbritter
* @author Jonatan Ivanov
* @author Vedran Pavic
*/
class ObservationAutoConfigurationTests {
@ -77,6 +80,7 @@ class ObservationAutoConfigurationTests {
assertThat(context).hasSingleBean(MeterRegistry.class);
assertThat(context).doesNotHaveBean(ObservationRegistry.class);
assertThat(context).doesNotHaveBean(ObservationHandler.class);
assertThat(context).doesNotHaveBean(ObservedAspect.class);
assertThat(context).doesNotHaveBean(ObservationHandlerGrouping.class);
});
}
@ -88,6 +92,7 @@ class ObservationAutoConfigurationTests {
ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class);
Observation.start("test-observation", observationRegistry).stop();
assertThat(context).doesNotHaveBean(ObservationHandler.class);
assertThat(context).hasSingleBean(ObservedAspect.class);
assertThat(context).doesNotHaveBean(ObservationHandlerGrouping.class);
});
}
@ -99,6 +104,7 @@ class ObservationAutoConfigurationTests {
Observation.start("test-observation", observationRegistry).stop();
assertThat(context).hasSingleBean(ObservationHandler.class);
assertThat(context).hasSingleBean(DefaultMeterObservationHandler.class);
assertThat(context).hasSingleBean(ObservedAspect.class);
assertThat(context).hasSingleBean(ObservationHandlerGrouping.class);
assertThat(context).hasBean("metricsObservationHandlerGrouping");
});
@ -110,6 +116,7 @@ class ObservationAutoConfigurationTests {
ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class);
Observation.start("test-observation", observationRegistry).stop();
assertThat(context).doesNotHaveBean(ObservationHandler.class);
assertThat(context).hasSingleBean(ObservedAspect.class);
assertThat(context).hasSingleBean(ObservationHandlerGrouping.class);
assertThat(context).hasBean("tracingObservationHandlerGrouping");
});
@ -123,6 +130,7 @@ class ObservationAutoConfigurationTests {
// TracingAwareMeterObservationHandler that we don't test here
Observation.start("test-observation", observationRegistry);
assertThat(context).hasSingleBean(ObservationHandler.class);
assertThat(context).hasSingleBean(ObservedAspect.class);
assertThat(context).hasSingleBean(TracingAwareMeterObservationHandler.class);
assertThat(context).hasSingleBean(ObservationHandlerGrouping.class);
assertThat(context).hasBean("metricsAndTracingObservationHandlerGrouping");
@ -138,6 +146,7 @@ class ObservationAutoConfigurationTests {
Observation.start("test-observation", observationRegistry).stop();
assertThat(context).hasSingleBean(ObservationHandler.class);
assertThat(context).hasSingleBean(DefaultMeterObservationHandler.class);
assertThat(context).hasSingleBean(ObservedAspect.class);
assertThat(context).hasSingleBean(ObservationHandlerGrouping.class);
assertThat(context).hasBean("metricsAndTracingObservationHandlerGrouping");
});
@ -155,6 +164,7 @@ class ObservationAutoConfigurationTests {
assertThat(meterRegistry.get("test-observation").timer().count()).isOne();
assertThat(context).hasSingleBean(DefaultMeterObservationHandler.class);
assertThat(context).hasSingleBean(ObservationHandler.class);
assertThat(context).hasSingleBean(ObservedAspect.class);
});
}
@ -164,6 +174,12 @@ class ObservationAutoConfigurationTests {
.run((context) -> assertThat(context).doesNotHaveBean(ObservationHandler.class));
}
@Test
void allowsObservedAspectToBeDisabled() {
this.contextRunner.withClassLoader(new FilteredClassLoader(Advice.class))
.run((context) -> assertThat(context).doesNotHaveBean(ObservedAspect.class));
}
@Test
void autoConfiguresObservationPredicates() {
this.contextRunner.withUserConfiguration(ObservationPredicates.class).run((context) -> {