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:
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user