Merge pull request #32399 from jonatan-ivanov
* gh-32399: Polish "Use TracingAwareMeterObservationHandler if tracing is configured" Use TracingAwareMeterObservationHandler if tracing is configured Closes gh-32399
This commit is contained in:
@@ -16,17 +16,23 @@
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.observation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler;
|
||||
import io.micrometer.core.instrument.observation.MeterObservationHandler;
|
||||
import io.micrometer.observation.GlobalObservationConvention;
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationHandler;
|
||||
import io.micrometer.observation.ObservationPredicate;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler;
|
||||
import io.micrometer.tracing.handler.TracingObservationHandler;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.tracing.MicrometerTracingAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
@@ -42,9 +48,10 @@ import org.springframework.context.annotation.Configuration;
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Brian Clozel
|
||||
* @author Jonatan Ivanov
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@AutoConfiguration(after = CompositeMeterRegistryAutoConfiguration.class)
|
||||
@AutoConfiguration(after = { CompositeMeterRegistryAutoConfiguration.class, MicrometerTracingAutoConfiguration.class })
|
||||
@ConditionalOnClass(ObservationRegistry.class)
|
||||
@EnableConfigurationProperties(ObservationProperties.class)
|
||||
public class ObservationAutoConfiguration {
|
||||
@@ -67,35 +74,68 @@ public class ObservationAutoConfiguration {
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnBean(MeterRegistry.class)
|
||||
static class MetricsConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(MeterObservationHandler.class)
|
||||
DefaultMeterObservationHandler defaultMeterObservationHandler(MeterRegistry meterRegistry) {
|
||||
return new DefaultMeterObservationHandler(meterRegistry);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingClass("io.micrometer.tracing.handler.TracingObservationHandler")
|
||||
@ConditionalOnClass(MeterRegistry.class)
|
||||
@ConditionalOnMissingClass("io.micrometer.tracing.Tracer")
|
||||
static class OnlyMetricsConfiguration {
|
||||
|
||||
@Bean
|
||||
OnlyMetricsObservationHandlerGrouping onlyMetricsObservationHandlerGrouping() {
|
||||
return new OnlyMetricsObservationHandlerGrouping();
|
||||
ObservationHandlerGrouping metricsObservationHandlerGrouping() {
|
||||
return new ObservationHandlerGrouping(MeterObservationHandler.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(TracingObservationHandler.class)
|
||||
static class TracingConfiguration {
|
||||
@ConditionalOnClass(Tracer.class)
|
||||
@ConditionalOnMissingClass("io.micrometer.core.instrument.MeterRegistry")
|
||||
static class OnlyTracingConfiguration {
|
||||
|
||||
@Bean
|
||||
TracingObservationHandlerGrouping tracingObservationHandlerGrouping() {
|
||||
return new TracingObservationHandlerGrouping();
|
||||
ObservationHandlerGrouping tracingObservationHandlerGrouping() {
|
||||
return new ObservationHandlerGrouping(TracingObservationHandler.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ MeterRegistry.class, Tracer.class })
|
||||
static class MetricsWithTracingConfiguration {
|
||||
|
||||
@Bean
|
||||
ObservationHandlerGrouping metricsAndTracingObservationHandlerGrouping() {
|
||||
return new ObservationHandlerGrouping(
|
||||
List.of(TracingObservationHandler.class, MeterObservationHandler.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnBean(MeterRegistry.class)
|
||||
@ConditionalOnMissingBean(MeterObservationHandler.class)
|
||||
static class MeterObservationHandlerConfiguration {
|
||||
|
||||
@ConditionalOnMissingBean(Tracer.class)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class OnlyMetricsMeterObservationHandlerConfiguration {
|
||||
|
||||
@Bean
|
||||
DefaultMeterObservationHandler defaultMeterObservationHandler(MeterRegistry meterRegistry) {
|
||||
return new DefaultMeterObservationHandler(meterRegistry);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnBean(Tracer.class)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TracingAndMetricsObservationHandlerConfiguration {
|
||||
|
||||
@Bean
|
||||
TracingAwareMeterObservationHandler<Observation.Context> tracingAwareMeterObservationHandler(
|
||||
MeterRegistry meterRegistry, Tracer tracer) {
|
||||
return new TracingAwareMeterObservationHandler<>(new DefaultMeterObservationHandler(meterRegistry),
|
||||
tracer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,24 +16,61 @@
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.observation;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.micrometer.observation.ObservationHandler;
|
||||
import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler;
|
||||
import io.micrometer.observation.ObservationRegistry.ObservationConfig;
|
||||
|
||||
/**
|
||||
* Strategy to apply {@link ObservationHandler ObservationHandlers} to an
|
||||
* {@link ObservationConfig}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
interface ObservationHandlerGrouping {
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Applies the given list of {@code handlers} to the given {@code config}.
|
||||
* @param handlers the list of observation handlers
|
||||
* @param config the config to apply the handlers to
|
||||
*/
|
||||
void apply(Collection<ObservationHandler<?>> handlers, ObservationConfig config);
|
||||
/**
|
||||
* Groups {@link ObservationHandler ObservationHandlers} by type.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
class ObservationHandlerGrouping {
|
||||
|
||||
private final List<Class<? extends ObservationHandler>> categories;
|
||||
|
||||
ObservationHandlerGrouping(Class<? extends ObservationHandler> category) {
|
||||
this(List.of(category));
|
||||
}
|
||||
|
||||
ObservationHandlerGrouping(List<Class<? extends ObservationHandler>> categories) {
|
||||
this.categories = categories;
|
||||
}
|
||||
|
||||
void apply(List<ObservationHandler<?>> handlers, ObservationConfig config) {
|
||||
Map<Class<? extends ObservationHandler>, List<ObservationHandler<?>>> groupings = new HashMap<>();
|
||||
for (ObservationHandler<?> handler : handlers) {
|
||||
Class<? extends ObservationHandler> category = findCategory(handler);
|
||||
if (category != null) {
|
||||
groupings.computeIfAbsent(category, (c) -> new ArrayList<>()).add(handler);
|
||||
}
|
||||
else {
|
||||
config.observationHandler(handler);
|
||||
}
|
||||
}
|
||||
for (Class<? extends ObservationHandler> category : this.categories) {
|
||||
List<ObservationHandler<?>> handlerGroup = groupings.get(category);
|
||||
if (!CollectionUtils.isEmpty(handlerGroup)) {
|
||||
config.observationHandler(new FirstMatchingCompositeObservationHandler(handlerGroup));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Class<? extends ObservationHandler> findCategory(ObservationHandler<?> handler) {
|
||||
for (Class<? extends ObservationHandler> category : this.categories) {
|
||||
if (category.isInstance(handler)) {
|
||||
return category;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@ class ObservationRegistryConfigurer {
|
||||
}
|
||||
|
||||
private void registerHandlers(ObservationRegistry registry) {
|
||||
this.observationHandlerGrouping.getObject().apply(asOrderedList(this.observationHandlers),
|
||||
registry.observationConfig());
|
||||
this.observationHandlerGrouping.ifAvailable(
|
||||
(grouping) -> grouping.apply(asOrderedList(this.observationHandlers), registry.observationConfig()));
|
||||
}
|
||||
|
||||
private void registerObservationPredicates(ObservationRegistry registry) {
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.observation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import io.micrometer.core.instrument.observation.MeterObservationHandler;
|
||||
import io.micrometer.observation.ObservationHandler;
|
||||
import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler;
|
||||
import io.micrometer.observation.ObservationRegistry.ObservationConfig;
|
||||
|
||||
/**
|
||||
* {@link ObservationHandlerGrouping} used by {@link ObservationAutoConfiguration} if
|
||||
* micrometer-tracing is not on the classpath.
|
||||
*
|
||||
* Groups all {@link MeterObservationHandler} into a
|
||||
* {@link FirstMatchingCompositeObservationHandler}. All other handlers are added to the
|
||||
* {@link ObservationConfig} directly.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class OnlyMetricsObservationHandlerGrouping implements ObservationHandlerGrouping {
|
||||
|
||||
@Override
|
||||
public void apply(Collection<ObservationHandler<?>> handlers, ObservationConfig config) {
|
||||
List<ObservationHandler<?>> meterObservationHandlers = new ArrayList<>();
|
||||
for (ObservationHandler<?> handler : handlers) {
|
||||
if (handler instanceof MeterObservationHandler<?>) {
|
||||
meterObservationHandlers.add(handler);
|
||||
}
|
||||
else {
|
||||
config.observationHandler(handler);
|
||||
}
|
||||
}
|
||||
if (!meterObservationHandlers.isEmpty()) {
|
||||
config.observationHandler(new FirstMatchingCompositeObservationHandler(meterObservationHandlers));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2022 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.observation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import io.micrometer.core.instrument.observation.MeterObservationHandler;
|
||||
import io.micrometer.observation.ObservationHandler;
|
||||
import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler;
|
||||
import io.micrometer.observation.ObservationRegistry.ObservationConfig;
|
||||
import io.micrometer.tracing.handler.TracingObservationHandler;
|
||||
|
||||
/**
|
||||
* {@link ObservationHandlerGrouping} used by {@link ObservationAutoConfiguration} if
|
||||
* micrometer-tracing is on the classpath.
|
||||
*
|
||||
* Groups all {@link TracingObservationHandler} into a
|
||||
* {@link FirstMatchingCompositeObservationHandler}, and {@link MeterObservationHandler}
|
||||
* into a {@link FirstMatchingCompositeObservationHandler}. All other handlers are added
|
||||
* to the {@link ObservationConfig} directly.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class TracingObservationHandlerGrouping implements ObservationHandlerGrouping {
|
||||
|
||||
@Override
|
||||
public void apply(Collection<ObservationHandler<?>> handlers, ObservationConfig config) {
|
||||
List<ObservationHandler<?>> meterObservationHandlers = new ArrayList<>();
|
||||
List<ObservationHandler<?>> tracingObservationHandlers = new ArrayList<>();
|
||||
for (ObservationHandler<?> handler : handlers) {
|
||||
if (handler instanceof TracingObservationHandler<?>) {
|
||||
tracingObservationHandlers.add(handler);
|
||||
}
|
||||
else if (handler instanceof MeterObservationHandler<?>) {
|
||||
meterObservationHandlers.add(handler);
|
||||
}
|
||||
else {
|
||||
config.observationHandler(handler);
|
||||
}
|
||||
}
|
||||
if (!tracingObservationHandlers.isEmpty()) {
|
||||
config.observationHandler(new FirstMatchingCompositeObservationHandler(tracingObservationHandlers));
|
||||
}
|
||||
if (!meterObservationHandlers.isEmpty()) {
|
||||
config.observationHandler(new FirstMatchingCompositeObservationHandler(meterObservationHandlers));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObserv
|
||||
import io.micrometer.observation.ObservationPredicate;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import io.micrometer.tracing.handler.TracingAwareMeterObservationHandler;
|
||||
import io.micrometer.tracing.handler.TracingObservationHandler;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Answers;
|
||||
@@ -55,6 +56,7 @@ import static org.mockito.Mockito.mock;
|
||||
* Tests for {@link ObservationAutoConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @author Jonatan Ivanov
|
||||
*/
|
||||
class ObservationAutoConfigurationTests {
|
||||
|
||||
@@ -63,7 +65,80 @@ class ObservationAutoConfigurationTests {
|
||||
.withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class));
|
||||
|
||||
private final ApplicationContextRunner tracingContextRunner = new ApplicationContextRunner()
|
||||
.with(MetricsRun.simple()).withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class));
|
||||
.with(MetricsRun.simple()).withUserConfiguration(TracerConfiguration.class)
|
||||
.withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void beansShouldNotBeSuppliedWhenMicrometerObservationIsNotOnClassPath() {
|
||||
this.tracingContextRunner.withClassLoader(new FilteredClassLoader("io.micrometer.observation"))
|
||||
.run((context) -> {
|
||||
assertThat(context).hasSingleBean(MeterRegistry.class);
|
||||
assertThat(context).doesNotHaveBean(ObservationRegistry.class);
|
||||
assertThat(context).doesNotHaveBean(ObservationHandler.class);
|
||||
assertThat(context).doesNotHaveBean(ObservationHandlerGrouping.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void supplyObservationRegistryWhenMicrometerCoreAndTracingAreNotOnClassPath() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader("io.micrometer.core", "io.micrometer.tracing"))
|
||||
.run((context) -> {
|
||||
ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class);
|
||||
Observation.start("test-observation", observationRegistry).stop();
|
||||
assertThat(context).doesNotHaveBean(ObservationHandler.class);
|
||||
assertThat(context).doesNotHaveBean(ObservationHandlerGrouping.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void supplyMeterHandlerAndGroupingWhenMicrometerCoreIsOnClassPathButTracingIsNot() {
|
||||
this.contextRunner.run((context) -> {
|
||||
ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class);
|
||||
Observation.start("test-observation", observationRegistry).stop();
|
||||
assertThat(context).hasSingleBean(ObservationHandler.class);
|
||||
assertThat(context).hasSingleBean(DefaultMeterObservationHandler.class);
|
||||
assertThat(context).hasSingleBean(ObservationHandlerGrouping.class);
|
||||
assertThat(context).hasBean("metricsObservationHandlerGrouping");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void supplyOnlyTracingObservationHandlerGroupingWhenMicrometerCoreIsNotOnClassPathButTracingIs() {
|
||||
this.tracingContextRunner.withClassLoader(new FilteredClassLoader("io.micrometer.core")).run((context) -> {
|
||||
ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class);
|
||||
Observation.start("test-observation", observationRegistry).stop();
|
||||
assertThat(context).doesNotHaveBean(ObservationHandler.class);
|
||||
assertThat(context).hasSingleBean(ObservationHandlerGrouping.class);
|
||||
assertThat(context).hasBean("tracingObservationHandlerGrouping");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void supplyMeterHandlerAndGroupingWhenMicrometerCoreAndTracingAreOnClassPath() {
|
||||
this.tracingContextRunner.run((context) -> {
|
||||
ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class);
|
||||
// Intentionally not stopped since that will trigger additional logic in
|
||||
// TracingAwareMeterObservationHandler that we don't test here
|
||||
Observation.start("test-observation", observationRegistry);
|
||||
assertThat(context).hasSingleBean(ObservationHandler.class);
|
||||
assertThat(context).hasSingleBean(TracingAwareMeterObservationHandler.class);
|
||||
assertThat(context).hasSingleBean(ObservationHandlerGrouping.class);
|
||||
assertThat(context).hasBean("metricsAndTracingObservationHandlerGrouping");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void supplyMeterHandlerAndGroupingWhenMicrometerCoreAndTracingAreOnClassPathButThereIsNoTracer() {
|
||||
new ApplicationContextRunner().with(MetricsRun.simple())
|
||||
.withConfiguration(AutoConfigurations.of(ObservationAutoConfiguration.class)).run((context) -> {
|
||||
ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class);
|
||||
Observation.start("test-observation", observationRegistry).stop();
|
||||
assertThat(context).hasSingleBean(ObservationHandler.class);
|
||||
assertThat(context).hasSingleBean(DefaultMeterObservationHandler.class);
|
||||
assertThat(context).hasSingleBean(ObservationHandlerGrouping.class);
|
||||
assertThat(context).hasBean("metricsAndTracingObservationHandlerGrouping");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoConfiguresDefaultMeterObservationHandler() {
|
||||
@@ -75,9 +150,17 @@ class ObservationAutoConfigurationTests {
|
||||
// Observation leads to a timer
|
||||
MeterRegistry meterRegistry = context.getBean(MeterRegistry.class);
|
||||
assertThat(meterRegistry.get("test-observation").timer().count()).isEqualTo(1);
|
||||
assertThat(context).hasSingleBean(DefaultMeterObservationHandler.class);
|
||||
assertThat(context).hasSingleBean(ObservationHandler.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void allowsDefaultMeterObservationHandlerToBeDisabled() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(MeterRegistry.class))
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(ObservationHandler.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoConfiguresObservationPredicates() {
|
||||
this.contextRunner.withUserConfiguration(ObservationPredicates.class).run((context) -> {
|
||||
@@ -119,6 +202,8 @@ class ObservationAutoConfigurationTests {
|
||||
assertThat(handlers.get(1)).isInstanceOf(CustomMeterObservationHandler.class);
|
||||
assertThat(((CustomMeterObservationHandler) handlers.get(1)).getName())
|
||||
.isEqualTo("customMeterObservationHandler1");
|
||||
assertThat(context).doesNotHaveBean(DefaultMeterObservationHandler.class);
|
||||
assertThat(context).doesNotHaveBean(TracingAwareMeterObservationHandler.class);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -132,9 +217,26 @@ class ObservationAutoConfigurationTests {
|
||||
Observation.start("test-observation", () -> customContext, observationRegistry).stop();
|
||||
assertThat(handlers).hasSize(1);
|
||||
assertThat(handlers.get(0)).isInstanceOf(ObservationHandlerWithCustomContext.class);
|
||||
assertThat(context).hasSingleBean(DefaultMeterObservationHandler.class);
|
||||
assertThat(context).doesNotHaveBean(TracingAwareMeterObservationHandler.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoConfiguresTracingAwareMeterObservationHandler() {
|
||||
this.tracingContextRunner.withUserConfiguration(CustomTracingObservationHandlers.class).run((context) -> {
|
||||
ObservationRegistry observationRegistry = context.getBean(ObservationRegistry.class);
|
||||
List<ObservationHandler<?>> handlers = context.getBean(CalledHandlers.class).getCalledHandlers();
|
||||
// Intentionally not stopped since that will trigger additional logic in
|
||||
// TracingAwareMeterObservationHandler that we don't test here
|
||||
Observation.start("test-observation", observationRegistry);
|
||||
assertThat(handlers).hasSize(1);
|
||||
assertThat(handlers.get(0)).isInstanceOf(CustomTracingObservationHandler.class);
|
||||
assertThat(context).hasSingleBean(TracingAwareMeterObservationHandler.class);
|
||||
assertThat(context.getBeansOfType(ObservationHandler.class)).hasSize(2);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoConfiguresObservationHandlerWhenTracingIsActive() {
|
||||
this.tracingContextRunner.withUserConfiguration(ObservationHandlersTracing.class).run((context) -> {
|
||||
@@ -156,6 +258,8 @@ class ObservationAutoConfigurationTests {
|
||||
assertThat(handlers.get(2)).isInstanceOf(CustomMeterObservationHandler.class);
|
||||
assertThat(((CustomMeterObservationHandler) handlers.get(2)).getName())
|
||||
.isEqualTo("customMeterObservationHandler1");
|
||||
assertThat(context).doesNotHaveBean(TracingAwareMeterObservationHandler.class);
|
||||
assertThat(context).doesNotHaveBean(DefaultMeterObservationHandler.class);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -236,6 +340,27 @@ class ObservationAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TracerConfiguration {
|
||||
|
||||
@Bean
|
||||
Tracer tracer() {
|
||||
return mock(Tracer.class); // simulating tracer configuration
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import(CalledHandlersConfiguration.class)
|
||||
static class CustomTracingObservationHandlers {
|
||||
|
||||
@Bean
|
||||
CustomTracingObservationHandler customTracingHandler1(CalledHandlers calledHandlers) {
|
||||
return new CustomTracingObservationHandler("customTracingHandler1", calledHandlers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import(CalledHandlersConfiguration.class)
|
||||
static class ObservationHandlersTracing {
|
||||
|
||||
Reference in New Issue
Block a user