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
This commit is contained in:
Marcin Grzejszczak
2017-06-06 08:05:27 +02:00
parent 6a0a57ef7f
commit f834e5222b
41 changed files with 493 additions and 184 deletions

View File

@@ -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);
}

View File

@@ -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);
}
}
}

View File

@@ -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.
* <p>
@@ -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);
}

View File

@@ -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;
}

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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()) {

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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<String> values = request.getHeaders(name);
if (values.hasMoreElements()) {
String key = this.traceKeys.getHttp().getPrefix() + name.toLowerCase();
String key = traceKeys().getHttp().getPrefix() + name.toLowerCase();
ArrayList<String> 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;
}
}

View File

@@ -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> 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 {

View File

@@ -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 {

View File

@@ -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

View File

@@ -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<T> 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();
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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"));
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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;
/**

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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.<ClientHttpRequestInterceptor>asList(
new TraceRestTemplateInterceptor(this.tracer, new ZipkinHttpSpanInjector(),
new HttpTraceKeysInjector(this.tracer, new TraceKeys()))));
new HttpTraceKeysInjector(this.tracer, new TraceKeys()),
new ExceptionMessageErrorParser())));
TestSpanContextHolder.removeCurrentSpan();
}

View File

@@ -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.<ClientHttpRequestInterceptor>asList(
new TraceRestTemplateInterceptor(this.tracer, new ZipkinHttpSpanInjector(),
new HttpTraceKeysInjector(this.tracer, new TraceKeys()))));
new HttpTraceKeysInjector(this.tracer, new TraceKeys()),
new ExceptionMessageErrorParser())));
TestSpanContextHolder.removeCurrentSpan();
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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;
/**

View File

@@ -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)

View File

@@ -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;

View File

@@ -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;