diff --git a/docs/src/main/asciidoc/README.adoc b/docs/src/main/asciidoc/README.adoc index 39895eaf4..2deb78884 100644 --- a/docs/src/main/asciidoc/README.adoc +++ b/docs/src/main/asciidoc/README.adoc @@ -10,15 +10,10 @@ include::intro.adoc[] == Running the sample -1. Download and build zipkin -2. Install redis and run `redis-server` -3. `cd zipkin` -4. `bin/collector redis` from [here](https://github.com/twitter/zipkin/blob/master/doc/redis.md) -5. `bin/query redis` -6. `bin/web` -7. run sample application -8. hit `http://localhost:3380` -9. goto `http://localhost:8080` for zipkin web +1. Run [Zipkin](https://github.com/openzipkin/zipkin), e.g. via the docker images at [Zipkin Docker](https://github.com/openzipkin/zipkin-docker) +7. Run sample application +8. Hit `http://localhost:3380` +9. Goto `http://localhost:8080` for zipkin web == Building diff --git a/docs/src/main/asciidoc/intro.adoc b/docs/src/main/asciidoc/intro.adoc index 0fe0cdd50..af89eba08 100644 --- a/docs/src/main/asciidoc/intro.adoc +++ b/docs/src/main/asciidoc/intro.adoc @@ -1,5 +1,3 @@ -TODO: intro Spring Cloud Sleuth - === Terminology Spring Cloud Sleuth borrows http://research.google.com/pubs/pub36356.html[Dapper's] terminology. diff --git a/docs/src/main/asciidoc/spring-cloud-consul.adoc b/docs/src/main/asciidoc/spring-cloud-sleuth.adoc similarity index 100% rename from docs/src/main/asciidoc/spring-cloud-consul.adoc rename to docs/src/main/asciidoc/spring-cloud-sleuth.adoc diff --git a/pom.xml b/pom.xml index a9823192e..2c4555043 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ org.springframework.cloud spring-cloud-build - 1.0.2.BUILD-SNAPSHOT + 1.1.0.BUILD-SNAPSHOT diff --git a/spring-cloud-sleuth-core/pom.xml b/spring-cloud-sleuth-core/pom.xml index e1ca6b9d9..60d3efd03 100644 --- a/spring-cloud-sleuth-core/pom.xml +++ b/spring-cloud-sleuth-core/pom.xml @@ -66,7 +66,7 @@ org.projectlombok lombok - provided + true org.springframework.boot diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/TraceScope.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/TraceScope.java index 695f913b0..f657fa3f7 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/TraceScope.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/TraceScope.java @@ -1,12 +1,16 @@ package org.springframework.cloud.sleuth; import java.io.Closeable; +import java.util.ArrayList; +import java.util.List; import lombok.SneakyThrows; import lombok.Value; import lombok.experimental.NonFinal; +import lombok.extern.apachecommons.CommonsLog; import org.springframework.cloud.sleuth.event.SpanStoppedEvent; +import org.springframework.cloud.sleuth.util.ExceptionUtils; import org.springframework.context.ApplicationEventPublisher; /** @@ -14,6 +18,7 @@ import org.springframework.context.ApplicationEventPublisher; */ @Value @NonFinal +@CommonsLog public class TraceScope implements Closeable { private final ApplicationEventPublisher publisher; @@ -28,6 +33,11 @@ public class TraceScope implements Closeable { */ private final Span savedSpan; + /** + * List of callbacks to run on close. + */ + private List callbacks = new ArrayList(); + @NonFinal private boolean detached = false; @@ -45,41 +55,54 @@ public class TraceScope implements Closeable { * @return the same Span object */ public Span detach() { - if (detached) { - Utils.error("Tried to detach trace span " + span + " but " + + if (this.detached) { + ExceptionUtils.error("Tried to detach trace span " + this.span + " but " + "it has already been detached."); } - detached = true; + this.detached = true; Span cur = TraceContextHolder.getCurrentSpan(); - if (cur != span) { - Utils.error("Tried to detach trace span " + span + " but " + + if (cur != this.span) { + ExceptionUtils.error("Tried to detach trace span " + this.span + " but " + "it is not the current span for the " + Thread.currentThread().getName() + " thread. You have " + "probably forgotten to close or detach " + cur); } else { - TraceContextHolder.setCurrentSpan(savedSpan); + TraceContextHolder.setCurrentSpan(this.savedSpan); + } + return this.span; + } + + public void register(Runnable callback) { + if (!this.callbacks .contains(callback)) { + this.callbacks.add(callback); } - return span; } @Override @SneakyThrows public void close() { - if (detached) { + if (this.detached) { return; } - detached = true; + this.detached = true; + for (Runnable callback : this.callbacks) { + try { + callback.run(); + } catch (Throwable e) { + log.error("Error with callback on close", e); + } + } Span cur = TraceContextHolder.getCurrentSpan(); - if (cur != span) { - Utils.error("Tried to close trace span " + span + " but " + + if (cur != this.span) { + ExceptionUtils.error("Tried to close trace span " + this.span + " but " + "it is not the current span for the " + Thread.currentThread().getName() + " thread. You have " + "probably forgotten to close or detach " + cur); } else { - span.stop(); - this.publisher.publishEvent(new SpanStoppedEvent(this, span)); - TraceContextHolder.setCurrentSpan(savedSpan); + this.span.stop(); + this.publisher.publishEvent(new SpanStoppedEvent(this, this.span)); + TraceContextHolder.setCurrentSpan(this.savedSpan); } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/TraceAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java similarity index 63% rename from spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/TraceAutoConfiguration.java rename to spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java index 84ff1e3b6..cc8782977 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/TraceAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java @@ -1,7 +1,12 @@ -package org.springframework.cloud.sleuth; +package org.springframework.cloud.sleuth.autoconfig; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.cloud.sleuth.IdGenerator; +import org.springframework.cloud.sleuth.RandomUuidGenerator; +import org.springframework.cloud.sleuth.Sampler; +import org.springframework.cloud.sleuth.Trace; import org.springframework.cloud.sleuth.sampler.IsTracingSampler; +import org.springframework.cloud.sleuth.trace.DefaultTrace; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -20,13 +25,13 @@ public class TraceAutoConfiguration { @Bean @ConditionalOnMissingBean - public Sampler defaultSampler() { + public Sampler defaultSampler() { return new IsTracingSampler(); } @Bean @ConditionalOnMissingBean - public Trace trace(Sampler sampler, IdGenerator idGenerator, + public Trace trace(Sampler sampler, IdGenerator idGenerator, ApplicationEventPublisher publisher) { return new DefaultTrace(sampler, idGenerator, publisher); } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/ArrayListSpanAccumulator.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ArrayListSpanAccumulator.java similarity index 79% rename from spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/ArrayListSpanAccumulator.java rename to spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ArrayListSpanAccumulator.java index 543ac1d04..1bb3d7f7e 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/ArrayListSpanAccumulator.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ArrayListSpanAccumulator.java @@ -1,10 +1,10 @@ -package org.springframework.cloud.sleuth; +package org.springframework.cloud.sleuth.event; import java.util.ArrayList; import lombok.Value; -import org.springframework.cloud.sleuth.event.SpanStoppedEvent; +import org.springframework.cloud.sleuth.Span; import org.springframework.context.ApplicationListener; /** diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/TraceRunnable.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/TraceRunnable.java index 259360f6f..4a46cb32d 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/TraceRunnable.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/TraceRunnable.java @@ -1,5 +1,6 @@ package org.springframework.cloud.sleuth.instrument; +import lombok.EqualsAndHashCode; import lombok.Value; import org.springframework.cloud.sleuth.Span; @@ -10,6 +11,7 @@ import org.springframework.cloud.sleuth.TraceScope; * @author Spencer Gibb */ @Value +@EqualsAndHashCode(callSuper=false) public class TraceRunnable extends TraceDelegate implements Runnable { public TraceRunnable(Trace trace, Runnable delagate) { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java index b6dee3321..e3c93bff7 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java @@ -30,6 +30,8 @@ import javax.servlet.http.HttpServletResponse; import org.springframework.cloud.sleuth.Trace; import org.springframework.cloud.sleuth.TraceInfo; import org.springframework.cloud.sleuth.TraceScope; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import org.springframework.web.filter.OncePerRequestFilter; /** @@ -44,6 +46,7 @@ import org.springframework.web.filter.OncePerRequestFilter; * @author Marcin Grzejszczak, 4financeIT * @author Spencer Gibb */ +@Order(Ordered.HIGHEST_PRECEDENCE + 5) public class TraceFilter extends OncePerRequestFilter { public static final Pattern DEFAULT_SKIP_PATTERN = Pattern @@ -65,10 +68,10 @@ public class TraceFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { + throws ServletException, IOException { String uri = hasText(request.getRequestURI()) ? request.getRequestURI() : ""; - boolean skip = skipPattern.matcher(uri).matches(); + boolean skip = this.skipPattern.matcher(uri).matches(); TraceScope traceScope = null; if (!skip) { @@ -78,13 +81,13 @@ public class TraceFilter extends OncePerRequestFilter { TraceInfo traceInfo = new TraceInfo(traceId, spanId); // TODO: trace description? - traceScope = trace.startSpan("traceFilter", traceInfo); + traceScope = this.trace.startSpan("traceFilter", traceInfo); // Send new span id back addToResponseIfNotPresent(response, SPAN_ID_NAME, traceScope.getSpan() .getSpanId()); } else { - traceScope = trace.startSpan("traceFilter"); + traceScope = this.trace.startSpan("traceFilter"); } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java index 7ffe04d2b..7a06bc4e3 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAspect.java @@ -67,12 +67,12 @@ public class TraceWebAspect { @Around("anyControllerOrRestControllerWithPublicAsyncMethod()") @SuppressWarnings("unchecked") public Object wrapWithCorrelationId(ProceedingJoinPoint pjp) throws Throwable { - Callable callable = (Callable) pjp.proceed(); + Callable callable = (Callable) pjp.proceed(); if (TraceContextHolder.isTracing()) { log.debug("Wrapping callable with span [" + TraceContextHolder.getCurrentSpan() + "]"); - return new TraceCallable(this.trace, callable); + return new TraceCallable(this.trace, callable); } else { return callable; diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java index 321c75dd2..2bf917497 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java @@ -27,8 +27,6 @@ import org.springframework.cloud.sleuth.Trace; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; /** * Registers beans that add tracing to requests @@ -55,41 +53,15 @@ public class TraceWebAutoConfiguration { @Bean @ConditionalOnMissingBean public TraceWebAspect traceWebAspect() { - return new TraceWebAspect(trace); + return new TraceWebAspect(this.trace); } - //TODO: I don't think TraceHandlerInterceptor is needed with TraceFilter - /*@Bean - @ConditionalOnMissingBean - public TraceHandlerInterceptor traceHandlerInterceptor() { - return new TraceHandlerInterceptor(trace); - } - - @Bean - public WebMvcConfigurerAdapter webMvcConfigurerAdapter( - TraceHandlerInterceptor handlerInterceptor) { - return new TraceWebConfigurer(handlerInterceptor); - } - - protected static class TraceWebConfigurer extends WebMvcConfigurerAdapter { - private TraceHandlerInterceptor interceptor; - - public TraceWebConfigurer(TraceHandlerInterceptor interceptor) { - this.interceptor = interceptor; - } - - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(interceptor).addPathPatterns("/**"); - } - }*/ - @Bean @ConditionalOnMissingBean public FilterRegistrationBean traceFilter() { - Pattern pattern = StringUtils.hasText(skipPattern) ? Pattern.compile(skipPattern) + Pattern pattern = StringUtils.hasText(this.skipPattern) ? Pattern.compile(this.skipPattern) : TraceFilter.DEFAULT_SKIP_PATTERN; - return new FilterRegistrationBean(new TraceFilter(trace, pattern)); + return new FilterRegistrationBean(new TraceFilter(this.trace, pattern)); } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/DefaultTrace.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/trace/DefaultTrace.java similarity index 81% rename from spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/DefaultTrace.java rename to spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/trace/DefaultTrace.java index 7a7c10a7c..31ebd0d66 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/DefaultTrace.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/trace/DefaultTrace.java @@ -1,10 +1,18 @@ -package org.springframework.cloud.sleuth; +package org.springframework.cloud.sleuth.trace; -import static org.springframework.cloud.sleuth.Utils.error; +import static org.springframework.cloud.sleuth.util.ExceptionUtils.error; -import java.util.Collections; import java.util.concurrent.Callable; +import org.springframework.cloud.sleuth.IdGenerator; +import org.springframework.cloud.sleuth.MilliSpan; +import org.springframework.cloud.sleuth.NullScope; +import org.springframework.cloud.sleuth.Sampler; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.Trace; +import org.springframework.cloud.sleuth.TraceContextHolder; +import org.springframework.cloud.sleuth.TraceInfo; +import org.springframework.cloud.sleuth.TraceScope; import org.springframework.cloud.sleuth.event.SpanStartedEvent; import org.springframework.cloud.sleuth.instrument.TraceCallable; import org.springframework.cloud.sleuth.instrument.TraceRunnable; @@ -30,7 +38,7 @@ public class DefaultTrace implements Trace { @Override public TraceScope startSpan(String name) { - return this.startSpan(name, defaultSampler); + return this.startSpan(name, this.defaultSampler); } @Override @@ -40,7 +48,7 @@ public class DefaultTrace implements Trace { .begin(System.currentTimeMillis()) .name(name) .traceId(tinfo.getTraceId()) - .spanId(idGenerator.create()) + .spanId(this.idGenerator.create()) .parent(tinfo.getSpanId()) .build(); return doStart(span); @@ -81,8 +89,8 @@ public class DefaultTrace implements Trace { return MilliSpan.builder() .begin(System.currentTimeMillis()) .name(name) - .traceId(idGenerator.create()) - .spanId(idGenerator.create()) + .traceId(this.idGenerator.create()) + .spanId(this.idGenerator.create()) .build(); } else { return createChild(parent, name); @@ -95,14 +103,14 @@ public class DefaultTrace implements Trace { .name(childname) .traceId(parent.getTraceId()) .parent(parent.getSpanId()) - .spanId(idGenerator.create()) + .spanId(this.idGenerator.create()) .processId(parent.getProcessId()) .build(); } protected TraceScope doStart(Span span) { if (span != null) { - publisher.publishEvent(new SpanStartedEvent(this, span)); + this.publisher.publishEvent(new SpanStartedEvent(this, span)); } return continueSpan(span); } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/Utils.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/ExceptionUtils.java similarity index 68% rename from spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/Utils.java rename to spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/ExceptionUtils.java index 09c4dbac5..9afc1bebc 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/Utils.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/ExceptionUtils.java @@ -1,4 +1,4 @@ -package org.springframework.cloud.sleuth; +package org.springframework.cloud.sleuth.util; import lombok.extern.apachecommons.CommonsLog; @@ -6,7 +6,7 @@ import lombok.extern.apachecommons.CommonsLog; * @author Spencer Gibb */ @CommonsLog -public abstract class Utils { +public abstract class ExceptionUtils { public static void error(String msg) { log.error(msg); throw new RuntimeException(msg); diff --git a/spring-cloud-sleuth-core/src/main/resources/META-INF/spring.factories b/spring-cloud-sleuth-core/src/main/resources/META-INF/spring.factories index d1c8cd4aa..02addd7ca 100644 --- a/spring-cloud-sleuth-core/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-sleuth-core/src/main/resources/META-INF/spring.factories @@ -1,6 +1,6 @@ # Auto Configuration org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.sleuth.TraceAutoConfiguration,\ +org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration,\ org.springframework.cloud.sleuth.slf4j.SleuthSlf4jAutoConfiguration,\ org.springframework.cloud.sleuth.instrument.web.TraceWebAutoConfiguration,\ org.springframework.cloud.sleuth.instrument.web.client.TraceWebClientAutoConfiguration diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/DefaultTraceTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/DefaultTraceTests.java index bd287981d..ca2444369 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/DefaultTraceTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/DefaultTraceTests.java @@ -17,6 +17,7 @@ import org.springframework.cloud.sleuth.event.SpanStartedEvent; import org.springframework.cloud.sleuth.event.SpanStoppedEvent; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.sampler.IsTracingSampler; +import org.springframework.cloud.sleuth.trace.DefaultTrace; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEventPublisher; diff --git a/spring-cloud-sleuth-sample/pom.xml b/spring-cloud-sleuth-sample/pom.xml index 4b6422b47..854965d41 100644 --- a/spring-cloud-sleuth-sample/pom.xml +++ b/spring-cloud-sleuth-sample/pom.xml @@ -6,8 +6,8 @@ spring-cloud-sleuth-sample jar - Spring Cloud Consul Sample - Spring Cloud Consul Sample + Spring Cloud Sleuth Sample + Spring Cloud Sleuth Sample org.springframework.cloud @@ -21,7 +21,6 @@ org.springframework.boot spring-boot-maven-plugin - 1.2.1.RELEASE @@ -49,6 +48,10 @@ org.springframework.cloud spring-cloud-sleuth-core + + org.springframework.cloud + spring-cloud-sleuth-zipkin + org.springframework.boot spring-boot-starter-aop diff --git a/spring-cloud-sleuth-sample/src/main/resources/application.yml b/spring-cloud-sleuth-sample/src/main/resources/application.yml index 9dafd9d4e..7996c7205 100644 --- a/spring-cloud-sleuth-sample/src/main/resources/application.yml +++ b/spring-cloud-sleuth-sample/src/main/resources/application.yml @@ -5,6 +5,10 @@ spring: application: name: testSleuthApp +logging: + pattern: + console: '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([trace=%X{Trace-Id:-},span=%X{Span-Id:-}]){yellow} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wex' + endpoints: health: sensitive: false diff --git a/spring-cloud-sleuth-sample/src/main/resources/logback.xml b/spring-cloud-sleuth-sample/src/main/resources/logback.xml deleted file mode 100644 index 1698a3b29..000000000 --- a/spring-cloud-sleuth-sample/src/main/resources/logback.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-cloud-sleuth-zipkin/pom.xml b/spring-cloud-sleuth-zipkin/pom.xml index 262b5359d..abeb57887 100644 --- a/spring-cloud-sleuth-zipkin/pom.xml +++ b/spring-cloud-sleuth-zipkin/pom.xml @@ -46,6 +46,11 @@ spring-boot-starter-actuator true + + org.springframework.boot + spring-boot-configuration-processor + true + com.github.kristofa brave-client @@ -67,8 +72,9 @@ brave-zipkin-spancollector - org.springframework.cloud - spring-cloud-starter-zuul + com.netflix.zuul + zuul-core + true com.google.guava @@ -78,7 +84,7 @@ org.projectlombok lombok - provided + true org.springframework.boot diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/TraceData.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/TraceData.java deleted file mode 100644 index 1511242d6..000000000 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/TraceData.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.springframework.cloud.sleuth.zipkin; - -import lombok.Data; - -/** -* @author Spencer Gibb -*/ -@Data -public class TraceData { - private Long traceId; - private Long spanId; - private Long parentSpanId; - private Boolean shouldBeSampled; - private String spanName; -} diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.java index c4a3e69f4..6589318e4 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.java @@ -1,11 +1,26 @@ package org.springframework.cloud.sleuth.zipkin; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +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.IdGenerator; +import org.springframework.cloud.sleuth.Sampler; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + import com.github.kristofa.brave.AnnotationSubmitterConfig; import com.github.kristofa.brave.ClientTracer; import com.github.kristofa.brave.ClientTracerConfig; import com.github.kristofa.brave.EndPointSubmitterConfig; import com.github.kristofa.brave.FixedSampleRateTraceFilter; import com.github.kristofa.brave.ServerSpanThreadBinderConfig; +import com.github.kristofa.brave.ServerTracer; import com.github.kristofa.brave.ServerTracerConfig; import com.github.kristofa.brave.SpanCollector; import com.github.kristofa.brave.TraceFilter; @@ -15,16 +30,6 @@ import com.github.kristofa.brave.client.ClientResponseInterceptor; import com.github.kristofa.brave.client.spanfilter.SpanNameFilter; import com.github.kristofa.brave.zipkin.ZipkinSpanCollector; import com.google.common.base.Optional; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -import java.util.List; /** * @author Spencer Gibb @@ -34,15 +39,15 @@ import java.util.List; @ConditionalOnClass(ServerTracerConfig.class) @ConditionalOnProperty(value = "spring.cloud.sleuth.zipkin.enabled", matchIfMissing = true) @Import({ AnnotationSubmitterConfig.class, ClientTracerConfig.class, - EndPointSubmitterConfig.class, ServerSpanThreadBinderConfig.class, - ServerTracerConfig.class }) + EndPointSubmitterConfig.class, ServerSpanThreadBinderConfig.class, + ServerTracerConfig.class }) public class ZipkinAutoConfiguration { @Bean @ConditionalOnMissingBean public SpanCollector spanCollector() { - return new ZipkinSpanCollector(zipkinProperties().getHost(), - zipkinProperties().getPort()); + return new ZipkinSpanCollector(zipkinProperties().getHost(), zipkinProperties() + .getPort()); } @Bean @@ -61,6 +66,11 @@ public class ZipkinAutoConfiguration { return new TraceFilters(traceFilters); } + @Bean + public ZipkinTrace zipkinTrace(ServerTracer serverTracer, Sampler sampler, IdGenerator idGenerator, ApplicationEventPublisher publisher) { + return new ZipkinTrace(serverTracer, sampler, idGenerator, publisher); + } + @Configuration protected static class InterceptorConfig { @@ -73,14 +83,14 @@ public class ZipkinAutoConfiguration { @Bean @ConditionalOnMissingBean public ClientRequestInterceptor clientRequestInterceptor() { - return new ClientRequestInterceptor(clientTracer, - Optional.fromNullable(spanNameFilter)); + return new ClientRequestInterceptor(this.clientTracer, + Optional.fromNullable(this.spanNameFilter)); } @Bean @ConditionalOnMissingBean public ClientResponseInterceptor clientResponseInterceptor() { - return new ClientResponseInterceptor(clientTracer); + return new ClientResponseInterceptor(this.clientTracer); } } } diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinInterceptor.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinInterceptor.java deleted file mode 100644 index d184cb5f3..000000000 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinInterceptor.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.springframework.cloud.sleuth.zipkin; - -import com.github.kristofa.brave.EndPointSubmitter; -import com.github.kristofa.brave.ServerTracer; -import lombok.extern.apachecommons.CommonsLog; - -/** - * @author Spencer Gibb - */ -@CommonsLog -public abstract class ZipkinInterceptor { - - private final ServerTracer serverTracer; - private final EndPointSubmitter endPointSubmitter; - - protected ZipkinInterceptor(ServerTracer serverTracer, EndPointSubmitter endPointSubmitter) { - this.serverTracer = serverTracer; - this.endPointSubmitter = endPointSubmitter; - } - - public void preTrace(T context) { - submitEndpoint(context, endPointSubmitter); - - final TraceData traceData = getTraceData(context); - serverTracer.clearCurrentSpan(); - - if (Boolean.FALSE.equals(traceData.getShouldBeSampled())) { - serverTracer.setStateNoTracing(); - log.debug("Received indication that we should NOT trace."); - } else { - final String spanName = getSpanName(context, traceData); - if (traceData.getTraceId() != null && traceData.getSpanId() != null) { - - log.debug("Received span information as part of request."); - serverTracer.setStateCurrentTrace(traceData.getTraceId(), traceData.getSpanId(), - traceData.getParentSpanId(), spanName); - } else { - log.debug("Received no span state."); - serverTracer.setStateUnknown(spanName); - } - serverTracer.setServerReceived(); - } - } - - protected abstract void submitEndpoint(T context, EndPointSubmitter endPointSubmitter); - protected abstract TraceData getTraceData(T context); - protected abstract String getSpanName(T context, TraceData traceData); - - public void postTrace(T context) { - // We can submit this in any case. When server state is not set or - // we should not trace this request nothing will happen. - log.debug("Sending server send."); - try { - serverTracer.setServerSend(); - } finally { - serverTracer.clearCurrentSpan(); - } - } - - protected EndPointSubmitter getEndPointSubmitter() { - return endPointSubmitter; - } - - protected ServerTracer getServerTracer() { - return serverTracer; - } -} diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinRestTemplateInterceptor.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinRestTemplateInterceptor.java deleted file mode 100644 index bb6128ddf..000000000 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinRestTemplateInterceptor.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.springframework.cloud.sleuth.zipkin; - -import com.github.kristofa.brave.BraveHttpHeaders; -import com.github.kristofa.brave.ClientRequestAdapter; -import com.github.kristofa.brave.ClientResponseAdapter; -import com.github.kristofa.brave.client.ClientRequestInterceptor; -import com.github.kristofa.brave.client.ClientResponseInterceptor; -import com.google.common.base.Optional; -import lombok.SneakyThrows; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; - -import java.io.IOException; -import java.net.URI; - -/** - * @author Spencer Gibb - */ -public class ZipkinRestTemplateInterceptor implements ClientHttpRequestInterceptor { - - private final ClientRequestInterceptor clientRequestInterceptor; - private final ClientResponseInterceptor clientResponseInterceptor; - - public ZipkinRestTemplateInterceptor(ClientRequestInterceptor clientRequestInterceptor, ClientResponseInterceptor clientResponseInterceptor) { - this.clientRequestInterceptor = clientRequestInterceptor; - //TODO: ClientResponseInterceptor assumes >= 300 is error - this.clientResponseInterceptor = clientResponseInterceptor; - } - - @SneakyThrows - @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { - - RequestAdapter requestAdapter = new RequestAdapter(request); - clientRequestInterceptor.handle(requestAdapter, Optional.absent()); - - ClientHttpResponse response = null; - Exception exception = null; - try { - response = execution.execute(request, body); - } catch (final Exception e) { - exception = e; - } - - clientResponseInterceptor.handle(new ResponseAdapter(response)); - if(exception != null) { - throw exception; - } - return response; - } - - class RequestAdapter implements ClientRequestAdapter { - - HttpRequest request; - - public RequestAdapter(HttpRequest request) { - this.request = request; - } - - @Override - public URI getUri() { - return request.getURI(); - } - - @Override - public String getMethod() { - return request.getMethod().toString(); - } - - @Override - public Optional getSpanName() { - String spanNameHeader = request.getHeaders().getFirst(BraveHttpHeaders.SpanName.getName()); - return Optional.fromNullable(spanNameHeader); - } - - @Override - public void addHeader(String header, String value) { - request.getHeaders().add(header, value); - } - } - - class ResponseAdapter implements ClientResponseAdapter { - ClientHttpResponse response; - - public ResponseAdapter(ClientHttpResponse response) { - this.response = response; - } - - @SneakyThrows - @Override - public int getStatusCode() { - if (response == null) { - return 0; - } - return response.getRawStatusCode(); - } - } -} diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinTrace.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinTrace.java new file mode 100644 index 000000000..c703d8721 --- /dev/null +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinTrace.java @@ -0,0 +1,116 @@ +package org.springframework.cloud.sleuth.zipkin; + +import lombok.Data; +import lombok.extern.apachecommons.CommonsLog; + +import org.springframework.cloud.sleuth.IdGenerator; +import org.springframework.cloud.sleuth.Sampler; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.TraceScope; +import org.springframework.cloud.sleuth.trace.DefaultTrace; +import org.springframework.context.ApplicationEventPublisher; + +import com.github.kristofa.brave.ServerTracer; + +/** + * @author Spencer Gibb + */ +@CommonsLog +public class ZipkinTrace extends DefaultTrace { + + private final ServerTracer serverTracer; + + @Override + protected TraceScope doStart(final Span span) { + preTrace(span); + TraceScope scope = super.doStart(span); + scope.register(new Runnable() { + @Override + public void run() { + postTrace(span); + } + }); + return scope; + } + + public ZipkinTrace(ServerTracer serverTracer, Sampler defaultSampler, + IdGenerator idGenerator, ApplicationEventPublisher publisher) { + super(defaultSampler, idGenerator, publisher); + this.serverTracer = serverTracer; + } + + public void preTrace(Span context) { + final TraceData traceData = getTraceData(context); + this.serverTracer.clearCurrentSpan(); + + if (Boolean.FALSE.equals(traceData.getShouldBeSampled())) { + this.serverTracer.setStateNoTracing(); + log.debug("Received indication that we should NOT trace."); + } + else { + final String spanName = getSpanName(context, traceData); + if (traceData.getTraceId() != null && traceData.getSpanId() != null) { + + log.debug("Received span information as part of request."); + this.serverTracer.setStateCurrentTrace(traceData.getTraceId(), + traceData.getSpanId(), traceData.getParentSpanId(), spanName); + } + else { + log.debug("Received no span state."); + this.serverTracer.setStateUnknown(spanName); + } + this.serverTracer.setServerReceived(); + } + } + + protected TraceData getTraceData(Span context) { + TraceData trace = new TraceData(); + trace.setTraceId(hash(context.getTraceId())); + trace.setSpanId(hash(context.getSpanId())); + trace.setShouldBeSampled(true); + trace.setSpanName(context.getName()); + if (!context.getParents().isEmpty()) { + trace.setParentSpanId(hash(context.getParents().iterator().next())); + } + return trace; + }; + + protected String getSpanName(Span context, TraceData traceData) { + return context.getName(); + } + + public void postTrace(Span context) { + // We can submit this in any case. When server state is not set or + // we should not trace this request nothing will happen. + log.debug("Sending server send."); + try { + this.serverTracer.setServerSend(); + } + finally { + this.serverTracer.clearCurrentSpan(); + } + } + + protected ServerTracer getServerTracer() { + return this.serverTracer; + } + + private static long hash(String string) { + long h = 1125899906842597L; + int len = string.length(); + + for (int i = 0; i < len; i++) { + h = 31 * h + string.charAt(i); + } + return h; + } + + @Data + private static class TraceData { + private Long traceId; + private Long spanId; + private Long parentSpanId; + private Boolean shouldBeSampled; + private String spanName; + } +} diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/HttpServletRequestInterceptor.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/HttpServletRequestInterceptor.java deleted file mode 100644 index 28f07cfe8..000000000 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/HttpServletRequestInterceptor.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.springframework.cloud.sleuth.zipkin.web; - -import static com.github.kristofa.brave.BraveHttpHeaders.ParentSpanId; -import static com.github.kristofa.brave.BraveHttpHeaders.Sampled; -import static com.github.kristofa.brave.BraveHttpHeaders.SpanId; -import static com.github.kristofa.brave.BraveHttpHeaders.SpanName; -import static com.github.kristofa.brave.BraveHttpHeaders.TraceId; - -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; - -import com.github.kristofa.brave.EndPointSubmitter; -import com.github.kristofa.brave.ServerTracer; -import lombok.extern.apachecommons.CommonsLog; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.cloud.sleuth.zipkin.TraceData; -import org.springframework.cloud.sleuth.zipkin.ZipkinInterceptor; -import org.springframework.http.HttpHeaders; -import org.springframework.http.server.ServletServerHttpRequest; - -import com.github.kristofa.brave.IdConversion; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; - -/** - * @author Spencer Gibb - */ -@CommonsLog -public class HttpServletRequestInterceptor extends ZipkinInterceptor { - - public HttpServletRequestInterceptor(ServerTracer serverTracer, EndPointSubmitter endPointSubmitter) { - super(serverTracer, endPointSubmitter); - } - - @Override - public void submitEndpoint(HttpServletRequest servletRequest, EndPointSubmitter endPointSubmitter) { - if (!endPointSubmitter.endPointSubmitted()) { - final String localAddr = servletRequest.getLocalAddr(); - final int localPort = servletRequest.getLocalPort(); - final String contextPath = servletRequest.getContextPath(); - log.debug("Setting endpoint: addr: "+localAddr+", port: "+localPort+", contextpath: "+ contextPath); - endPointSubmitter.submit(localAddr, localPort, contextPath); - } - } - - @Override - public TraceData getTraceData(HttpServletRequest request) { - ServletServerHttpRequest req = new ServletServerHttpRequest(request); - HttpHeaders headers = req.getHeaders(); - - TraceData traceData = new TraceData(); - - for (Map.Entry> headerEntry : headers.entrySet()) { - log.debug(headerEntry.getKey() +" = "+ headerEntry.getValue()); - if (TraceId.getName().equalsIgnoreCase(headerEntry.getKey())) { - traceData.setTraceId(getFirstLong(headerEntry)); - } else if (SpanId.getName().equalsIgnoreCase(headerEntry.getKey())) { - traceData.setSpanId(getFirstLong(headerEntry)); - } else if (ParentSpanId.getName().equalsIgnoreCase(headerEntry.getKey())) { - traceData.setParentSpanId(getFirstLong(headerEntry)); - } else if (Sampled.getName().equalsIgnoreCase(headerEntry.getKey())) { - traceData.setShouldBeSampled(getFirstBoolean(headerEntry)); - } else if (SpanName.getName().equalsIgnoreCase(headerEntry.getKey())) { - traceData.setSpanName(getFirstString(headerEntry)); - } - } - return traceData; - } - - protected Long getFirstLong(final Map.Entry> headerEntry) { - final String value = getFirstString(headerEntry); - if (value == null) { - return null; - } - return IdConversion.convertToLong(value); - - } - - protected Boolean getFirstBoolean(final Map.Entry> headerEntry) { - final String firstStringValueFor = getFirstString(headerEntry); - return firstStringValueFor == null ? null : Boolean.valueOf(firstStringValueFor); - } - - protected String getFirstString(final Map.Entry> headerEntry) { - final List values = headerEntry.getValue(); - if (values != null && values.size() > 0) { - return headerEntry.getValue().get(0); - } - return null; - } - - @Override - protected String getSpanName(HttpServletRequest request, TraceData traceData) { - if (StringUtils.isNotBlank(traceData.getSpanName())) { - return traceData.getSpanName(); - } else { - //TODO: what is the functional equivalent of resteasy request.getPreprocessedPath(); - UriComponents components = UriComponentsBuilder.fromUriString(request.getRequestURL().toString()).build(); - StringBuilder preprocessedPath = new StringBuilder(); - for (String segment : components.getPathSegments()) { - preprocessedPath.append("/").append(segment); - } - if (preprocessedPath.length() == 0) { - preprocessedPath.append("/"); - } - return preprocessedPath.toString(); - } - } -} diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/ZipkinFilter.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/ZipkinFilter.java index f8de9d915..037332200 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/ZipkinFilter.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/ZipkinFilter.java @@ -1,6 +1,6 @@ package org.springframework.cloud.sleuth.zipkin.web; -import org.springframework.cloud.sleuth.zipkin.ZipkinInterceptor; +import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -8,36 +8,54 @@ import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; -import java.io.IOException; +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; + +import com.github.kristofa.brave.EndPointSubmitter; /** * @author Spencer Gibb */ +@Order(Ordered.HIGHEST_PRECEDENCE + 2) public class ZipkinFilter implements Filter { - private final ZipkinInterceptor zipkinInterceptor; + @Value("${spring.application.name:application}") + private String serviceName; - public ZipkinFilter(ZipkinInterceptor zipkinInterceptor) { - this.zipkinInterceptor = zipkinInterceptor; - } + private EndPointSubmitter endPointSubmitter; + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } - @Override - public void init(FilterConfig filterConfig) throws ServletException { - //NOOP - } + public ZipkinFilter(EndPointSubmitter endPointSubmitter) { + this.endPointSubmitter = endPointSubmitter; + } - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - zipkinInterceptor.preTrace(request); + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // NOOP + } - chain.doFilter(request, response); + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + if (!this.endPointSubmitter.endPointSubmitted()) { + final String localAddr = request.getLocalAddr(); + final int localPort = request.getLocalPort(); + final String contextPath = this.serviceName + + ((request instanceof HttpServletRequest) ? ((HttpServletRequest) request) + .getContextPath() : ""); + this.endPointSubmitter.submit(localAddr, localPort, contextPath); + } + chain.doFilter(request, response); + } - zipkinInterceptor.postTrace(request); - } - - @Override - public void destroy() { - //NOOP - } + @Override + public void destroy() { + // NOOP + } } diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/ZipkinHandlerInterceptor.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/ZipkinHandlerInterceptor.java deleted file mode 100644 index fc62196a4..000000000 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/ZipkinHandlerInterceptor.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.springframework.cloud.sleuth.zipkin.web; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import lombok.extern.apachecommons.CommonsLog; - -import org.springframework.cloud.sleuth.zipkin.ZipkinInterceptor; -import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.ModelAndView; - -/** - * @author Spencer Gibb - */ -@CommonsLog -public class ZipkinHandlerInterceptor implements HandlerInterceptor { - - private final ZipkinInterceptor zipkinInterceptor; - - public ZipkinHandlerInterceptor(ZipkinInterceptor zipkinInterceptor) { - this.zipkinInterceptor = zipkinInterceptor; - } - - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - zipkinInterceptor.preTrace(request); - return true; - } - - @Override - public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { - zipkinInterceptor.postTrace(request); - } - - @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { - } - -} diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/ZipkinWebAutoConfiguration.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/ZipkinWebAutoConfiguration.java index ba22a6999..0f1f69ccd 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/ZipkinWebAutoConfiguration.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/web/ZipkinWebAutoConfiguration.java @@ -1,22 +1,18 @@ package org.springframework.cloud.sleuth.zipkin.web; -import com.github.kristofa.brave.EndPointSubmitter; -import com.github.kristofa.brave.ServerTracer; -import com.github.kristofa.brave.ServerTracerConfig; -import com.github.kristofa.brave.client.ClientRequestInterceptor; -import com.github.kristofa.brave.client.ClientResponseInterceptor; 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.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration; import org.springframework.cloud.sleuth.zipkin.ZipkinAutoConfiguration; -import org.springframework.cloud.sleuth.zipkin.ZipkinRestTemplateInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +import com.github.kristofa.brave.EndPointSubmitter; +import com.github.kristofa.brave.ServerTracerConfig; /** * @author Spencer Gibb @@ -26,62 +22,15 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter @ConditionalOnWebApplication @ConditionalOnProperty(value = "spring.cloud.sleuth.zipkin.enabled", matchIfMissing = true) @AutoConfigureAfter(ZipkinAutoConfiguration.class) +@AutoConfigureBefore(TraceAutoConfiguration.class) public class ZipkinWebAutoConfiguration { @Autowired private EndPointSubmitter endPointSubmitter; - @Autowired - private ServerTracer serverTracer; - @Bean - public ZipkinHandlerInterceptor zipkinHandlerInterceptor() { - return new ZipkinHandlerInterceptor(httpServletRequestInterceptor()); + public ZipkinFilter zipkinFilter() { + return new ZipkinFilter(this.endPointSubmitter); } - @Bean - public ZipkinFilter zipkinFilter() { - return new ZipkinFilter(httpServletRequestInterceptor()); - } - - @Bean - public HttpServletRequestInterceptor httpServletRequestInterceptor() { - return new HttpServletRequestInterceptor(serverTracer, endPointSubmitter); - } - - @Bean - @ConditionalOnBean(ZipkinHandlerInterceptor.class) - public WebMvcConfigurerAdapter webMvcConfigurerAdapter(ZipkinHandlerInterceptor zipkinHandlerInterceptor) { - return new ZipkinWebConfigurer(zipkinHandlerInterceptor); - } - - @Configuration - protected static class RestTemplateConfig { - - @Autowired - private ClientRequestInterceptor clientRequestInterceptor; - - @Autowired - private ClientResponseInterceptor clientResponseInterceptor; - - @Bean - public ZipkinRestTemplateInterceptor zipkinRestTemplateInterceptor() { - return new ZipkinRestTemplateInterceptor(clientRequestInterceptor, - clientResponseInterceptor); - } - - } - - protected static class ZipkinWebConfigurer extends WebMvcConfigurerAdapter { - private ZipkinHandlerInterceptor interceptor; - - public ZipkinWebConfigurer(ZipkinHandlerInterceptor interceptor) { - this.interceptor = interceptor; - } - - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(interceptor).addPathPatterns("/**"); - } - } } diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/zuul/ZipkinPostFilter.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/zuul/ZipkinPostFilter.java deleted file mode 100644 index ced38c08a..000000000 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/zuul/ZipkinPostFilter.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.springframework.cloud.sleuth.zipkin.zuul; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import lombok.extern.apachecommons.CommonsLog; -import org.springframework.cloud.sleuth.zipkin.ZipkinInterceptor; - -import javax.servlet.http.HttpServletRequest; - -/** - * @author Spencer Gibb - */ -@CommonsLog -public class ZipkinPostFilter extends ZuulFilter { - - private ZipkinInterceptor zipkinInterceptor; - - public ZipkinPostFilter(ZipkinInterceptor zipkinInterceptor) { - this.zipkinInterceptor = zipkinInterceptor; - } - - @Override - public String filterType() { - return "post"; - } - - @Override - public int filterOrder() { - return 0; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); - - zipkinInterceptor.postTrace(request); - - return null; - } -} diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/zuul/ZipkinPreFilter.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/zuul/ZipkinPreFilter.java deleted file mode 100644 index 6d9e1857a..000000000 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/zuul/ZipkinPreFilter.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.springframework.cloud.sleuth.zipkin.zuul; - -import javax.servlet.http.HttpServletRequest; - -import lombok.extern.apachecommons.CommonsLog; - -import org.springframework.cloud.sleuth.zipkin.ZipkinInterceptor; - -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; - -/** - * @author Spencer Gibb - */ -@CommonsLog -public class ZipkinPreFilter extends ZuulFilter { - - private ZipkinInterceptor zipkinInterceptor; - - public ZipkinPreFilter(ZipkinInterceptor zipkinInterceptor) { - this.zipkinInterceptor = zipkinInterceptor; - } - - @Override - public String filterType() { - return "pre"; - } - - @Override - public int filterOrder() { - return 0; - } - - @Override - public boolean shouldFilter() { - return true; - } - - @Override - public Object run() { - HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); - - zipkinInterceptor.preTrace(request); - - return null; - } -} diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/zuul/ZipkinZuulAutoConfiguration.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/zuul/ZipkinZuulAutoConfiguration.java deleted file mode 100644 index 1ab83ebe5..000000000 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/zuul/ZipkinZuulAutoConfiguration.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.springframework.cloud.sleuth.zipkin.zuul; - -import com.netflix.zuul.ZuulFilter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.cloud.sleuth.zipkin.ZipkinInterceptor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - */ -@Configuration -@ConditionalOnClass(ZuulFilter.class) -@ConditionalOnBean(ZipkinInterceptor.class) -public class ZipkinZuulAutoConfiguration { - - @Bean - public ZipkinPreFilter zipkinPreFilter(ZipkinInterceptor zipkinInterceptor) { - return new ZipkinPreFilter(zipkinInterceptor); - } - - @Bean - public ZipkinPostFilter zipkinPostFilter(ZipkinInterceptor zipkinInterceptor) { - return new ZipkinPostFilter(zipkinInterceptor); - } -}