Browse Source

Auto-configure SpanTagAnnotationHandler

Closes gh-38662
pull/38968/head
Moritz Halbritter 2 years ago
parent
commit
c4be302fdb
  1. 40
      spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java
  2. 13
      spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java

40
spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfiguration.java

@ -1,5 +1,5 @@ @@ -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.
@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
package org.springframework.boot.actuate.autoconfigure.tracing;
import io.micrometer.common.annotation.ValueExpressionResolver;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.annotation.DefaultNewSpanParser;
import io.micrometer.tracing.annotation.ImperativeMethodInvocationProcessor;
@ -29,7 +30,7 @@ import io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler; @@ -29,7 +30,7 @@ import io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler;
import io.micrometer.tracing.propagation.Propagator;
import org.aspectj.weaver.Advice;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
@ -39,6 +40,10 @@ import org.springframework.context.annotation.Bean; @@ -39,6 +40,10 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
/**
* {@link EnableAutoConfiguration Auto-configuration} for the Micrometer Tracing API.
@ -104,14 +109,18 @@ public class MicrometerTracingAutoConfiguration { @@ -104,14 +109,18 @@ public class MicrometerTracingAutoConfiguration {
return new DefaultNewSpanParser();
}
@Bean
@ConditionalOnMissingBean
SpanTagAnnotationHandler spanTagAnnotationHandler(BeanFactory beanFactory) {
ValueExpressionResolver valueExpressionResolver = new SpelTagValueExpressionResolver();
return new SpanTagAnnotationHandler(beanFactory::getBean, (ignored) -> valueExpressionResolver);
}
@Bean
@ConditionalOnMissingBean(MethodInvocationProcessor.class)
ImperativeMethodInvocationProcessor imperativeMethodInvocationProcessor(NewSpanParser newSpanParser,
Tracer tracer, ObjectProvider<SpanTagAnnotationHandler> spanTagAnnotationHandler) {
ImperativeMethodInvocationProcessor methodInvocationProcessor = new ImperativeMethodInvocationProcessor(
newSpanParser, tracer);
spanTagAnnotationHandler.ifAvailable(methodInvocationProcessor::setSpanTagAnnotationHandler);
return methodInvocationProcessor;
Tracer tracer, SpanTagAnnotationHandler spanTagAnnotationHandler) {
return new ImperativeMethodInvocationProcessor(newSpanParser, tracer, spanTagAnnotationHandler);
}
@Bean
@ -122,4 +131,21 @@ public class MicrometerTracingAutoConfiguration { @@ -122,4 +131,21 @@ public class MicrometerTracingAutoConfiguration {
}
private static class SpelTagValueExpressionResolver implements ValueExpressionResolver {
@Override
public String resolve(String expression, Object parameter) {
try {
SimpleEvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expressionToEvaluate = expressionParser.parseExpression(expression);
return expressionToEvaluate.getValue(context, parameter, String.class);
}
catch (Exception ex) {
throw new IllegalStateException("Unable to evaluate SpEL expression '%s'".formatted(expression), ex);
}
}
}
}

13
spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/MicrometerTracingAutoConfigurationTests.java

@ -1,5 +1,5 @@ @@ -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.
@ -18,6 +18,8 @@ package org.springframework.boot.actuate.autoconfigure.tracing; @@ -18,6 +18,8 @@ package org.springframework.boot.actuate.autoconfigure.tracing;
import java.util.List;
import io.micrometer.common.annotation.ValueExpressionResolver;
import io.micrometer.common.annotation.ValueResolver;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.annotation.DefaultNewSpanParser;
import io.micrometer.tracing.annotation.ImperativeMethodInvocationProcessor;
@ -63,6 +65,7 @@ class MicrometerTracingAutoConfigurationTests { @@ -63,6 +65,7 @@ class MicrometerTracingAutoConfigurationTests {
assertThat(context).hasSingleBean(DefaultNewSpanParser.class);
assertThat(context).hasSingleBean(ImperativeMethodInvocationProcessor.class);
assertThat(context).hasSingleBean(SpanAspect.class);
assertThat(context).hasSingleBean(SpanTagAnnotationHandler.class);
});
}
@ -100,6 +103,8 @@ class MicrometerTracingAutoConfigurationTests { @@ -100,6 +103,8 @@ class MicrometerTracingAutoConfigurationTests {
assertThat(context).hasSingleBean(ImperativeMethodInvocationProcessor.class);
assertThat(context).hasBean("customSpanAspect");
assertThat(context).hasSingleBean(SpanAspect.class);
assertThat(context).hasBean("customSpanTagAnnotationHandler");
assertThat(context).hasSingleBean(SpanTagAnnotationHandler.class);
});
}
@ -215,6 +220,12 @@ class MicrometerTracingAutoConfigurationTests { @@ -215,6 +220,12 @@ class MicrometerTracingAutoConfigurationTests {
return new SpanAspect(methodInvocationProcessor);
}
@Bean
SpanTagAnnotationHandler customSpanTagAnnotationHandler() {
return new SpanTagAnnotationHandler((aClass) -> mock(ValueResolver.class),
(aClass) -> mock(ValueExpressionResolver.class));
}
}
@Configuration(proxyBeanMethods = false)

Loading…
Cancel
Save