diff --git a/pom.xml b/pom.xml
index 1e06126d4..a9823192e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,6 @@
spring-cloud-sleuth-core
- spring-cloud-sleuth-zipkin
spring-cloud-sleuth-sample
docs
@@ -155,6 +154,11 @@
hystrix-core
1.4.5
+
+ com.netflix.zuul
+ zuul-core
+ 1.0.28
+
org.aspectj
aspectjrt
diff --git a/spring-cloud-sleuth-core/pom.xml b/spring-cloud-sleuth-core/pom.xml
index bcbab14b3..e1ca6b9d9 100644
--- a/spring-cloud-sleuth-core/pom.xml
+++ b/spring-cloud-sleuth-core/pom.xml
@@ -47,6 +47,11 @@
hystrix-core
true
+
+ com.netflix.zuul
+ zuul-core
+ true
+
io.reactivex
rxjava
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 4429cafbb..d757d1f82 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
@@ -86,6 +86,7 @@ public class TraceFilter extends OncePerRequestFilter {
// Send new span id back
addToResponseIfNotPresent(response, SPAN_ID_NAME, span.getSpanId());
+ //TODO: trace description?
traceScope = trace.startSpan("traceFilter", span);
}
else {
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostFilter.java
new file mode 100644
index 000000000..910dbadb3
--- /dev/null
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostFilter.java
@@ -0,0 +1,46 @@
+package org.springframework.cloud.sleuth.instrument.zuul;
+
+import org.springframework.cloud.sleuth.Trace;
+import org.springframework.cloud.sleuth.TraceScope;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+
+/**
+ * @author Spencer Gibb
+ */
+public class TracePostFilter extends ZuulFilter {
+
+ private Trace trace;
+
+ public TracePostFilter(Trace trace) {
+ this.trace = trace;
+ }
+
+ @Override
+ public String filterType() {
+ return "post";
+ }
+
+ @Override
+ public int filterOrder() {
+ return 0;
+ }
+
+ @Override
+ public boolean shouldFilter() {
+ return true;
+ }
+
+ @Override
+ public Object run() {
+ TraceScope traceScope = (TraceScope) RequestContext.getCurrentContext().get(
+ "traceScope");
+
+ if (traceScope != null) {
+ traceScope.close();
+ }
+
+ return null;
+ }
+}
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreFilter.java
new file mode 100644
index 000000000..6d7e0e3a6
--- /dev/null
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreFilter.java
@@ -0,0 +1,72 @@
+package org.springframework.cloud.sleuth.instrument.zuul;
+
+import static org.springframework.cloud.sleuth.Trace.SPAN_ID_NAME;
+import static org.springframework.cloud.sleuth.Trace.TRACE_ID_NAME;
+import static org.springframework.util.StringUtils.hasText;
+
+import java.util.Collections;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.cloud.sleuth.MilliSpan;
+import org.springframework.cloud.sleuth.Span;
+import org.springframework.cloud.sleuth.Trace;
+import org.springframework.cloud.sleuth.TraceScope;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+
+/**
+ * @author Spencer Gibb
+ */
+public class TracePreFilter extends ZuulFilter {
+
+ private Trace trace;
+
+ public TracePreFilter(Trace trace) {
+ this.trace = trace;
+ }
+
+ @Override
+ public String filterType() {
+ return "pre";
+ }
+
+ @Override
+ public int filterOrder() {
+ return 0;
+ }
+
+ @Override
+ public boolean shouldFilter() {
+ return true;
+ }
+
+ @Override
+ public Object run() {
+ RequestContext context = RequestContext.getCurrentContext();
+ HttpServletRequest request = context.getRequest();
+
+ String spanId = request.getHeader(SPAN_ID_NAME);
+ String traceId = request.getHeader(TRACE_ID_NAME);
+ TraceScope traceScope = null;
+ if (hasText(spanId) && hasText(traceId)) {
+
+ Span span = MilliSpan.builder().traceId(traceId)
+ .parents(Collections.singletonList(spanId))
+ // TODO: use parent() when lombok plugin supports it
+ .build();
+
+ // TODO: trace description?
+ traceScope = trace.startSpan("traceZuulFilter", span);
+ }
+ else {
+ traceScope = trace.startSpan("traceZuulFilter");
+
+ }
+
+ context.set("traceScope", traceScope);
+
+ return null;
+ }
+}
diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulAutoConfiguration.java
new file mode 100644
index 000000000..18d542435
--- /dev/null
+++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulAutoConfiguration.java
@@ -0,0 +1,28 @@
+package org.springframework.cloud.sleuth.instrument.zuul;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.cloud.sleuth.Trace;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.netflix.zuul.ZuulFilter;
+
+/**
+ * @author Spencer Gibb
+ */
+@Configuration
+@ConditionalOnClass(ZuulFilter.class)
+@ConditionalOnBean(Trace.class)
+public class TraceZuulAutoConfiguration {
+
+ @Bean
+ public TracePreFilter tracePreFilter(Trace trace) {
+ return new TracePreFilter(trace);
+ }
+
+ @Bean
+ public TracePostFilter tracePostFilter(Trace trace) {
+ return new TracePostFilter(trace);
+ }
+}