Add noop tracer bean if tracing is disabled
The new functionality doesn't expose any public API and works the same as WebTestClientContextCustomizer does. Closes gh-32907
This commit is contained in:
@@ -19,17 +19,36 @@ package org.springframework.boot.test.autoconfigure.actuate.observability;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import io.micrometer.tracing.Tracer;
|
||||
|
||||
import org.springframework.aot.AotDetector;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.test.context.ContextConfigurationAttributes;
|
||||
import org.springframework.test.context.ContextCustomizer;
|
||||
import org.springframework.test.context.ContextCustomizerFactory;
|
||||
import org.springframework.test.context.MergedContextConfiguration;
|
||||
import org.springframework.test.context.TestContextAnnotationUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link ContextCustomizerFactory} that globally disables metrics export and tracing
|
||||
* unless {@link AutoConfigureObservability} is set on the test class.
|
||||
* <p>
|
||||
* Registers {@link Tracer#NOOP} if tracing is disabled, micrometer-tracing is on the
|
||||
* classpath, and the user hasn't supplied their own {@link Tracer}.
|
||||
*
|
||||
* @author Chris Bono
|
||||
* @author Moritz Halbritter
|
||||
@@ -44,11 +63,10 @@ class ObservabilityContextCustomizerFactory implements ContextCustomizerFactory
|
||||
if (annotation == null) {
|
||||
return new DisableObservabilityContextCustomizer(true, true);
|
||||
}
|
||||
|
||||
return new DisableObservabilityContextCustomizer(!annotation.metrics(), !annotation.tracing());
|
||||
}
|
||||
|
||||
static class DisableObservabilityContextCustomizer implements ContextCustomizer {
|
||||
private static class DisableObservabilityContextCustomizer implements ContextCustomizer {
|
||||
|
||||
private final boolean disableMetrics;
|
||||
|
||||
@@ -68,9 +86,29 @@ class ObservabilityContextCustomizerFactory implements ContextCustomizerFactory
|
||||
}
|
||||
if (this.disableTracing) {
|
||||
TestPropertyValues.of("management.tracing.enabled=false").applyTo(context);
|
||||
registerNoopTracer(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerNoopTracer(ConfigurableApplicationContext context) {
|
||||
if (AotDetector.useGeneratedArtifacts()) {
|
||||
return;
|
||||
}
|
||||
if (!ClassUtils.isPresent("io.micrometer.tracing.Tracer", context.getClassLoader())) {
|
||||
return;
|
||||
}
|
||||
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
|
||||
if (beanFactory instanceof BeanDefinitionRegistry registry) {
|
||||
registerNoopTracer(registry);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerNoopTracer(BeanDefinitionRegistry registry) {
|
||||
RootBeanDefinition definition = new RootBeanDefinition(NoopTracerRegistrar.class);
|
||||
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
registry.registerBeanDefinition(NoopTracerRegistrar.class.getName(), definition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@@ -90,4 +128,40 @@ class ObservabilityContextCustomizerFactory implements ContextCustomizerFactory
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link BeanDefinitionRegistryPostProcessor} that runs after the
|
||||
* {@link ConfigurationClassPostProcessor} and adds a {@link Tracer} bean definition
|
||||
* when a {@link Tracer} hasn't already been registered.
|
||||
*/
|
||||
private static class NoopTracerRegistrar implements BeanDefinitionRegistryPostProcessor, Ordered, BeanFactoryAware {
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
|
||||
if (AotDetector.useGeneratedArtifacts()) {
|
||||
return;
|
||||
}
|
||||
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors((ListableBeanFactory) this.beanFactory,
|
||||
Tracer.class, false, false).length == 0) {
|
||||
registry.registerBeanDefinition("noopTracer", new RootBeanDefinition(Tracer.class, () -> Tracer.NOOP));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user