Fixed closing of Zuul span, added local component span for zuul

fixes #242
This commit is contained in:
Marcin Grzejszczak
2016-04-02 00:04:28 +02:00
parent 441bd0834e
commit b3c78c139d
5 changed files with 76 additions and 15 deletions

View File

@@ -17,7 +17,7 @@
package org.springframework.cloud.sleuth.instrument.zuul; package org.springframework.cloud.sleuth.instrument.zuul;
import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.SpanAccessor; import org.springframework.cloud.sleuth.Tracer;
import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.ZuulFilter;
@@ -29,10 +29,10 @@ import com.netflix.zuul.ZuulFilter;
*/ */
public class TracePostZuulFilter extends ZuulFilter { public class TracePostZuulFilter extends ZuulFilter {
private final SpanAccessor spanAccessor; private final Tracer tracer;
public TracePostZuulFilter(SpanAccessor spanAccessor) { public TracePostZuulFilter(Tracer tracer) {
this.spanAccessor = spanAccessor; this.tracer = tracer;
} }
@Override @Override
@@ -44,6 +44,7 @@ public class TracePostZuulFilter extends ZuulFilter {
public Object run() { public Object run() {
// TODO: the client sent event should come from the client not the filter! // TODO: the client sent event should come from the client not the filter!
getCurrentSpan().logEvent(Span.CLIENT_RECV); getCurrentSpan().logEvent(Span.CLIENT_RECV);
this.tracer.close(getCurrentSpan());
return null; return null;
} }
@@ -58,6 +59,6 @@ public class TracePostZuulFilter extends ZuulFilter {
} }
private Span getCurrentSpan() { private Span getCurrentSpan() {
return this.spanAccessor.getCurrentSpan(); return this.tracer.getCurrentSpan();
} }
} }

View File

@@ -20,7 +20,9 @@ import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.SpanInjector; import org.springframework.cloud.sleuth.SpanInjector;
import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.Tracer;
import com.netflix.zuul.ExecutionStatus;
import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.ZuulFilterResult;
import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.context.RequestContext;
/** /**
@@ -32,6 +34,8 @@ import com.netflix.zuul.context.RequestContext;
*/ */
public class TracePreZuulFilter extends ZuulFilter { public class TracePreZuulFilter extends ZuulFilter {
private static final String ZUUL_COMPONENT = "zuul";
private final Tracer tracer; private final Tracer tracer;
private final SpanInjector<RequestContext> spanInjector; private final SpanInjector<RequestContext> spanInjector;
@@ -47,12 +51,22 @@ public class TracePreZuulFilter extends ZuulFilter {
@Override @Override
public Object run() { public Object run() {
getCurrentSpan().logEvent(Span.CLIENT_SEND);
return null;
}
@Override
public ZuulFilterResult runFilter() {
RequestContext ctx = RequestContext.getCurrentContext(); RequestContext ctx = RequestContext.getCurrentContext();
Span span = getCurrentSpan(); Span span = getCurrentSpan();
this.spanInjector.inject(span, ctx); Span newSpan = this.tracer.createSpan(span.getName(), span);
// TODO: the client sent event should come from the client not the filter! newSpan.tag(Span.SPAN_LOCAL_COMPONENT_TAG_NAME, ZUUL_COMPONENT);
span.logEvent(Span.CLIENT_SEND); this.spanInjector.inject(newSpan, ctx);
return null; ZuulFilterResult result = super.runFilter();
if (ExecutionStatus.SUCCESS != result.getStatus()) {
this.tracer.close(newSpan);
}
return result;
} }
private Span getCurrentSpan() { private Span getCurrentSpan() {

View File

@@ -22,7 +22,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.sleuth.SpanAccessor;
import org.springframework.cloud.sleuth.SpanInjector; import org.springframework.cloud.sleuth.SpanInjector;
import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration; import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
@@ -63,8 +62,8 @@ public class TraceZuulAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public TracePostZuulFilter tracePostZuulFilter(SpanAccessor accessor) { public TracePostZuulFilter tracePostZuulFilter(Tracer tracer) {
return new TracePostZuulFilter(accessor); return new TracePostZuulFilter(tracer);
} }
@Bean @Bean

View File

@@ -52,10 +52,11 @@ public class TracePostZuulFilterTests {
} }
@Test @Test
public void filterPublishesEvent() throws Exception { public void filterPublishesEventAndClosesSpan() throws Exception {
Span span = this.tracer.createSpan("http:start"); Span span = this.tracer.createSpan("http:start");
this.filter.run(); this.filter.run();
then(span).hasLoggedAnEvent(Span.CLIENT_RECV); then(span).hasLoggedAnEvent(Span.CLIENT_RECV);
then(this.tracer.getCurrentSpan()).isNull();
} }
} }

View File

@@ -17,6 +17,7 @@
package org.springframework.cloud.sleuth.instrument.zuul; package org.springframework.cloud.sleuth.instrument.zuul;
import java.util.Random; import java.util.Random;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@@ -31,6 +32,7 @@ import org.springframework.cloud.sleuth.trace.DefaultTracer;
import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder;
import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.monitoring.MonitoringHelper;
import static org.assertj.core.api.BDDAssertions.then; import static org.assertj.core.api.BDDAssertions.then;
@@ -45,6 +47,11 @@ public class TracePreZuulFilterTests {
private TracePreZuulFilter filter = new TracePreZuulFilter(this.tracer, new RequestContextInjector()); private TracePreZuulFilter filter = new TracePreZuulFilter(this.tracer, new RequestContextInjector());
@Before
public void setup() {
MonitoringHelper.initMocks();
}
@After @After
@Before @Before
public void clean() { public void clean() {
@@ -56,7 +63,7 @@ public class TracePreZuulFilterTests {
public void filterAddsHeaders() throws Exception { public void filterAddsHeaders() throws Exception {
this.tracer.createSpan("http:start"); this.tracer.createSpan("http:start");
this.filter.run(); this.filter.runFilter();
RequestContext ctx = RequestContext.getCurrentContext(); RequestContext ctx = RequestContext.getCurrentContext();
then(ctx.getZuulRequestHeaders().get(Span.TRACE_ID_NAME)) then(ctx.getZuulRequestHeaders().get(Span.TRACE_ID_NAME))
@@ -69,7 +76,7 @@ public class TracePreZuulFilterTests {
public void notSampledIfNotExportable() throws Exception { public void notSampledIfNotExportable() throws Exception {
this.tracer.createSpan("http:start", NeverSampler.INSTANCE); this.tracer.createSpan("http:start", NeverSampler.INSTANCE);
this.filter.run(); this.filter.runFilter();
RequestContext ctx = RequestContext.getCurrentContext(); RequestContext ctx = RequestContext.getCurrentContext();
then(ctx.getZuulRequestHeaders().get(Span.TRACE_ID_NAME)) then(ctx.getZuulRequestHeaders().get(Span.TRACE_ID_NAME))
@@ -78,4 +85,43 @@ public class TracePreZuulFilterTests {
.isEqualTo(Span.SPAN_NOT_SAMPLED); .isEqualTo(Span.SPAN_NOT_SAMPLED);
} }
@Test
public void shouldCloseSpanWhenExceptionIsThrown() throws Exception {
Span startedSpan = this.tracer.createSpan("http:start", NeverSampler.INSTANCE);
final AtomicReference<Span> span = new AtomicReference<>();
new TracePreZuulFilter(this.tracer, new RequestContextInjector()) {
@Override
public Object run() {
super.run();
span.set(TracePreZuulFilterTests.this.tracer.getCurrentSpan());
throw new RuntimeException();
}
}.runFilter();
then(startedSpan).isNotEqualTo(span.get());
then(span.get().logs()).extracting("event").contains(Span.CLIENT_SEND);
then(this.tracer.getCurrentSpan()).isEqualTo(startedSpan);
}
@Test
public void shouldNotCloseSpanWhenNoExceptionIsThrown() throws Exception {
Span startedSpan = this.tracer.createSpan("http:start", NeverSampler.INSTANCE);
final AtomicReference<Span> span = new AtomicReference<>();
new TracePreZuulFilter(this.tracer, new RequestContextInjector()) {
@Override
public Object run() {
span.set(TracePreZuulFilterTests.this.tracer.getCurrentSpan());
return super.run();
}
}.runFilter();
then(startedSpan).isNotEqualTo(span.get());
then(span.get().logs()).extracting("event").contains(Span.CLIENT_SEND);
then(span.get().tags()).containsKey(Span.SPAN_LOCAL_COMPONENT_TAG_NAME);
then(this.tracer.getCurrentSpan()).isEqualTo(span.get());
}
} }