Merge branch '2.2.x'
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.autoconfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -40,7 +39,6 @@ import zipkin2.reporter.Reporter;
|
||||
import zipkin2.reporter.ReporterMetrics;
|
||||
import zipkin2.reporter.metrics.micrometer.MicrometerReporterMetrics;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@@ -66,14 +64,13 @@ import org.springframework.util.StringUtils;
|
||||
* @author Marcin Grzejszczak
|
||||
* @author Tim Ysewyn
|
||||
* @since 2.0.0
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty(value = "spring.sleuth.enabled", matchIfMissing = true)
|
||||
@EnableConfigurationProperties(SleuthProperties.class)
|
||||
@Import({ TraceBaggageConfiguration.class, SamplerAutoConfiguration.class })
|
||||
// public allows @AutoConfigureAfter(TraceAutoConfiguration)
|
||||
// for components needing Tracing
|
||||
public class TraceAutoConfiguration {
|
||||
|
||||
/**
|
||||
@@ -86,19 +83,15 @@ public class TraceAutoConfiguration {
|
||||
*/
|
||||
public static final String DEFAULT_SERVICE_NAME = "default";
|
||||
|
||||
@Autowired(required = false)
|
||||
List<SpanHandler> spanHandlers = new ArrayList<>();
|
||||
|
||||
@Autowired(required = false)
|
||||
List<TracingCustomizer> tracingCustomizers = new ArrayList<>();
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
// NOTE: stable bean name as might be used outside sleuth
|
||||
Tracing tracing(@LocalServiceName String serviceName, Propagation.Factory factory,
|
||||
CurrentTraceContext currentTraceContext, Sampler sampler,
|
||||
ErrorParser errorParser, SleuthProperties sleuthProperties,
|
||||
@Nullable List<Reporter<zipkin2.Span>> spanReporters) {
|
||||
@Nullable List<Reporter<zipkin2.Span>> spanReporters,
|
||||
@Nullable List<SpanHandler> spanHandlers,
|
||||
@Nullable List<TracingCustomizer> tracingCustomizers) {
|
||||
Tracing.Builder builder = Tracing.newBuilder().sampler(sampler)
|
||||
.errorParser(errorParser)
|
||||
.localServiceName(StringUtils.isEmpty(serviceName) ? DEFAULT_SERVICE_NAME
|
||||
@@ -108,11 +101,15 @@ public class TraceAutoConfiguration {
|
||||
spanReporters != null ? spanReporters : Collections.emptyList()))
|
||||
.traceId128Bit(sleuthProperties.isTraceId128())
|
||||
.supportsJoin(sleuthProperties.isSupportsJoin());
|
||||
for (SpanHandler spanHandlerFactory : this.spanHandlers) {
|
||||
builder.addSpanHandler(spanHandlerFactory);
|
||||
if (spanHandlers != null) {
|
||||
for (SpanHandler spanHandlerFactory : spanHandlers) {
|
||||
builder.addSpanHandler(spanHandlerFactory);
|
||||
}
|
||||
}
|
||||
for (TracingCustomizer customizer : this.tracingCustomizers) {
|
||||
customizer.customize(builder);
|
||||
if (tracingCustomizers != null) {
|
||||
for (TracingCustomizer customizer : tracingCustomizers) {
|
||||
customizer.customize(builder);
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
@@ -129,9 +126,6 @@ public class TraceAutoConfiguration {
|
||||
return new DefaultSpanNamer();
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
List<CurrentTraceContextCustomizer> currentTraceContextCustomizers = new ArrayList<>();
|
||||
|
||||
@Bean
|
||||
CurrentTraceContext sleuthCurrentTraceContext(CurrentTraceContext.Builder builder,
|
||||
@Nullable List<CurrentTraceContext.ScopeDecorator> scopeDecorators,
|
||||
|
||||
@@ -29,10 +29,8 @@ import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @since 1.0.0
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
// public as most types in this package were documented for use
|
||||
public class LazyTraceAsyncCustomizer extends AsyncConfigurerSupport {
|
||||
|
||||
private final BeanFactory beanFactory;
|
||||
|
||||
@@ -35,10 +35,8 @@ import org.springframework.core.task.AsyncTaskExecutor;
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 2.1.0
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
// public as most types in this package were documented for use
|
||||
public class LazyTraceAsyncTaskExecutor implements AsyncTaskExecutor {
|
||||
|
||||
private static final Log log = LogFactory.getLog(LazyTraceAsyncTaskExecutor.class);
|
||||
|
||||
@@ -32,10 +32,8 @@ import org.springframework.cloud.sleuth.SpanNamer;
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @since 1.0.0
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
// public as most types in this package were documented for use
|
||||
public class LazyTraceExecutor implements Executor {
|
||||
|
||||
private static final Log log = LogFactory.getLog(LazyTraceExecutor.class);
|
||||
|
||||
@@ -39,11 +39,9 @@ import org.springframework.util.concurrent.ListenableFuture;
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.0.10
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("serial")
|
||||
// public as most types in this package were documented for use
|
||||
public class LazyTraceThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
|
||||
|
||||
private static final Log log = LogFactory
|
||||
|
||||
@@ -33,10 +33,8 @@ import org.springframework.cloud.sleuth.SpanNamer;
|
||||
* @author Spencer Gibb
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.0.0
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
// public as most types in this package were documented for use
|
||||
public class TraceCallable<V> implements Callable<V> {
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,10 +30,8 @@ import org.springframework.cloud.sleuth.SpanNamer;
|
||||
* @author Spencer Gibb
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.0.0
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
// public as most types in this package were documented for use
|
||||
public class TraceRunnable implements Runnable {
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,10 +36,8 @@ import org.springframework.cloud.sleuth.SpanNamer;
|
||||
*
|
||||
* @author Gaurav Rai Mazra
|
||||
* @since 1.0.0
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
// public as most types in this package were documented for use
|
||||
public class TraceableExecutorService implements ExecutorService {
|
||||
|
||||
final ExecutorService delegate;
|
||||
|
||||
@@ -29,10 +29,8 @@ import org.springframework.beans.factory.BeanFactory;
|
||||
*
|
||||
* @author Gaurav Rai Mazra
|
||||
* @since 1.0.0
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
// public as most types in this package were documented for use
|
||||
public class TraceableScheduledExecutorService extends TraceableExecutorService
|
||||
implements ScheduledExecutorService {
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.cloud.sleuth.instrument.messaging;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import brave.Span;
|
||||
@@ -47,7 +46,6 @@ import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.aop.framework.ProxyFactoryBean;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
@@ -77,10 +75,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 2.0.0
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnBean(Tracing.class)
|
||||
@ConditionalOnClass(MessagingTracing.class)
|
||||
@@ -88,17 +83,17 @@ import org.springframework.util.ReflectionUtils;
|
||||
TraceSpringMessagingAutoConfiguration.class })
|
||||
@OnMessagingEnabled
|
||||
@EnableConfigurationProperties(SleuthMessagingProperties.class)
|
||||
// public allows @AutoConfigureAfter(TraceMessagingAutoConfiguration)
|
||||
// for components needing MessagingTracing
|
||||
public class TraceMessagingAutoConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
List<MessagingTracingCustomizer> messagingTracingCustomizers = new ArrayList<>();
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
// NOTE: stable bean name as might be used outside sleuth
|
||||
MessagingTracing messagingTracing(Tracing tracing,
|
||||
@Nullable @ProducerSampler SamplerFunction<MessagingRequest> producerSampler,
|
||||
@Nullable @ConsumerSampler SamplerFunction<MessagingRequest> consumerSampler) {
|
||||
@Nullable @ConsumerSampler SamplerFunction<MessagingRequest> consumerSampler,
|
||||
@Nullable List<MessagingTracingCustomizer> messagingTracingCustomizers) {
|
||||
|
||||
MessagingTracing.Builder builder = MessagingTracing.newBuilder(tracing);
|
||||
if (producerSampler != null) {
|
||||
@@ -107,8 +102,10 @@ public class TraceMessagingAutoConfiguration {
|
||||
if (consumerSampler != null) {
|
||||
builder.consumerSampler(consumerSampler);
|
||||
}
|
||||
for (MessagingTracingCustomizer customizer : this.messagingTracingCustomizers) {
|
||||
customizer.customize(builder);
|
||||
if (messagingTracingCustomizers != null) {
|
||||
for (MessagingTracingCustomizer customizer : messagingTracingCustomizers) {
|
||||
customizer.customize(builder);
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.rpc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import brave.Tracing;
|
||||
@@ -25,7 +24,6 @@ import brave.rpc.RpcTracing;
|
||||
import brave.rpc.RpcTracingCustomizer;
|
||||
import brave.sampler.SamplerFunction;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
@@ -41,27 +39,24 @@ import org.springframework.lang.Nullable;
|
||||
* Auto-configuration} related to RPC based communication.
|
||||
*
|
||||
* @since 2.2.0
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty(name = "spring.sleuth.rpc.enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@ConditionalOnBean(Tracing.class)
|
||||
@ConditionalOnClass(RpcTracing.class)
|
||||
@AutoConfigureAfter(TraceAutoConfiguration.class)
|
||||
// public allows @AutoConfigureAfter(TraceRpcAutoConfiguration)
|
||||
// for components needing RpcTracing
|
||||
public class TraceRpcAutoConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
List<RpcTracingCustomizer> rpcTracingCustomizers = new ArrayList<>();
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
// NOTE: stable bean name as might be used outside sleuth
|
||||
RpcTracing rpcTracing(Tracing tracing,
|
||||
@Nullable @RpcClientSampler SamplerFunction<RpcRequest> clientSampler,
|
||||
@Nullable @RpcServerSampler SamplerFunction<RpcRequest> serverSampler) {
|
||||
@Nullable @RpcServerSampler SamplerFunction<RpcRequest> serverSampler,
|
||||
@Nullable List<RpcTracingCustomizer> rpcTracingCustomizers) {
|
||||
|
||||
RpcTracing.Builder builder = RpcTracing.newBuilder(tracing);
|
||||
if (clientSampler != null) {
|
||||
@@ -70,8 +65,10 @@ public class TraceRpcAutoConfiguration {
|
||||
if (serverSampler != null) {
|
||||
builder.serverSampler(serverSampler);
|
||||
}
|
||||
for (RpcTracingCustomizer customizer : this.rpcTracingCustomizers) {
|
||||
customizer.customize(builder);
|
||||
if (rpcTracingCustomizers != null) {
|
||||
for (RpcTracingCustomizer customizer : rpcTracingCustomizers) {
|
||||
customizer.customize(builder);
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -29,13 +28,15 @@ import brave.http.HttpTracingCustomizer;
|
||||
import brave.sampler.SamplerFunction;
|
||||
import brave.sampler.SamplerFunctions;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
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.cloud.sleuth.autoconfig.TraceAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
@@ -45,22 +46,25 @@ import org.springframework.lang.Nullable;
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 2.0.0
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnBean(TraceWebAutoConfiguration.class)
|
||||
@ConditionalOnProperty(name = "spring.sleuth.http.enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@AutoConfigureAfter(TraceWebAutoConfiguration.class)
|
||||
// This was formerly conditional on TraceWebAutoConfiguration, which was
|
||||
// conditional on "spring.sleuth.web.enabled". As this is conditional on
|
||||
// "spring.sleuth.http.enabled", to be compatible with old behavior we have
|
||||
// to be conditional on two properties.
|
||||
@ConditionalOnProperty(
|
||||
name = { "spring.sleuth.http.enabled", "spring.sleuth.web.enabled" },
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnBean(Tracing.class)
|
||||
@ConditionalOnClass(HttpTracing.class)
|
||||
@AutoConfigureAfter(TraceAutoConfiguration.class)
|
||||
@Import(TraceWebAutoConfiguration.class)
|
||||
// public allows @AutoConfigureAfter(TraceHttpAutoConfiguration)
|
||||
// for components needing HttpTracing
|
||||
public class TraceHttpAutoConfiguration {
|
||||
|
||||
static final int TRACING_FILTER_ORDER = Ordered.HIGHEST_PRECEDENCE + 5;
|
||||
|
||||
@Autowired(required = false)
|
||||
List<HttpTracingCustomizer> httpTracingCustomizers = new ArrayList<>();
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
// NOTE: stable bean name as might be used outside sleuth
|
||||
@@ -72,7 +76,8 @@ public class TraceHttpAutoConfiguration {
|
||||
@Nullable @HttpServerResponseParser HttpResponseParser httpServerResponseParser,
|
||||
@Nullable brave.http.HttpServerParser serverParser,
|
||||
@HttpClientSampler SamplerFunction<HttpRequest> httpClientSampler,
|
||||
@Nullable @HttpServerSampler SamplerFunction<HttpRequest> httpServerSampler) {
|
||||
@Nullable @HttpServerSampler SamplerFunction<HttpRequest> httpServerSampler,
|
||||
@Nullable List<HttpTracingCustomizer> httpTracingCustomizers) {
|
||||
SamplerFunction<HttpRequest> combinedSampler = combineUserProvidedSamplerWithSkipPatternSampler(
|
||||
httpServerSampler, provider);
|
||||
HttpTracing.Builder builder = HttpTracing.newBuilder(tracing)
|
||||
@@ -102,10 +107,11 @@ public class TraceHttpAutoConfiguration {
|
||||
builder.serverParser(serverParser);
|
||||
}
|
||||
|
||||
for (HttpTracingCustomizer customizer : this.httpTracingCustomizers) {
|
||||
customizer.customize(builder);
|
||||
if (httpTracingCustomizers != null) {
|
||||
for (HttpTracingCustomizer customizer : httpTracingCustomizers) {
|
||||
customizer.customize(builder);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.sleuth.instrument.web.TraceWebServletAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.instrument.web.TraceHttpAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.client.AsyncClientHttpRequestFactory;
|
||||
@@ -54,7 +54,7 @@ import org.springframework.web.client.AsyncRestTemplate;
|
||||
matchIfMissing = true)
|
||||
@ConditionalOnClass(AsyncRestTemplate.class)
|
||||
@ConditionalOnBean(HttpTracing.class)
|
||||
@AutoConfigureAfter(TraceWebServletAutoConfiguration.class)
|
||||
@AutoConfigureAfter(TraceHttpAutoConfiguration.class)
|
||||
public class TraceWebAsyncClientAutoConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
|
||||
@@ -42,7 +42,7 @@ import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoR
|
||||
import org.springframework.boot.web.client.RestTemplateCustomizer;
|
||||
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
|
||||
import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter;
|
||||
import org.springframework.cloud.sleuth.instrument.web.TraceWebServletAutoConfiguration;
|
||||
import org.springframework.cloud.sleuth.instrument.web.TraceHttpAutoConfiguration;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -69,7 +69,7 @@ import org.springframework.web.reactive.function.client.WebClient;
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@SleuthWebClientEnabled
|
||||
@ConditionalOnBean(HttpTracing.class)
|
||||
@AutoConfigureAfter(TraceWebServletAutoConfiguration.class)
|
||||
@AutoConfigureAfter(TraceHttpAutoConfiguration.class)
|
||||
@AutoConfigureBefore(HttpClientConfiguration.class)
|
||||
public class TraceWebClientAutoConfiguration {
|
||||
|
||||
|
||||
@@ -33,10 +33,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
* @author Marcin Grzejszczak
|
||||
* @see SamplerCondition
|
||||
* @since 2.1.0
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(SamplerProperties.class)
|
||||
// This is not auto-configuration, but it was in the past. Leaving the name as
|
||||
|
||||
@@ -46,10 +46,7 @@ import org.springframework.lang.Nullable;
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 2.1.1
|
||||
* @deprecated This type should have never been public and will be hidden or removed in
|
||||
* 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public final class TracingJmsListenerEndpointRegistry
|
||||
extends JmsListenerEndpointRegistry {
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
org.springframework.cloud.sleuth.annotation.SleuthAnnotationAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.instrument.web.TraceHttpAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.instrument.web.TraceWebAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.instrument.web.TraceWebServletAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.instrument.web.client.TraceWebClientAutoConfiguration,\
|
||||
org.springframework.cloud.sleuth.instrument.web.client.TraceWebAsyncClientAutoConfiguration,\
|
||||
|
||||
@@ -59,6 +59,11 @@
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-sleuth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.zipkin.brave</groupId>
|
||||
<artifactId>brave-tests</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
||||
@@ -16,180 +16,98 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.async;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import brave.Span;
|
||||
import brave.Tracer;
|
||||
import brave.Tracing;
|
||||
import brave.sampler.Sampler;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import brave.SpanCustomizer;
|
||||
import brave.handler.MutableSpan;
|
||||
import brave.handler.SpanHandler;
|
||||
import brave.propagation.CurrentTraceContext;
|
||||
import brave.propagation.CurrentTraceContext.Scope;
|
||||
import brave.propagation.TraceContext;
|
||||
import brave.test.IntegrationTestSpanHandler;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
|
||||
classes = { TraceAsyncIntegrationTests.TraceAsyncITestConfiguration.class })
|
||||
public class TraceAsyncIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
ClassPerformingAsyncLogic classPerformingAsyncLogic;
|
||||
@ClassRule
|
||||
public static IntegrationTestSpanHandler spans = new IntegrationTestSpanHandler();
|
||||
|
||||
TraceContext context = TraceContext.newBuilder().traceId(1).spanId(2).sampled(true)
|
||||
.build();
|
||||
|
||||
@Autowired
|
||||
Tracing tracer;
|
||||
AsyncLogic asyncLogic;
|
||||
|
||||
@Autowired
|
||||
ArrayListSpanReporter reporter;
|
||||
|
||||
@BeforeEach
|
||||
public void cleanup() {
|
||||
this.classPerformingAsyncLogic.clear();
|
||||
this.reporter.clear();
|
||||
}
|
||||
CurrentTraceContext currentTraceContext;
|
||||
|
||||
@Test
|
||||
public void should_set_span_on_an_async_annotated_method() {
|
||||
whenAsyncProcessingTakesPlace();
|
||||
asyncLogic.invokeAsync();
|
||||
|
||||
thenANewAsyncSpanGetsCreated();
|
||||
assertSpan_invokeAsync(takeDesirableSpan());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_set_span_with_custom_method_on_an_async_annotated_method() {
|
||||
whenAsyncProcessingTakesPlaceWithCustomSpanName();
|
||||
asyncLogic.invokeAsync_customName();
|
||||
|
||||
thenAsyncSpanHasCustomName();
|
||||
assertSpan_invokeAsync_customName(takeDesirableSpan());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_continue_a_span_on_an_async_annotated_method() {
|
||||
Span span = givenASpanInCurrentThread();
|
||||
try (Scope ws = currentTraceContext.maybeScope(context)) {
|
||||
asyncLogic.invokeAsync();
|
||||
|
||||
try (Tracer.SpanInScope ws = this.tracer.tracer().withSpanInScope(span.start())) {
|
||||
whenAsyncProcessingTakesPlace();
|
||||
|
||||
thenTraceIdIsPassedFromTheCurrentThreadToTheAsyncOne(span);
|
||||
}
|
||||
finally {
|
||||
span.finish();
|
||||
MutableSpan span = assertSpan_invokeAsync(takeDesirableSpan());
|
||||
assertThat(span.traceId()).isEqualTo(context.traceIdString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_continue_a_span_with_custom_method_on_an_async_annotated_method() {
|
||||
Span span = givenASpanInCurrentThread();
|
||||
try (Scope ws = currentTraceContext.maybeScope(context)) {
|
||||
asyncLogic.invokeAsync_customName();
|
||||
|
||||
try (Tracer.SpanInScope ws = this.tracer.tracer().withSpanInScope(span.start())) {
|
||||
whenAsyncProcessingTakesPlaceWithCustomSpanName();
|
||||
|
||||
thenTraceIdIsPassedFromTheCurrentThreadToTheAsyncOneAndSpanHasCustomName(
|
||||
span);
|
||||
}
|
||||
finally {
|
||||
span.finish();
|
||||
MutableSpan span = assertSpan_invokeAsync_customName(takeDesirableSpan());
|
||||
assertThat(span.traceId()).isEqualTo(context.traceIdString());
|
||||
}
|
||||
}
|
||||
|
||||
private Span givenASpanInCurrentThread() {
|
||||
return this.tracer.tracer().nextSpan().name("http:existing");
|
||||
static MutableSpan assertSpan_invokeAsync_customName(MutableSpan span) {
|
||||
assertThat(span.name()).isEqualTo("foo");
|
||||
assertThat(span.containsAnnotation("@Async")).isTrue();
|
||||
assertThat(span.tags()).containsEntry("class", "AsyncLogic")
|
||||
.containsEntry("method", "invokeAsync_customName");
|
||||
return span;
|
||||
}
|
||||
|
||||
private void whenAsyncProcessingTakesPlace() {
|
||||
this.classPerformingAsyncLogic.invokeAsynchronousLogic();
|
||||
static MutableSpan assertSpan_invokeAsync(MutableSpan span) {
|
||||
assertThat(span.name()).isEqualTo("invoke-async");
|
||||
assertThat(span.containsAnnotation("@Async")).isTrue();
|
||||
assertThat(span.tags()).containsEntry("class", "AsyncLogic")
|
||||
.containsEntry("method", "invokeAsync");
|
||||
return span;
|
||||
}
|
||||
|
||||
private void whenAsyncProcessingTakesPlaceWithCustomSpanName() {
|
||||
this.classPerformingAsyncLogic.customNameInvokeAsynchronousLogic();
|
||||
}
|
||||
|
||||
private void thenTraceIdIsPassedFromTheCurrentThreadToTheAsyncOne(final Span span) {
|
||||
Awaitility.await().atMost(5, SECONDS).untilAsserted(() -> {
|
||||
Span asyncSpan = TraceAsyncIntegrationTests.this.classPerformingAsyncLogic
|
||||
.getSpan();
|
||||
then(asyncSpan.context().traceId()).isEqualTo(span.context().traceId());
|
||||
List<zipkin2.Span> spans = TraceAsyncIntegrationTests.this.reporter
|
||||
.getSpans();
|
||||
zipkin2.Span reportedAsyncSpan = spans.stream()
|
||||
.filter(span2 -> span2.name().equals("invoke-asynchronous-logic"))
|
||||
.findFirst().orElseThrow(() -> new AssertionError(
|
||||
"Should have a span with custom name"));
|
||||
then(reportedAsyncSpan.traceId()).isEqualTo(span.context().traceIdString());
|
||||
then(reportedAsyncSpan.name()).isEqualTo("invoke-asynchronous-logic");
|
||||
then(reportedAsyncSpan.tags())
|
||||
.contains(new AbstractMap.SimpleEntry<>("class",
|
||||
"ClassPerformingAsyncLogic"))
|
||||
.contains(new AbstractMap.SimpleEntry<>("method",
|
||||
"invokeAsynchronousLogic"));
|
||||
});
|
||||
}
|
||||
|
||||
private void thenANewAsyncSpanGetsCreated() {
|
||||
Awaitility.await().atMost(5, SECONDS).untilAsserted(() -> {
|
||||
List<zipkin2.Span> spans = TraceAsyncIntegrationTests.this.reporter
|
||||
.getSpans();
|
||||
then(spans).hasSize(2);
|
||||
zipkin2.Span reportedAsyncSpan = spans.stream()
|
||||
.filter(span -> span.name().equals("invoke-asynchronous-logic"))
|
||||
.findFirst().orElseThrow(() -> new AssertionError(
|
||||
"Should have a span with custom name"));
|
||||
then(reportedAsyncSpan.tags())
|
||||
.contains(new AbstractMap.SimpleEntry<>("class",
|
||||
"ClassPerformingAsyncLogic"))
|
||||
.contains(new AbstractMap.SimpleEntry<>("method",
|
||||
"invokeAsynchronousLogic"));
|
||||
});
|
||||
}
|
||||
|
||||
private void thenTraceIdIsPassedFromTheCurrentThreadToTheAsyncOneAndSpanHasCustomName(
|
||||
final Span span) {
|
||||
Awaitility.await().atMost(5, SECONDS).untilAsserted(() -> {
|
||||
Span asyncSpan = TraceAsyncIntegrationTests.this.classPerformingAsyncLogic
|
||||
.getSpan();
|
||||
then(asyncSpan.context().traceId()).isEqualTo(span.context().traceId());
|
||||
List<zipkin2.Span> spans = TraceAsyncIntegrationTests.this.reporter
|
||||
.getSpans();
|
||||
then(spans).hasSize(2);
|
||||
zipkin2.Span reportedAsyncSpan = spans.stream()
|
||||
.filter(span2 -> span2.name().equals("foo")).findFirst()
|
||||
.orElseThrow(() -> new AssertionError(
|
||||
"Should have a span with custom name"));
|
||||
then(reportedAsyncSpan.traceId()).isEqualTo(span.context().traceIdString());
|
||||
then(reportedAsyncSpan.name()).isEqualTo("foo");
|
||||
then(reportedAsyncSpan.tags())
|
||||
.contains(new AbstractMap.SimpleEntry<>("class",
|
||||
"ClassPerformingAsyncLogic"))
|
||||
.contains(new AbstractMap.SimpleEntry<>("method",
|
||||
"customNameInvokeAsynchronousLogic"));
|
||||
});
|
||||
}
|
||||
|
||||
private void thenAsyncSpanHasCustomName() {
|
||||
Awaitility.await().atMost(5, SECONDS).untilAsserted(() -> {
|
||||
List<zipkin2.Span> spans = TraceAsyncIntegrationTests.this.reporter
|
||||
.getSpans();
|
||||
zipkin2.Span reportedAsyncSpan = spans.stream()
|
||||
.filter(span2 -> span2.name().equals("foo")).findFirst()
|
||||
.orElseThrow(() -> new AssertionError(
|
||||
"Should have a span with custom name"));
|
||||
then(reportedAsyncSpan.name()).isEqualTo("foo");
|
||||
then(reportedAsyncSpan.tags())
|
||||
.contains(new AbstractMap.SimpleEntry<>("class",
|
||||
"ClassPerformingAsyncLogic"))
|
||||
.contains(new AbstractMap.SimpleEntry<>("method",
|
||||
"customNameInvokeAsynchronousLogic"));
|
||||
});
|
||||
// Sleuth adds spans named "async" with no tags when an executor is used.
|
||||
// We don't want that one.
|
||||
MutableSpan takeDesirableSpan() {
|
||||
MutableSpan span1 = spans.takeLocalSpan();
|
||||
MutableSpan span2 = spans.takeLocalSpan();
|
||||
return span1.name().equals("async") ? span2 : span1;
|
||||
}
|
||||
|
||||
@DefaultTestAutoConfiguration
|
||||
@@ -198,49 +116,34 @@ public class TraceAsyncIntegrationTests {
|
||||
static class TraceAsyncITestConfiguration {
|
||||
|
||||
@Bean
|
||||
ClassPerformingAsyncLogic asyncClass(Tracer tracer) {
|
||||
return new ClassPerformingAsyncLogic(tracer);
|
||||
AsyncLogic asyncLogic(SpanCustomizer customizer) {
|
||||
return new AsyncLogic(customizer);
|
||||
}
|
||||
|
||||
@Bean
|
||||
Sampler defaultSampler() {
|
||||
return Sampler.ALWAYS_SAMPLE;
|
||||
}
|
||||
|
||||
@Bean
|
||||
ArrayListSpanReporter reporter() {
|
||||
return new ArrayListSpanReporter();
|
||||
SpanHandler spanHandler() {
|
||||
return spans;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class ClassPerformingAsyncLogic {
|
||||
static class AsyncLogic {
|
||||
|
||||
private final Tracer tracer;
|
||||
final SpanCustomizer customizer;
|
||||
|
||||
AtomicReference<Span> span = new AtomicReference<>();
|
||||
|
||||
ClassPerformingAsyncLogic(Tracer tracer) {
|
||||
this.tracer = tracer;
|
||||
AsyncLogic(SpanCustomizer customizer) {
|
||||
this.customizer = customizer;
|
||||
}
|
||||
|
||||
@Async
|
||||
public void invokeAsynchronousLogic() {
|
||||
this.span.set(this.tracer.currentSpan());
|
||||
public void invokeAsync() {
|
||||
customizer.annotate("@Async"); // proves the handler is in scope
|
||||
}
|
||||
|
||||
@Async
|
||||
@SpanName("foo")
|
||||
public void customNameInvokeAsynchronousLogic() {
|
||||
this.span.set(this.tracer.currentSpan());
|
||||
}
|
||||
|
||||
public Span getSpan() {
|
||||
return this.span.get();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.span.set(null);
|
||||
public void invokeAsync_customName() {
|
||||
customizer.annotate("@Async"); // proves the handler is in scope
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user