From f834e5222b19f24e6421bcfd52d46e9c810f0530 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 6 Jun 2017 08:05:27 +0200 Subject: [PATCH] Added the ErrorParser interface without this change there's no way to alter the exception message that gets attached as a tag to the span with this change you can register your own ErrorParser bean to alter that behaviour fixes #576 --- .../cloud/sleuth/ErrorParser.java | 22 ++++ .../sleuth/ExceptionMessageErrorParser.java | 28 ++++ .../springframework/cloud/sleuth/Span.java | 10 +- .../annotation/SleuthAdvisorConfig.java | 12 +- .../autoconfig/TraceAutoConfiguration.java | 8 ++ .../AbstractTraceChannelInterceptor.java | 44 ++++++- .../IntegrationTraceChannelInterceptor.java | 7 +- .../messaging/TraceChannelInterceptor.java | 9 +- ...aceSpringIntegrationAutoConfiguration.java | 10 +- .../sleuth/instrument/web/TraceFilter.java | 122 +++++++++++++----- .../web/TraceHandlerInterceptor.java | 16 ++- .../sleuth/instrument/web/TraceWebAspect.java | 16 ++- .../web/TraceWebAutoConfiguration.java | 15 +-- .../web/client/TraceAsyncRestTemplate.java | 58 ++++++++- .../client/TraceRestTemplateInterceptor.java | 18 ++- .../TraceWebClientAutoConfiguration.java | 12 +- .../web/client/feign/TraceFeignClient.java | 22 +++- .../ExceptionMessageErrorParserTests.java | 32 +++++ .../cloud/sleuth/SpanTests.java | 8 +- .../async/MultipleAsyncRestTemplateTests.java | 2 - .../async/issues/issue410/Issue410Tests.java | 1 - .../HystrixAnnotationsIntegrationTests.java | 1 - .../MessagingSpanExtractorTests.java | 1 - .../messaging/MessagingSpanInjectorTests.java | 1 - .../instrument/rxjava/SleuthRxJavaTests.java | 1 - .../scheduling/TracingOnScheduledTests.java | 1 - ...stTemplateTraceAspectIntegrationTests.java | 1 - .../web/SpringDataInstrumentationTests.java | 1 - ...ceFilterAlwaysSamplerIntegrationTests.java | 23 +++- .../TraceFilterMockChainIntegrationTests.java | 25 +++- .../instrument/web/TraceFilterTests.java | 94 ++++++++------ ...stTemplateInterceptorIntegrationTests.java | 12 +- .../TraceRestTemplateInterceptorTests.java | 4 +- .../exception/WebClientExceptionTests.java | 1 - .../exceptionresolver/Issue585Tests.java | 1 - .../web/client/feign/FeignRetriesTests.java | 21 +-- .../client/feign/TraceFeignClientTests.java | 13 +- .../FeignClientServerErrorTests.java | 1 - .../client/integration/WebClientTests.java | 1 - .../zuul/TraceZuulIntegrationTests.java | 1 - .../zipkin/ZipkinSpanListenerTests.java | 1 - 41 files changed, 493 insertions(+), 184 deletions(-) create mode 100644 spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/ErrorParser.java create mode 100644 spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/ExceptionMessageErrorParser.java create mode 100644 spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/ExceptionMessageErrorParserTests.java diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/ErrorParser.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/ErrorParser.java new file mode 100644 index 000000000..97033d406 --- /dev/null +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/ErrorParser.java @@ -0,0 +1,22 @@ +package org.springframework.cloud.sleuth; + +/** + * Contract for hooking into process of adding error response tags. + * This interface is only called when an exception is thrown upon receiving a response. + * (e.g. a response of 500 may not be an exception). + * + * @author Marcin Grzejszczak + * @since 1.2.1 + */ +public interface ErrorParser { + + /** + * Allows setting of tags when an exception was thrown when the response was received. + * The implementation should not manipulate the {@link Span} in other way than just + * by adding the tags. + * + * @param span - current span in context + * @param error - error that was thrown upon receiving a response + */ + void parseErrorTags(Span span, Throwable error); +} diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/ExceptionMessageErrorParser.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/ExceptionMessageErrorParser.java new file mode 100644 index 000000000..8d2781376 --- /dev/null +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/ExceptionMessageErrorParser.java @@ -0,0 +1,28 @@ +package org.springframework.cloud.sleuth; + +import java.lang.invoke.MethodHandles; + +import org.apache.commons.logging.LogFactory; +import org.springframework.cloud.sleuth.util.ExceptionUtils; + +/** + * {@link ErrorParser} that sets the error tag for an exportable span. + * + * @author Marcin Grzejszczak + * @since 1.2.1 + */ +public class ExceptionMessageErrorParser implements ErrorParser { + + private static final org.apache.commons.logging.Log log = LogFactory.getLog(MethodHandles.lookup().lookupClass()); + + @Override + public void parseErrorTags(Span span, Throwable error) { + if (span.isExportable()) { + String errorMsg = ExceptionUtils.getExceptionMessage(error); + if (log.isDebugEnabled()) { + log.debug("Adding an error tag [" + errorMsg + "] to span " + span); + } + span.tag(Span.SPAN_ERROR_TAG_NAME, errorMsg); + } + } +} diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/Span.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/Span.java index f8146c946..33c5d09bc 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/Span.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/Span.java @@ -16,6 +16,10 @@ package org.springframework.cloud.sleuth; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -31,10 +35,6 @@ import java.util.concurrent.ConcurrentLinkedQueue; import org.springframework.util.Assert; import org.springframework.util.StringUtils; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonInclude; - /** * Class for gathering and reporting statistics about a block of execution. *

@@ -769,7 +769,7 @@ public class Span implements SpanContext { public Span.SpanBuilder from(Span span) { return begin(span.begin).end(span.end).name(span.name) .traceIdHigh(span.traceIdHigh).traceId(span.traceId) - .parents(span.getParents()).logs(span.logs).tags(span.tags) + .parents(span.getParents()).logs(span.logs).tags(span.tags).baggage(span.baggage) .spanId(span.spanId).remote(span.remote).exportable(span.exportable) .processId(span.processId).savedSpan(span.savedSpan); } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAdvisorConfig.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAdvisorConfig.java index 19452465f..136f05816 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAdvisorConfig.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/annotation/SleuthAdvisorConfig.java @@ -37,9 +37,9 @@ import org.springframework.aop.support.annotation.AnnotationClassFilter; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.cloud.sleuth.ErrorParser; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.util.ExceptionUtils; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; @@ -229,6 +229,7 @@ class SleuthInterceptor implements IntroductionInterceptor, BeanFactoryAware { private SpanCreator spanCreator; private Tracer tracer; private SpanTagAnnotationHandler spanTagAnnotationHandler; + private ErrorParser errorParser; @Override public Object invoke(MethodInvocation invocation) throws Throwable { @@ -262,7 +263,7 @@ class SleuthInterceptor implements IntroductionInterceptor, BeanFactoryAware { if (hasLog) { logEvent(span, log + ".afterFailure"); } - tracer().addTag(Span.SPAN_ERROR_TAG_NAME, ExceptionUtils.getExceptionMessage(e)); + errorParser().parseErrorTags(tracer().getCurrentSpan(), e); throw e; } finally { if (span != null) { @@ -314,6 +315,13 @@ class SleuthInterceptor implements IntroductionInterceptor, BeanFactoryAware { return this.spanTagAnnotationHandler; } + private ErrorParser errorParser() { + if (this.errorParser == null) { + this.errorParser = this.beanFactory.getBean(ErrorParser.class); + } + return this.errorParser; + } + @Override public boolean implementsInterface(Class intf) { return true; } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java index 57d6d85de..e692ab863 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java @@ -23,6 +23,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.sleuth.DefaultSpanNamer; +import org.springframework.cloud.sleuth.ErrorParser; +import org.springframework.cloud.sleuth.ExceptionMessageErrorParser; import org.springframework.cloud.sleuth.NoOpSpanAdjuster; import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Sampler; @@ -91,4 +93,10 @@ public class TraceAutoConfiguration { return new NoOpSpanAdjuster(); } + @Bean + @ConditionalOnMissingBean + public ErrorParser defaultErrorParser() { + return new ExceptionMessageErrorParser(); + } + } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/AbstractTraceChannelInterceptor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/AbstractTraceChannelInterceptor.java index 520211a76..49b1dd62c 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/AbstractTraceChannelInterceptor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/AbstractTraceChannelInterceptor.java @@ -4,6 +4,9 @@ import java.lang.invoke.MethodHandles; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.sleuth.ErrorParser; +import org.springframework.cloud.sleuth.ExceptionMessageErrorParser; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanTextMap; import org.springframework.cloud.sleuth.TraceKeys; @@ -36,11 +39,14 @@ abstract class AbstractTraceChannelInterceptor extends ChannelInterceptorAdapter */ protected static final String MESSAGE_COMPONENT = "message"; - private final Tracer tracer; - private final TraceKeys traceKeys; - private final MessagingSpanTextMapExtractor spanExtractor; - private final MessagingSpanTextMapInjector spanInjector; + private Tracer tracer; + private TraceKeys traceKeys; + private MessagingSpanTextMapExtractor spanExtractor; + private MessagingSpanTextMapInjector spanInjector; + private ErrorParser errorParser; + private BeanFactory beanFactory; + @Deprecated protected AbstractTraceChannelInterceptor(Tracer tracer, TraceKeys traceKeys, MessagingSpanTextMapExtractor spanExtractor, MessagingSpanTextMapInjector spanInjector) { @@ -48,27 +54,55 @@ abstract class AbstractTraceChannelInterceptor extends ChannelInterceptorAdapter this.traceKeys = traceKeys; this.spanExtractor = spanExtractor; this.spanInjector = spanInjector; + this.errorParser = new ExceptionMessageErrorParser(); + } + + protected AbstractTraceChannelInterceptor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; } protected Tracer getTracer() { + if (this.tracer == null) { + this.tracer = this.beanFactory.getBean(Tracer.class); + } return this.tracer; } protected TraceKeys getTraceKeys() { + if (this.traceKeys == null) { + this.traceKeys = this.beanFactory.getBean(TraceKeys.class); + } return this.traceKeys; } + protected MessagingSpanTextMapExtractor getSpanExtractor() { + if (this.spanExtractor == null) { + this.spanExtractor = this.beanFactory.getBean(MessagingSpanTextMapExtractor.class); + } + return this.spanExtractor; + } + protected MessagingSpanTextMapInjector getSpanInjector() { + if (this.spanInjector == null) { + this.spanInjector = this.beanFactory.getBean(MessagingSpanTextMapInjector.class); + } return this.spanInjector; } + protected ErrorParser getErrorParser() { + if (this.errorParser == null) { + this.errorParser = this.beanFactory.getBean(ErrorParser.class); + } + return this.errorParser; + } + /** * Returns a span given the message and a channel. Returns {@code null} if ids are * missing. */ protected Span buildSpan(SpanTextMap carrier) { try { - return this.spanExtractor.joinTrace(carrier); + return getSpanExtractor().joinTrace(carrier); } catch (Exception e) { log.error("Exception occurred while trying to extract span from carrier", e); return null; diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/IntegrationTraceChannelInterceptor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/IntegrationTraceChannelInterceptor.java index 5cc14ca11..fcbcb7438 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/IntegrationTraceChannelInterceptor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/IntegrationTraceChannelInterceptor.java @@ -16,6 +16,7 @@ package org.springframework.cloud.sleuth.instrument.messaging; +import org.springframework.beans.factory.BeanFactory; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; import org.springframework.integration.channel.ChannelInterceptorAware; @@ -28,13 +29,17 @@ import org.springframework.messaging.support.ChannelInterceptor; */ class IntegrationTraceChannelInterceptor extends TraceChannelInterceptor implements VetoCapableInterceptor { - + @Deprecated public IntegrationTraceChannelInterceptor(Tracer tracer, TraceKeys traceKeys, MessagingSpanTextMapExtractor spanExtractor, MessagingSpanTextMapInjector spanInjector) { super(tracer, traceKeys, spanExtractor, spanInjector); } + public IntegrationTraceChannelInterceptor(BeanFactory beanFactory) { + super(beanFactory); + } + @Override public boolean shouldIntercept(String beanName, ChannelInterceptorAware channel) { for (ChannelInterceptor interceptor : channel.getChannelInterceptors()) { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceChannelInterceptor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceChannelInterceptor.java index 9da6a0cc2..954dd5f0b 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceChannelInterceptor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceChannelInterceptor.java @@ -16,12 +16,12 @@ package org.springframework.cloud.sleuth.instrument.messaging; +import org.springframework.beans.factory.BeanFactory; import org.springframework.cloud.sleuth.Log; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.sampler.NeverSampler; -import org.springframework.cloud.sleuth.util.ExceptionUtils; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessageHandler; @@ -38,12 +38,17 @@ import org.springframework.messaging.support.MessageHeaderAccessor; */ public class TraceChannelInterceptor extends AbstractTraceChannelInterceptor { + @Deprecated public TraceChannelInterceptor(Tracer tracer, TraceKeys traceKeys, MessagingSpanTextMapExtractor spanExtractor, MessagingSpanTextMapInjector spanInjector) { super(tracer, traceKeys, spanExtractor, spanInjector); } + public TraceChannelInterceptor(BeanFactory beanFactory) { + super(beanFactory); + } + @Override public void afterSendCompletion(Message message, MessageChannel channel, boolean sent, Exception ex) { Span currentSpan = getTracer().getCurrentSpan(); @@ -124,7 +129,7 @@ public class TraceChannelInterceptor extends AbstractTraceChannelInterceptor { private void addErrorTag(Exception ex) { if (ex != null) { - getTracer().addTag(Span.SPAN_ERROR_TAG_NAME, ExceptionUtils.getExceptionMessage(ex)); + getErrorParser().parseErrorTags(getTracer().getCurrentSpan(), ex); } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java index 31111ea55..104083f43 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/messaging/TraceSpringIntegrationAutoConfiguration.java @@ -16,8 +16,7 @@ package org.springframework.cloud.sleuth.instrument.messaging; -import java.util.Random; - +import org.springframework.beans.factory.BeanFactory; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -51,11 +50,8 @@ public class TraceSpringIntegrationAutoConfiguration { @Bean @GlobalChannelInterceptor(patterns = "${spring.sleuth.integration.patterns:*}") - public TraceChannelInterceptor traceChannelInterceptor(Tracer tracer, - TraceKeys traceKeys, Random random, MessagingSpanTextMapExtractor spanExtractor, - MessagingSpanTextMapInjector spanInjector) { - return new IntegrationTraceChannelInterceptor(tracer, traceKeys, spanExtractor, - spanInjector); + public TraceChannelInterceptor traceChannelInterceptor(BeanFactory beanFactory) { + return new IntegrationTraceChannelInterceptor(beanFactory); } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java index 17b01b8c5..2b0657581 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java @@ -30,13 +30,15 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.cloud.sleuth.ErrorParser; +import org.springframework.cloud.sleuth.ExceptionMessageErrorParser; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.sampler.NeverSampler; -import org.springframework.cloud.sleuth.util.ExceptionUtils; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; @@ -95,15 +97,18 @@ public class TraceFilter extends GenericFilterBean { @Deprecated public static final String DEFAULT_SKIP_PATTERN = SleuthWebProperties.DEFAULT_SKIP_PATTERN; - private final Tracer tracer; - private final TraceKeys traceKeys; - private final Pattern skipPattern; - private final SpanReporter spanReporter; - private final HttpSpanExtractor spanExtractor; - private final HttpTraceKeysInjector httpTraceKeysInjector; + private Tracer tracer; + private TraceKeys traceKeys; + private Pattern skipPattern; + private SpanReporter spanReporter; + private HttpSpanExtractor spanExtractor; + private HttpTraceKeysInjector httpTraceKeysInjector; + private ErrorParser errorParser; + private BeanFactory beanFactory; private UrlPathHelper urlPathHelper = new UrlPathHelper(); + @Deprecated public TraceFilter(Tracer tracer, TraceKeys traceKeys, SpanReporter spanReporter, HttpSpanExtractor spanExtractor, HttpTraceKeysInjector httpTraceKeysInjector) { @@ -111,6 +116,7 @@ public class TraceFilter extends GenericFilterBean { spanExtractor, httpTraceKeysInjector); } + @Deprecated public TraceFilter(Tracer tracer, TraceKeys traceKeys, Pattern skipPattern, SpanReporter spanReporter, HttpSpanExtractor spanExtractor, HttpTraceKeysInjector httpTraceKeysInjector) { @@ -120,6 +126,16 @@ public class TraceFilter extends GenericFilterBean { this.spanReporter = spanReporter; this.spanExtractor = spanExtractor; this.httpTraceKeysInjector = httpTraceKeysInjector; + this.errorParser = new ExceptionMessageErrorParser(); + } + + public TraceFilter(BeanFactory beanFactory) { + this(beanFactory, Pattern.compile(SleuthWebProperties.DEFAULT_SKIP_PATTERN)); + } + + public TraceFilter(BeanFactory beanFactory, Pattern skipPattern) { + this.beanFactory = beanFactory; + this.skipPattern = skipPattern; } @Override @@ -153,7 +169,7 @@ public class TraceFilter extends GenericFilterBean { filterChain.doFilter(request, new TraceHttpServletResponse(response, spanFromRequest)); } catch (Throwable e) { exception = e; - this.tracer.addTag(Span.SPAN_ERROR_TAG_NAME, ExceptionUtils.getExceptionMessage(e)); + errorParser().parseErrorTags(tracer().getCurrentSpan(), e); throw e; } finally { if (isAsyncStarted(request) || request.isAsyncStarted()) { @@ -190,13 +206,13 @@ public class TraceFilter extends GenericFilterBean { request.setAttribute(TRACE_ERROR_HANDLED_REQUEST_ATTR, true); addResponseTags(response, null); if (request.getAttribute(TraceRequestAttributes.ERROR_HANDLED_SPAN_REQUEST_ATTR) == null) { - this.tracer.close(spanFromRequest); + tracer().close(spanFromRequest); } } } private void continueSpan(HttpServletRequest request, Span spanFromRequest) { - this.tracer.continueSpan(spanFromRequest); + tracer().continueSpan(spanFromRequest); request.setAttribute(TraceRequestAttributes.SPAN_CONTINUED_REQUEST_ATTR, "true"); if (log.isDebugEnabled()) { log.debug("There has already been a span in the request " + spanFromRequest); @@ -208,7 +224,7 @@ public class TraceFilter extends GenericFilterBean { private Span createSpanIfRequestNotHandled(HttpServletRequest request, Span spanFromRequest, String name, boolean skip) { if (!requestHasAlreadyBeenHandled(request)) { - spanFromRequest = this.tracer.createSpan(name); + spanFromRequest = tracer().createSpan(name); request.setAttribute(TRACE_REQUEST_ATTR, spanFromRequest); if (log.isDebugEnabled() && !skip) { log.debug("The request with uri [" + request.getRequestURI() + "] hasn't been handled by any of Sleuth's components. " @@ -231,38 +247,38 @@ public class TraceFilter extends GenericFilterBean { if (span.hasSavedSpan() && requestHasAlreadyBeenHandled(request)) { recordParentSpan(span.getSavedSpan()); } else if (!requestHasAlreadyBeenHandled(request)) { - span = this.tracer.close(span); + span = tracer().close(span); } recordParentSpan(span); // in case of a response with exception status will close the span when exception dispatch is handled // checking if tracing is in progress due to async / different order of view controller processing - if (httpStatusSuccessful(response) && this.tracer.isTracing()) { + if (httpStatusSuccessful(response) && tracer().isTracing()) { if (log.isDebugEnabled()) { log.debug("Closing the span " + span + " since the response was successful"); } - this.tracer.close(span); - } else if (errorAlreadyHandled(request) && this.tracer.isTracing()) { + tracer().close(span); + } else if (errorAlreadyHandled(request) && tracer().isTracing()) { if (log.isDebugEnabled()) { log.debug( "Won't detach the span " + span + " since error has already been handled"); } - } else if (shouldCloseSpan(request) && this.tracer.isTracing() && stillTracingCurrentSapn(span)) { + } else if (shouldCloseSpan(request) && tracer().isTracing() && stillTracingCurrentSapn(span)) { if (log.isDebugEnabled()) { log.debug( "Will close span " + span + " since some component marked it for closure"); } - this.tracer.close(span); - } else if (this.tracer.isTracing()) { + tracer().close(span); + } else if (tracer().isTracing()) { if (log.isDebugEnabled()) { log.debug("Detaching the span " + span + " since the response was unsuccessful"); } - this.tracer.detach(span); + tracer().detach(span); } } } private boolean stillTracingCurrentSapn(Span span) { - return this.tracer.getCurrentSpan().equals(span); + return tracer().getCurrentSpan().equals(span); } private void recordParentSpan(Span parent) { @@ -276,7 +292,7 @@ public class TraceFilter extends GenericFilterBean { parent.stop(); // should be already done by HttpServletResponse wrappers SsLogSetter.annotateWithServerSendIfLogIsNotAlreadyPresent(parent); - this.spanReporter.report(parent); + spanReporter().report(parent); } else { // should be already done by HttpServletResponse wrappers SsLogSetter.annotateWithServerSendIfLogIsNotAlreadyPresent(parent); @@ -330,14 +346,14 @@ public class TraceFilter extends GenericFilterBean { } return spanFromRequest; } - Span parent = this.spanExtractor.joinTrace(new HttpServletRequestTextMap(request)); + Span parent = spanExtractor().joinTrace(new HttpServletRequestTextMap(request)); if (parent != null) { if (log.isDebugEnabled()) { log.debug("Found a parent span " + parent + " in the request"); } addRequestTagsForParentSpan(request, parent); spanFromRequest = parent; - this.tracer.continueSpan(spanFromRequest); + tracer().continueSpan(spanFromRequest); if (parent.isRemote()) { parent.logEvent(Span.SERVER_RECV); } @@ -347,14 +363,14 @@ public class TraceFilter extends GenericFilterBean { } } else { if (skip) { - spanFromRequest = this.tracer.createSpan(name, NeverSampler.INSTANCE); + spanFromRequest = tracer().createSpan(name, NeverSampler.INSTANCE); } else { String header = request.getHeader(Span.SPAN_FLAGS); if (Span.SPAN_SAMPLED.equals(header)) { - spanFromRequest = this.tracer.createSpan(name, new AlwaysSampler()); + spanFromRequest = tracer().createSpan(name, new AlwaysSampler()); } else { - spanFromRequest = this.tracer.createSpan(name); + spanFromRequest = tracer().createSpan(name); } } spanFromRequest.logEvent(Span.SERVER_RECV); @@ -369,16 +385,16 @@ public class TraceFilter extends GenericFilterBean { /** Override to add annotations not defined in {@link TraceKeys}. */ protected void addRequestTags(Span span, HttpServletRequest request) { String uri = this.urlPathHelper.getPathWithinApplication(request); - this.httpTraceKeysInjector.addRequestTags(span, getFullUrl(request), + keysInjector().addRequestTags(span, getFullUrl(request), request.getServerName(), uri, request.getMethod()); - for (String name : this.traceKeys.getHttp().getHeaders()) { + for (String name : traceKeys().getHttp().getHeaders()) { Enumeration values = request.getHeaders(name); if (values.hasMoreElements()) { - String key = this.traceKeys.getHttp().getPrefix() + name.toLowerCase(); + String key = traceKeys().getHttp().getPrefix() + name.toLowerCase(); ArrayList list = Collections.list(values); String value = list.size() == 1 ? list.get(0) : StringUtils.collectionToDelimitedString(list, ",", "'", "'"); - this.httpTraceKeysInjector.tagSpan(span, key, value); + keysInjector().tagSpan(span, key, value); } } } @@ -389,12 +405,12 @@ public class TraceFilter extends GenericFilterBean { if (httpStatus == HttpServletResponse.SC_OK && e != null) { // Filter chain threw exception but the response status may not have been set // yet, so we have to guess. - this.tracer.addTag(this.traceKeys.getHttp().getStatusCode(), + tracer().addTag(traceKeys().getHttp().getStatusCode(), String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR)); } // only tag valid http statuses else if (httpStatus >= 100 && (httpStatus < 200) || (httpStatus > 399)) { - this.tracer.addTag(this.traceKeys.getHttp().getStatusCode(), + tracer().addTag(traceKeys().getHttp().getStatusCode(), String.valueOf(response.getStatus())); } } @@ -412,5 +428,47 @@ public class TraceFilter extends GenericFilterBean { return requestURI.append('?').append(queryString).toString(); } } + + Tracer tracer() { + if (this.tracer == null) { + this.tracer = this.beanFactory.getBean(Tracer.class); + } + return this.tracer; + } + + TraceKeys traceKeys() { + if (this.traceKeys == null) { + this.traceKeys = this.beanFactory.getBean(TraceKeys.class); + } + return this.traceKeys; + } + + SpanReporter spanReporter() { + if (this.spanReporter == null) { + this.spanReporter = this.beanFactory.getBean(SpanReporter.class); + } + return this.spanReporter; + } + + HttpSpanExtractor spanExtractor() { + if (this.spanExtractor == null) { + this.spanExtractor = this.beanFactory.getBean(HttpSpanExtractor.class); + } + return this.spanExtractor; + } + + HttpTraceKeysInjector keysInjector() { + if (this.httpTraceKeysInjector == null) { + this.httpTraceKeysInjector = this.beanFactory.getBean(HttpTraceKeysInjector.class); + } + return this.httpTraceKeysInjector; + } + + ErrorParser errorParser() { + if (this.errorParser == null) { + this.errorParser = this.beanFactory.getBean(ErrorParser.class); + } + return this.errorParser; + } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerInterceptor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerInterceptor.java index b4896059e..b24515067 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerInterceptor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceHandlerInterceptor.java @@ -26,10 +26,10 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.boot.autoconfigure.web.ErrorController; +import org.springframework.cloud.sleuth.ErrorParser; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.util.ExceptionUtils; import org.springframework.cloud.sleuth.util.SpanNameUtil; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; @@ -55,6 +55,7 @@ public class TraceHandlerInterceptor extends HandlerInterceptorAdapter { private Tracer tracer; private TraceKeys traceKeys; + private ErrorParser errorParser; private AtomicReference errorController; public TraceHandlerInterceptor(BeanFactory beanFactory) { @@ -137,11 +138,7 @@ public class TraceHandlerInterceptor extends HandlerInterceptorAdapter { } Span span = getRootSpanFromAttribute(request); if (ex != null) { - String errorMsg = ExceptionUtils.getExceptionMessage(ex); - if (log.isDebugEnabled()) { - log.debug("Adding an error tag [" + errorMsg + "] to span " + span + ""); - } - getTracer().addTag(Span.SPAN_ERROR_TAG_NAME, errorMsg); + getErrorParser().parseErrorTags(span, ex); } if (getNewSpanFromAttribute(request) != null) { if (log.isDebugEnabled()) { @@ -188,6 +185,13 @@ public class TraceHandlerInterceptor extends HandlerInterceptorAdapter { return this.traceKeys; } + private ErrorParser getErrorParser() { + if (this.errorParser == null) { + this.errorParser = this.beanFactory.getBean(ErrorParser.class); + } + return this.errorParser; + } + ErrorController getErrorController() { if (this.errorController == null) { try { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java index edd70abde..1468d84ff 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java @@ -26,12 +26,13 @@ import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; +import org.springframework.cloud.sleuth.ErrorParser; +import org.springframework.cloud.sleuth.ExceptionMessageErrorParser; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanNamer; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.instrument.async.SpanContinuingTraceCallable; -import org.springframework.cloud.sleuth.util.ExceptionUtils; import org.springframework.web.context.request.async.WebAsyncTask; /** @@ -76,11 +77,22 @@ public class TraceWebAspect { private final Tracer tracer; private final SpanNamer spanNamer; private final TraceKeys traceKeys; + private final ErrorParser errorParser; + @Deprecated public TraceWebAspect(Tracer tracer, SpanNamer spanNamer, TraceKeys traceKeys) { this.tracer = tracer; this.spanNamer = spanNamer; this.traceKeys = traceKeys; + this.errorParser = new ExceptionMessageErrorParser(); + } + + public TraceWebAspect(Tracer tracer, SpanNamer spanNamer, TraceKeys traceKeys, + ErrorParser errorParser) { + this.tracer = tracer; + this.spanNamer = spanNamer; + this.traceKeys = traceKeys; + this.errorParser = errorParser; } @Pointcut("@within(org.springframework.web.bind.annotation.RestController)") @@ -145,7 +157,7 @@ public class TraceWebAspect { Span currentSpan = this.tracer.getCurrentSpan(); try { if (currentSpan != null && !currentSpan.tags().containsKey(Span.SPAN_ERROR_TAG_NAME)) { - this.tracer.addTag(Span.SPAN_ERROR_TAG_NAME, ExceptionUtils.getExceptionMessage(ex)); + this.errorParser.parseErrorTags(currentSpan, ex); } return pjp.proceed(); } finally { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java index 1705814fb..f9cffada3 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java @@ -28,8 +28,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.cloud.sleuth.ErrorParser; import org.springframework.cloud.sleuth.SpanNamer; -import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; import org.springframework.context.annotation.Bean; @@ -73,8 +73,8 @@ public class TraceWebAutoConfiguration { @Bean public TraceWebAspect traceWebAspect(Tracer tracer, TraceKeys traceKeys, - SpanNamer spanNamer) { - return new TraceWebAspect(tracer, spanNamer, traceKeys); + SpanNamer spanNamer, ErrorParser errorParser) { + return new TraceWebAspect(tracer, spanNamer, traceKeys, errorParser); } @Bean @@ -95,12 +95,9 @@ public class TraceWebAutoConfiguration { } @Bean - public TraceFilter traceFilter(Tracer tracer, TraceKeys traceKeys, - SkipPatternProvider skipPatternProvider, SpanReporter spanReporter, - HttpSpanExtractor spanExtractor, - HttpTraceKeysInjector httpTraceKeysInjector) { - return new TraceFilter(tracer, traceKeys, skipPatternProvider.skipPattern(), - spanReporter, spanExtractor, httpTraceKeysInjector); + public TraceFilter traceFilter(BeanFactory beanFactory, + SkipPatternProvider skipPatternProvider) { + return new TraceFilter(beanFactory, skipPatternProvider.skipPattern()); } @Configuration diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceAsyncRestTemplate.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceAsyncRestTemplate.java index 64d112c60..2f042d422 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceAsyncRestTemplate.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceAsyncRestTemplate.java @@ -24,9 +24,10 @@ import java.util.concurrent.TimeoutException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.cloud.sleuth.ErrorParser; +import org.springframework.cloud.sleuth.ExceptionMessageErrorParser; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.util.ExceptionUtils; import org.springframework.core.task.AsyncListenableTaskExecutor; import org.springframework.http.HttpMethod; import org.springframework.http.client.AsyncClientHttpRequestFactory; @@ -52,33 +53,78 @@ import org.springframework.web.client.RestTemplate; public class TraceAsyncRestTemplate extends AsyncRestTemplate { private final Tracer tracer; + private final ErrorParser errorParser; + @Deprecated public TraceAsyncRestTemplate(Tracer tracer) { super(); this.tracer = tracer; + this.errorParser = new ExceptionMessageErrorParser(); } + @Deprecated public TraceAsyncRestTemplate(AsyncListenableTaskExecutor taskExecutor, Tracer tracer) { super(taskExecutor); this.tracer = tracer; + this.errorParser = new ExceptionMessageErrorParser(); } + @Deprecated public TraceAsyncRestTemplate(AsyncClientHttpRequestFactory asyncRequestFactory, Tracer tracer) { super(asyncRequestFactory); this.tracer = tracer; + this.errorParser = new ExceptionMessageErrorParser(); } + @Deprecated public TraceAsyncRestTemplate(AsyncClientHttpRequestFactory asyncRequestFactory, ClientHttpRequestFactory syncRequestFactory, Tracer tracer) { super(asyncRequestFactory, syncRequestFactory); this.tracer = tracer; + this.errorParser = new ExceptionMessageErrorParser(); } + @Deprecated public TraceAsyncRestTemplate(AsyncClientHttpRequestFactory requestFactory, RestTemplate restTemplate, Tracer tracer) { super(requestFactory, restTemplate); this.tracer = tracer; + this.errorParser = new ExceptionMessageErrorParser(); + } + + public TraceAsyncRestTemplate(Tracer tracer, ErrorParser errorParser) { + super(); + this.tracer = tracer; + this.errorParser = errorParser; + } + + public TraceAsyncRestTemplate(AsyncListenableTaskExecutor taskExecutor, + Tracer tracer, ErrorParser errorParser) { + super(taskExecutor); + this.tracer = tracer; + this.errorParser = errorParser; + } + + public TraceAsyncRestTemplate(AsyncClientHttpRequestFactory asyncRequestFactory, + Tracer tracer, ErrorParser errorParser) { + super(asyncRequestFactory); + this.tracer = tracer; + this.errorParser = errorParser; + } + + public TraceAsyncRestTemplate(AsyncClientHttpRequestFactory asyncRequestFactory, + ClientHttpRequestFactory syncRequestFactory, Tracer tracer, ErrorParser errorParser) { + super(asyncRequestFactory, syncRequestFactory); + this.tracer = tracer; + this.errorParser = errorParser; + } + + public TraceAsyncRestTemplate(AsyncClientHttpRequestFactory requestFactory, + RestTemplate restTemplate, Tracer tracer, ErrorParser errorParser) { + super(requestFactory, restTemplate); + this.tracer = tracer; + this.errorParser = errorParser; } @Override @@ -87,7 +133,8 @@ public class TraceAsyncRestTemplate extends AsyncRestTemplate { throws RestClientException { final ListenableFuture future = super.doExecute(url, method, requestCallback, responseExtractor); final Span span = this.tracer.getCurrentSpan(); - future.addCallback(new TraceListenableFutureCallback<>(this.tracer, span)); + future.addCallback(new TraceListenableFutureCallback<>(this.tracer, span, + this.errorParser)); // potential race can happen here if (span != null && span.equals(this.tracer.getCurrentSpan())) { this.tracer.detach(span); @@ -231,10 +278,13 @@ public class TraceAsyncRestTemplate extends AsyncRestTemplate { private final Tracer tracer; private final Span parent; + private final ErrorParser errorParser; - private TraceListenableFutureCallback(Tracer tracer, Span parent) { + private TraceListenableFutureCallback(Tracer tracer, Span parent, + ErrorParser errorParser) { this.tracer = tracer; this.parent = parent; + this.errorParser = errorParser; } @Override @@ -243,7 +293,7 @@ public class TraceAsyncRestTemplate extends AsyncRestTemplate { if (log.isDebugEnabled()) { log.debug("The callback failed - will close the span"); } - this.tracer.addTag(Span.SPAN_ERROR_TAG_NAME, ExceptionUtils.getExceptionMessage(ex)); + this.errorParser.parseErrorTags(currentSpan(), ex); finish(); } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptor.java index 8b7048bac..cd26a72aa 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptor.java @@ -18,11 +18,11 @@ package org.springframework.cloud.sleuth.instrument.web.client; import java.io.IOException; -import org.springframework.cloud.sleuth.instrument.web.HttpSpanInjector; -import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.ErrorParser; +import org.springframework.cloud.sleuth.ExceptionMessageErrorParser; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.instrument.web.HttpSpanInjector; import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; -import org.springframework.cloud.sleuth.util.ExceptionUtils; import org.springframework.http.HttpRequest; import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestInterceptor; @@ -41,9 +41,19 @@ import org.springframework.http.client.ClientHttpResponse; public class TraceRestTemplateInterceptor extends AbstractTraceHttpRequestInterceptor implements ClientHttpRequestInterceptor { + private final ErrorParser errorParser; + + @Deprecated public TraceRestTemplateInterceptor(Tracer tracer, HttpSpanInjector spanInjector, HttpTraceKeysInjector httpTraceKeysInjector) { super(tracer, spanInjector, httpTraceKeysInjector); + this.errorParser = new ExceptionMessageErrorParser(); + } + + public TraceRestTemplateInterceptor(Tracer tracer, HttpSpanInjector spanInjector, + HttpTraceKeysInjector httpTraceKeysInjector, ErrorParser errorParser) { + super(tracer, spanInjector, httpTraceKeysInjector); + this.errorParser = errorParser; } @Override @@ -61,7 +71,7 @@ public class TraceRestTemplateInterceptor extends AbstractTraceHttpRequestInterc if (log.isDebugEnabled()) { log.debug("Exception occurred while trying to execute the request. Will close the span [" + currentSpan() + "]", e); } - this.tracer.addTag(Span.SPAN_ERROR_TAG_NAME, ExceptionUtils.getExceptionMessage(e)); + this.errorParser.parseErrorTags(currentSpan(), e); finish(); throw e; } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java index ab384e61f..8e6b19d49 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebClientAutoConfiguration.java @@ -16,18 +16,19 @@ package org.springframework.cloud.sleuth.instrument.web.client; -import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import javax.annotation.PostConstruct; 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.cloud.sleuth.instrument.web.HttpSpanInjector; +import org.springframework.cloud.sleuth.ErrorParser; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.instrument.web.HttpSpanInjector; import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; import org.springframework.cloud.sleuth.instrument.web.TraceWebAutoConfiguration; import org.springframework.context.annotation.Bean; @@ -53,9 +54,10 @@ public class TraceWebClientAutoConfiguration { @Bean @ConditionalOnMissingBean public TraceRestTemplateInterceptor traceRestTemplateInterceptor(Tracer tracer, - HttpSpanInjector spanInjector, - HttpTraceKeysInjector httpTraceKeysInjector) { - return new TraceRestTemplateInterceptor(tracer, spanInjector, httpTraceKeysInjector); + HttpSpanInjector spanInjector, HttpTraceKeysInjector httpTraceKeysInjector, + ErrorParser errorParser) { + return new TraceRestTemplateInterceptor(tracer, spanInjector, + httpTraceKeysInjector, errorParser); } @Configuration diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClient.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClient.java index 505331d05..d4c730b8b 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClient.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClient.java @@ -16,6 +16,10 @@ package org.springframework.cloud.sleuth.instrument.web.client.feign; +import feign.Client; +import feign.Request; +import feign.Response; + import java.io.IOException; import java.lang.invoke.MethodHandles; import java.net.URI; @@ -24,18 +28,14 @@ import java.util.concurrent.atomic.AtomicReference; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.BeanFactory; -import org.springframework.cloud.sleuth.instrument.web.HttpSpanInjector; import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.cloud.sleuth.ErrorParser; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.instrument.web.HttpSpanInjector; import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; -import org.springframework.cloud.sleuth.util.ExceptionUtils; import org.springframework.cloud.sleuth.util.SpanNameUtil; -import feign.Client; -import feign.Request; -import feign.Response; - /** * A Feign Client that closes a Span if there is no response body. In other cases Span * will get closed because the Decoder will be called @@ -53,6 +53,7 @@ class TraceFeignClient implements Client { private final BeanFactory beanFactory; private Tracer tracer; private HttpSpanInjector spanInjector; + private ErrorParser errorParser; TraceFeignClient(BeanFactory beanFactory) { this.beanFactory = beanFactory; @@ -154,7 +155,7 @@ class TraceFeignClient implements Client { private void logError(Exception e) { Span span = getTracer().getCurrentSpan(); if (span != null) { - getTracer().addTag(Span.SPAN_ERROR_TAG_NAME, ExceptionUtils.getExceptionMessage(e)); + getErrorParser().parseErrorTags(span, e); } } @@ -164,4 +165,11 @@ class TraceFeignClient implements Client { } return this.tracer; } + + private ErrorParser getErrorParser() { + if (this.errorParser == null) { + this.errorParser = this.beanFactory.getBean(ErrorParser.class); + } + return this.errorParser; + } } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/ExceptionMessageErrorParserTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/ExceptionMessageErrorParserTests.java new file mode 100644 index 000000000..535348662 --- /dev/null +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/ExceptionMessageErrorParserTests.java @@ -0,0 +1,32 @@ +package org.springframework.cloud.sleuth; + +import org.junit.Test; + +import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +public class ExceptionMessageErrorParserTests { + + @Test + public void should_append_tag_for_exportable_span() throws Exception { + Throwable e = new RuntimeException("foo"); + Span span = new Span.SpanBuilder().exportable(true).build(); + + new ExceptionMessageErrorParser().parseErrorTags(span, e); + + then(span).hasATag("error", "foo"); + } + + @Test + public void should_not_append_tag_for_non_exportable_span() throws Exception { + Throwable e = new RuntimeException("foo"); + Span span = new Span.SpanBuilder().exportable(false).build(); + + new ExceptionMessageErrorParser().parseErrorTags(span, e); + + then(span.tags()).isEmpty(); + } + +} \ No newline at end of file diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanTests.java index 99cef25c8..db94a01ee 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanTests.java @@ -16,14 +16,14 @@ package org.springframework.cloud.sleuth; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + import java.io.IOException; import java.util.concurrent.atomic.AtomicLong; import org.junit.Test; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.BDDAssertions.then; @@ -276,6 +276,6 @@ public class SpanTests { private Span.SpanBuilder builder() { return Span.builder().name("http:name").traceId(1L).spanId(2L).parent(3L) .begin(1L).end(2L).traceId(3L).exportable(true).parent(4L) - .remote(true).tag("tag", "tag").log(new Log(System.currentTimeMillis(), "log")); + .baggage("foo", "bar").remote(true).tag("tag", "tag").log(new Log(System.currentTimeMillis(), "log")); } } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/MultipleAsyncRestTemplateTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/MultipleAsyncRestTemplateTests.java index 5b5b87858..3a116de77 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/MultipleAsyncRestTemplateTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/MultipleAsyncRestTemplateTests.java @@ -27,7 +27,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.SpanInjector; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.instrument.web.HttpSpanInjector; import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; @@ -36,7 +35,6 @@ import org.springframework.cloud.sleuth.instrument.web.client.TraceAsyncRestTemp import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; import org.springframework.http.client.AsyncClientHttpRequest; import org.springframework.http.client.AsyncClientHttpRequestFactory; import org.springframework.http.client.ClientHttpRequest; diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/issues/issue410/Issue410Tests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/issues/issue410/Issue410Tests.java index cf59db54e..01939d93a 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/issues/issue410/Issue410Tests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/issues/issue410/Issue410Tests.java @@ -16,7 +16,6 @@ package org.springframework.cloud.sleuth.instrument.async.issues.issue410; -import static org.assertj.core.api.BDDAssertions.then; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; import java.lang.invoke.MethodHandles; diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/HystrixAnnotationsIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/HystrixAnnotationsIntegrationTests.java index 9f60c974b..d2d890bc6 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/HystrixAnnotationsIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/HystrixAnnotationsIntegrationTests.java @@ -17,7 +17,6 @@ package org.springframework.cloud.sleuth.instrument.hystrix; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.assertj.core.api.BDDAssertions.then; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; import java.util.concurrent.atomic.AtomicReference; diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessagingSpanExtractorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessagingSpanExtractorTests.java index efa230d5b..778731020 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessagingSpanExtractorTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessagingSpanExtractorTests.java @@ -27,7 +27,6 @@ import org.springframework.messaging.support.MessageBuilder; import org.springframework.util.StringUtils; import static org.assertj.core.api.Assertions.fail; -import static org.assertj.core.api.BDDAssertions.then; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; public class MessagingSpanExtractorTests { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessagingSpanInjectorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessagingSpanInjectorTests.java index 8fd2a8bec..f0aead814 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessagingSpanInjectorTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/MessagingSpanInjectorTests.java @@ -26,7 +26,6 @@ import org.springframework.messaging.support.MessageBuilder; import org.springframework.messaging.support.MessageHeaderAccessor; import org.springframework.messaging.support.NativeMessageHeaderAccessor; -import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.assertThat; /** diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaTests.java index b029d7c92..cbed5bf7b 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaTests.java @@ -2,7 +2,6 @@ package org.springframework.cloud.sleuth.instrument.rxjava; import static com.jayway.awaitility.Awaitility.await; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.assertj.core.api.BDDAssertions.then; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; import java.util.ArrayList; diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java index 745b4f058..269982f29 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java @@ -18,7 +18,6 @@ package org.springframework.cloud.sleuth.instrument.scheduling; import static com.jayway.awaitility.Awaitility.await; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.assertj.core.api.BDDAssertions.then; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; import java.util.concurrent.atomic.AtomicBoolean; diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/RestTemplateTraceAspectIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/RestTemplateTraceAspectIntegrationTests.java index f99213850..6868910bb 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/RestTemplateTraceAspectIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/RestTemplateTraceAspectIntegrationTests.java @@ -14,7 +14,6 @@ import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; -import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; import org.springframework.cloud.sleuth.util.ExceptionUtils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SpringDataInstrumentationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SpringDataInstrumentationTests.java index 4aac55654..66d59b8e6 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SpringDataInstrumentationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SpringDataInstrumentationTests.java @@ -16,7 +16,6 @@ package org.springframework.cloud.sleuth.instrument.web; -import static org.assertj.core.api.BDDAssertions.then; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; import java.util.Collection; diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterAlwaysSamplerIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterAlwaysSamplerIntegrationTests.java index 7bb4abe2c..c36e4db10 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterAlwaysSamplerIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterAlwaysSamplerIntegrationTests.java @@ -1,17 +1,20 @@ package org.springframework.cloud.sleuth.instrument.web; -import static org.assertj.core.api.BDDAssertions.then; - import java.util.Random; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.BDDMockito; +import org.mockito.Mockito; +import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanReporter; +import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration; import org.springframework.cloud.sleuth.instrument.web.common.AbstractMvcIntegrationTest; @@ -27,6 +30,8 @@ import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import static org.assertj.core.api.BDDAssertions.then; + @RunWith(SpringRunner.class) @SpringBootTest(classes = TraceFilterAlwaysSamplerIntegrationTests.Config.class) public class TraceFilterAlwaysSamplerIntegrationTests extends AbstractMvcIntegrationTest { @@ -57,8 +62,18 @@ public class TraceFilterAlwaysSamplerIntegrationTests extends AbstractMvcIntegra @Override protected void configureMockMvcBuilder(DefaultMockMvcBuilder mockMvcBuilder) { - mockMvcBuilder.addFilters(new TraceFilter(this.tracer, this.traceKeys, - new NoOpSpanReporter(), this.spanExtractor, this.httpTraceKeysInjector)); + BeanFactory beanFactory = beanFactory(); + mockMvcBuilder.addFilters(new TraceFilter(beanFactory)); + } + + private BeanFactory beanFactory() { + BeanFactory beanFactory = Mockito.mock(BeanFactory.class); + BDDMockito.given(beanFactory.getBean(Tracer.class)).willReturn(this.tracer); + BDDMockito.given(beanFactory.getBean(TraceKeys.class)).willReturn(this.traceKeys); + BDDMockito.given(beanFactory.getBean(HttpSpanExtractor.class)).willReturn(this.spanExtractor); + BDDMockito.given(beanFactory.getBean(SpanReporter.class)).willReturn(new NoOpSpanReporter()); + BDDMockito.given(beanFactory.getBean(HttpTraceKeysInjector.class)).willReturn(this.httpTraceKeysInjector); + return beanFactory; } private MvcResult whenSentPingWithTraceIdAndNotSampling(Long traceId) diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterMockChainIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterMockChainIntegrationTests.java index a69a624c9..644f05ecc 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterMockChainIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterMockChainIntegrationTests.java @@ -21,9 +21,13 @@ import java.util.regex.Pattern; import org.junit.Before; import org.junit.Test; +import org.mockito.BDDMockito; +import org.mockito.Mockito; +import org.springframework.beans.factory.BeanFactory; import org.springframework.cloud.sleuth.DefaultSpanNamer; import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.log.NoOpSpanLogger; @@ -72,9 +76,7 @@ public class TraceFilterMockChainIntegrationTests { @Test public void startsNewTrace() throws Exception { - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, new NoOpSpanReporter(), - new ZipkinHttpSpanExtractor(Pattern.compile(SleuthWebProperties.DEFAULT_SKIP_PATTERN)), - keysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); filter.doFilter(this.request, this.response, this.filterChain); assertNull(TestSpanContextHolder.getCurrentSpan()); } @@ -84,11 +86,22 @@ public class TraceFilterMockChainIntegrationTests { Random generator = new Random(); this.request = builder().header(Span.SPAN_ID_NAME, generator.nextLong()) .header(Span.TRACE_ID_NAME, generator.nextLong()).buildRequest(new MockServletContext()); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, new NoOpSpanReporter(), - new ZipkinHttpSpanExtractor(Pattern.compile(SleuthWebProperties.DEFAULT_SKIP_PATTERN)), - keysInjector); + BeanFactory beanFactory = beanFactory(); + TraceFilter filter = new TraceFilter(beanFactory); filter.doFilter(this.request, this.response, this.filterChain); assertNull(TestSpanContextHolder.getCurrentSpan()); } + private BeanFactory beanFactory() { + BeanFactory beanFactory = Mockito.mock(BeanFactory.class); + BDDMockito.given(beanFactory.getBean(Tracer.class)).willReturn(this.tracer); + BDDMockito.given(beanFactory.getBean(TraceKeys.class)).willReturn(this.traceKeys); + BDDMockito.given(beanFactory.getBean(HttpSpanExtractor.class)) + .willReturn(new ZipkinHttpSpanExtractor( + Pattern.compile(SleuthWebProperties.DEFAULT_SKIP_PATTERN))); + BDDMockito.given(beanFactory.getBean(SpanReporter.class)).willReturn(new NoOpSpanReporter()); + BDDMockito.given(beanFactory.getBean(HttpTraceKeysInjector.class)).willReturn(this.keysInjector); + return beanFactory; + } + } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java index b83a501a1..50cee09dc 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java @@ -24,8 +24,14 @@ import java.util.regex.Pattern; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.mockito.BDDMockito; import org.mockito.Mock; +import org.mockito.Mockito; +import org.springframework.beans.factory.BeanFactory; import org.springframework.cloud.sleuth.DefaultSpanNamer; +import org.springframework.cloud.sleuth.ErrorParser; +import org.springframework.cloud.sleuth.ExceptionMessageErrorParser; +import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Sampler; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanReporter; @@ -109,8 +115,7 @@ public class TraceFilterTests { @Test public void notTraced() throws Exception { this.sampler = NeverSampler.INSTANCE; - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); this.request = get("/favicon.ico").accept(MediaType.ALL) .buildRequest(new MockServletContext()); @@ -123,8 +128,7 @@ public class TraceFilterTests { @Test public void startsNewTrace() throws Exception { - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); filter.doFilter(this.request, this.response, this.filterChain); verifyCurrentSpanStatusCode(HttpStatus.OK); @@ -134,8 +138,7 @@ public class TraceFilterTests { @Test public void shouldNotStoreHttpStatusCodeWhenResponseCodeHasNotYetBeenSet() throws Exception { - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); this.response.setStatus(0); filter.doFilter(this.request, this.response, this.filterChain); @@ -150,10 +153,10 @@ public class TraceFilterTests { .header(Span.SPAN_ID_NAME, Span.idToHex(PARENT_ID)) .header(Span.TRACE_ID_NAME, Span.idToHex(2L)) .header(Span.PARENT_ID_NAME, Span.idToHex(3L)) - .buildRequest(new MockServletContext()); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + .buildRequest(new MockServletContext());BeanFactory beanFactory = beanFactory(); + BDDMockito.given(beanFactory.getBean(SpanReporter.class)).willReturn(this.spanReporter); + TraceFilter filter = new TraceFilter(beanFactory); filter.doFilter(this.request, this.response, this.filterChain); // this creates a child span which is why we'd expect the parents to include the parent id @@ -184,8 +187,7 @@ public class TraceFilterTests { // It should have been removed from the thread local context so simulate that TestSpanContextHolder.removeCurrentSpan(); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); filter.doFilter(this.request, this.response, this.filterChain); then(TestSpanContextHolder.getCurrentSpan()).isNull(); @@ -200,8 +202,7 @@ public class TraceFilterTests { // It should have been removed from the thread local context so simulate that TestSpanContextHolder.removeCurrentSpan(); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); filter.doFilter(this.request, this.response, this.filterChain); then(TestSpanContextHolder.getCurrentSpan()).isNull(); @@ -217,8 +218,7 @@ public class TraceFilterTests { // It should have been removed from the thread local context so simulate that TestSpanContextHolder.removeCurrentSpan(); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); filter.doFilter(this.request, this.response, this.filterChain); then(TestSpanContextHolder.getCurrentSpan()).isNull(); @@ -228,9 +228,10 @@ public class TraceFilterTests { public void continuesSpanFromHeaders() throws Exception { this.request = builder().header(Span.SPAN_ID_NAME, PARENT_ID) .header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext()); + BeanFactory beanFactory = beanFactory(); + BDDMockito.given(beanFactory.getBean(SpanReporter.class)).willReturn(this.spanReporter); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory); filter.doFilter(this.request, this.response, this.filterChain); verifyParentSpanHttpTags(); @@ -242,10 +243,11 @@ public class TraceFilterTests { public void addsAdditionalHeaders() throws Exception { this.request = builder().header(Span.SPAN_ID_NAME, PARENT_ID) .header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext()); - this.traceKeys.getHttp().getHeaders().add("x-foo"); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + BeanFactory beanFactory = beanFactory(); + BDDMockito.given(beanFactory.getBean(SpanReporter.class)).willReturn(this.spanReporter); + + TraceFilter filter = new TraceFilter(beanFactory); this.request.addHeader("X-Foo", "bar"); filter.doFilter(this.request, this.response, this.filterChain); @@ -272,10 +274,10 @@ public class TraceFilterTests { public void additionalMultiValuedHeader() throws Exception { this.request = builder().header(Span.SPAN_ID_NAME, PARENT_ID) .header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext()); + this.traceKeys.getHttp().getHeaders().add("x-foo");BeanFactory beanFactory = beanFactory(); + BDDMockito.given(beanFactory.getBean(SpanReporter.class)).willReturn(this.spanReporter); - this.traceKeys.getHttp().getHeaders().add("x-foo"); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory); this.request.addHeader("X-Foo", "bar"); this.request.addHeader("X-Foo", "spam"); filter.doFilter(this.request, this.response, this.filterChain); @@ -289,8 +291,10 @@ public class TraceFilterTests { public void shouldAnnotateSpanWithErrorWhenExceptionIsThrown() throws Exception { this.request = builder().header(Span.SPAN_ID_NAME, PARENT_ID) .header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext()); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + BeanFactory beanFactory = beanFactory(); + BDDMockito.given(beanFactory.getBean(SpanReporter.class)).willReturn(this.spanReporter); + + TraceFilter filter = new TraceFilter(beanFactory); this.filterChain = new MockFilterChain() { @Override public void doFilter(javax.servlet.ServletRequest request, @@ -316,8 +320,7 @@ public class TraceFilterTests { public void detachesSpanWhenResponseStatusIsNot2xx() throws Exception { this.request = builder().header(Span.SPAN_ID_NAME, PARENT_ID) .header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext()); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); this.response.setStatus(404); filter.doFilter(this.request, this.response, this.filterChain); @@ -329,8 +332,7 @@ public class TraceFilterTests { public void closesSpanWhenResponseStatusIs2xx() throws Exception { this.request = builder().header(Span.SPAN_ID_NAME, PARENT_ID) .header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext()); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); this.response.setStatus(200); filter.doFilter(this.request, this.response, this.filterChain); @@ -342,8 +344,7 @@ public class TraceFilterTests { public void closesSpanWhenResponseStatusIs3xx() throws Exception { this.request = builder().header(Span.SPAN_ID_NAME, PARENT_ID) .header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext()); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); this.response.setStatus(302); filter.doFilter(this.request, this.response, this.filterChain); @@ -355,8 +356,7 @@ public class TraceFilterTests { public void returns400IfSpanIsMalformedAndCreatesANewSpan() throws Exception { this.request = builder().header(Span.SPAN_ID_NAME, "asd") .header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext()); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); filter.doFilter(this.request, this.response, this.filterChain); @@ -371,8 +371,7 @@ public class TraceFilterTests { this.request = builder().header(Span.SPAN_ID_NAME, PARENT_ID) .header(Span.PARENT_ID_NAME, "-") .header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext()); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); filter.doFilter(this.request, this.response, this.filterChain); @@ -388,8 +387,7 @@ public class TraceFilterTests { .header(Span.SPAN_FLAGS, 1) .buildRequest(new MockServletContext()); this.sampler = new NeverSampler(); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); filter.doFilter(this.request, this.response, this.filterChain); @@ -404,8 +402,7 @@ public class TraceFilterTests { .header(Span.SPAN_FLAGS, 0) .buildRequest(new MockServletContext()); this.sampler = new AlwaysSampler(); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); filter.doFilter(this.request, this.response, this.filterChain); @@ -421,9 +418,10 @@ public class TraceFilterTests { .header(Span.SPAN_ID_NAME, 10L) .buildRequest(new MockServletContext()); this.sampler = new NeverSampler(); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + BeanFactory beanFactory = beanFactory(); + BDDMockito.given(beanFactory.getBean(SpanReporter.class)).willReturn(this.spanReporter); + TraceFilter filter = new TraceFilter(beanFactory); filter.doFilter(this.request, this.response, this.filterChain); then(new ListOfSpans(this.spanReporter.getSpans())) @@ -439,8 +437,7 @@ public class TraceFilterTests { .header(Span.TRACE_ID_NAME, 10L) .buildRequest(new MockServletContext()); this.sampler = new NeverSampler(); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, this.spanReporter, - this.spanExtractor, this.httpTraceKeysInjector); + TraceFilter filter = new TraceFilter(beanFactory()); filter.doFilter(this.request, this.response, this.filterChain); @@ -484,4 +481,15 @@ public class TraceFilterTests { return TraceFilterTests.this.sampler.isSampled(span); } } + + private BeanFactory beanFactory() { + BeanFactory beanFactory = Mockito.mock(BeanFactory.class); + BDDMockito.given(beanFactory.getBean(Tracer.class)).willReturn(this.tracer); + BDDMockito.given(beanFactory.getBean(TraceKeys.class)).willReturn(this.traceKeys); + BDDMockito.given(beanFactory.getBean(HttpSpanExtractor.class)).willReturn(this.spanExtractor); + BDDMockito.given(beanFactory.getBean(SpanReporter.class)).willReturn(new NoOpSpanReporter()); + BDDMockito.given(beanFactory.getBean(HttpTraceKeysInjector.class)).willReturn(this.httpTraceKeysInjector); + BDDMockito.given(beanFactory.getBean(ErrorParser.class)).willReturn(new ExceptionMessageErrorParser()); + return beanFactory; + } } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java index 796f93698..ab40e3cc0 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java @@ -16,6 +16,10 @@ package org.springframework.cloud.sleuth.instrument.web.client; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.SocketPolicy; + import java.io.IOException; import java.util.Arrays; import java.util.Map; @@ -27,6 +31,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.springframework.cloud.sleuth.DefaultSpanNamer; +import org.springframework.cloud.sleuth.ExceptionMessageErrorParser; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.assertions.ListOfSpans; @@ -44,10 +49,6 @@ import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.SocketPolicy; - import static org.assertj.core.api.BDDAssertions.then; /** @@ -69,7 +70,8 @@ public class TraceRestTemplateInterceptorIntegrationTests { new DefaultSpanNamer(), new NoOpSpanLogger(), this.spanAccumulator, new TraceKeys()); this.template.setInterceptors(Arrays.asList( new TraceRestTemplateInterceptor(this.tracer, new ZipkinHttpSpanInjector(), - new HttpTraceKeysInjector(this.tracer, new TraceKeys())))); + new HttpTraceKeysInjector(this.tracer, new TraceKeys()), + new ExceptionMessageErrorParser()))); TestSpanContextHolder.removeCurrentSpan(); } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorTests.java index 64249b1f8..9a892246d 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorTests.java @@ -27,6 +27,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.springframework.cloud.sleuth.DefaultSpanNamer; +import org.springframework.cloud.sleuth.ExceptionMessageErrorParser; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; @@ -73,7 +74,8 @@ public class TraceRestTemplateInterceptorTests { new DefaultSpanNamer(), new NoOpSpanLogger(), this.spanAccumulator, new TraceKeys()); this.template.setInterceptors(Arrays.asList( new TraceRestTemplateInterceptor(this.tracer, new ZipkinHttpSpanInjector(), - new HttpTraceKeysInjector(this.tracer, new TraceKeys())))); + new HttpTraceKeysInjector(this.tracer, new TraceKeys()), + new ExceptionMessageErrorParser()))); TestSpanContextHolder.removeCurrentSpan(); } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java index 4090e34b1..6ebd501f7 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java @@ -50,7 +50,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.ResponseEntity; import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.rules.SpringClassRule; import org.springframework.test.context.junit4.rules.SpringMethodRule; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exceptionresolver/Issue585Tests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exceptionresolver/Issue585Tests.java index 87b457eab..11dfa819e 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exceptionresolver/Issue585Tests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exceptionresolver/Issue585Tests.java @@ -19,7 +19,6 @@ import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.assertions.ListOfSpans; -import org.springframework.cloud.sleuth.assertions.SleuthAssertions; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.util.ArrayListSpanAccumulator; import org.springframework.context.annotation.Bean; diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java index 6a869f539..17d724ebd 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java @@ -16,6 +16,14 @@ package org.springframework.cloud.sleuth.instrument.web.client.feign; +import feign.Client; +import feign.Feign; +import feign.FeignException; +import feign.Request; +import feign.RequestLine; +import feign.Response; +import okhttp3.mockwebserver.MockWebServer; + import java.io.IOException; import java.nio.charset.Charset; import java.util.HashMap; @@ -32,10 +40,12 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.beans.factory.BeanFactory; import org.springframework.cloud.sleuth.DefaultSpanNamer; -import org.springframework.cloud.sleuth.instrument.web.HttpSpanInjector; +import org.springframework.cloud.sleuth.ErrorParser; +import org.springframework.cloud.sleuth.ExceptionMessageErrorParser; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.instrument.web.HttpSpanInjector; import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; import org.springframework.cloud.sleuth.instrument.web.ZipkinHttpSpanInjector; import org.springframework.cloud.sleuth.log.NoOpSpanLogger; @@ -45,14 +55,6 @@ import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; import org.springframework.cloud.sleuth.util.ArrayListSpanAccumulator; import org.springframework.cloud.sleuth.util.ExceptionUtils; -import feign.Client; -import feign.Feign; -import feign.FeignException; -import feign.Request; -import feign.RequestLine; -import feign.Response; -import okhttp3.mockwebserver.MockWebServer; - import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; @@ -81,6 +83,7 @@ public class FeignRetriesTests { BDDMockito.given(this.beanFactory.getBean(HttpSpanInjector.class)) .willReturn(new ZipkinHttpSpanInjector()); BDDMockito.given(this.beanFactory.getBean(Tracer.class)).willReturn(this.tracer); + BDDMockito.given(this.beanFactory.getBean(ErrorParser.class)).willReturn(new ExceptionMessageErrorParser()); } @Test diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientTests.java index 225feca37..3da860c66 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientTests.java @@ -16,6 +16,10 @@ package org.springframework.cloud.sleuth.instrument.web.client.feign; +import feign.Client; +import feign.Request; +import feign.Response; + import java.io.IOException; import java.nio.charset.Charset; import java.util.HashMap; @@ -31,11 +35,13 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.beans.factory.BeanFactory; import org.springframework.cloud.sleuth.DefaultSpanNamer; -import org.springframework.cloud.sleuth.instrument.web.HttpSpanInjector; +import org.springframework.cloud.sleuth.ErrorParser; +import org.springframework.cloud.sleuth.ExceptionMessageErrorParser; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.assertions.SleuthAssertions; +import org.springframework.cloud.sleuth.instrument.web.HttpSpanInjector; import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; import org.springframework.cloud.sleuth.instrument.web.ZipkinHttpSpanInjector; import org.springframework.cloud.sleuth.log.NoOpSpanLogger; @@ -45,10 +51,6 @@ import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; import org.springframework.cloud.sleuth.util.ArrayListSpanAccumulator; import org.springframework.cloud.sleuth.util.ExceptionUtils; -import feign.Client; -import feign.Request; -import feign.Response; - import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; /** @@ -74,6 +76,7 @@ public class TraceFeignClientTests { BDDMockito.given(this.beanFactory.getBean(HttpSpanInjector.class)) .willReturn(new ZipkinHttpSpanInjector()); BDDMockito.given(this.beanFactory.getBean(Tracer.class)).willReturn(this.tracer); + BDDMockito.given(this.beanFactory.getBean(ErrorParser.class)).willReturn(new ExceptionMessageErrorParser()); } @Test diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/servererrors/FeignClientServerErrorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/servererrors/FeignClientServerErrorTests.java index 6147842b6..b9b5fa686 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/servererrors/FeignClientServerErrorTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/servererrors/FeignClientServerErrorTests.java @@ -63,7 +63,6 @@ import com.netflix.loadbalancer.Server; import feign.codec.Decoder; import feign.codec.ErrorDecoder; -import static org.assertj.core.api.BDDAssertions.then; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; /** diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java index bc351f34a..7f9bf918c 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java @@ -79,7 +79,6 @@ import junitparams.Parameters; import static junitparams.JUnitParamsRunner.$; import static org.assertj.core.api.Assertions.fail; -import static org.assertj.core.api.BDDAssertions.then; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; @RunWith(JUnitParamsRunner.class) diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulIntegrationTests.java index b5c06a962..af3e8e382 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulIntegrationTests.java @@ -1,6 +1,5 @@ package org.springframework.cloud.sleuth.instrument.zuul; -import static org.assertj.core.api.BDDAssertions.then; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; import java.io.IOException; diff --git a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListenerTests.java b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListenerTests.java index d4d0b1370..8bc679781 100644 --- a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListenerTests.java +++ b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListenerTests.java @@ -28,7 +28,6 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.sleuth.Sampler; import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.SpanAdjuster; import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.sampler.AlwaysSampler;