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 20ef24468..41be7dd8c 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 @@ -134,7 +134,7 @@ public class TraceFilter extends GenericFilterBean { } } if (log.isTraceEnabled()) { - log.trace("Received a request to uri [" + uri + "] that matches the skip pattern [" + skip + "]"); + log.trace("Received a request to uri [" + uri + "] that matches the should be skipped [" + skip + "]"); } // in case of a response with exception status a exception controller will close the span if (!httpStatusSuccessful(response) && isSpanContinued(request)) { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilter.java index ff32b5a44..4c91cf1af 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilter.java @@ -18,13 +18,15 @@ package org.springframework.cloud.sleuth.instrument.zuul; import java.lang.invoke.MethodHandles; -import com.netflix.zuul.ZuulFilter; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; +import com.netflix.zuul.ZuulFilter; +import com.netflix.zuul.context.RequestContext; + /**8 * A post request {@link ZuulFilter} that publishes an event upon start of the filtering * @@ -36,9 +38,11 @@ public class TracePostZuulFilter extends ZuulFilter { private static final Log log = LogFactory.getLog(MethodHandles.lookup().lookupClass()); private final Tracer tracer; + private final TraceKeys traceKeys; - public TracePostZuulFilter(Tracer tracer) { + public TracePostZuulFilter(Tracer tracer, TraceKeys traceKeys) { this.tracer = tracer; + this.traceKeys = traceKeys; } @Override @@ -53,6 +57,8 @@ public class TracePostZuulFilter extends ZuulFilter { if (log.isTraceEnabled()) { log.trace("Closing current client span " + getCurrentSpan() + ""); } + this.tracer.addTag(this.traceKeys.getHttp().getStatusCode(), + String.valueOf(RequestContext.getCurrentContext().getResponse().getStatus())); this.tracer.close(getCurrentSpan()); return null; } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilter.java index 090fd10c7..bdc7db600 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilter.java @@ -17,17 +17,19 @@ package org.springframework.cloud.sleuth.instrument.zuul; import java.lang.invoke.MethodHandles; - -import com.netflix.zuul.ExecutionStatus; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.ZuulFilterResult; -import com.netflix.zuul.context.RequestContext; +import java.net.URI; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanInjector; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; + +import com.netflix.zuul.ExecutionStatus; +import com.netflix.zuul.ZuulFilter; +import com.netflix.zuul.ZuulFilterResult; +import com.netflix.zuul.context.RequestContext; /** * A pre request {@link ZuulFilter} that sets tracing related headers on the request @@ -44,10 +46,13 @@ public class TracePreZuulFilter extends ZuulFilter { private final Tracer tracer; private final SpanInjector spanInjector; + private final HttpTraceKeysInjector httpTraceKeysInjector; - public TracePreZuulFilter(Tracer tracer, SpanInjector spanInjector) { + public TracePreZuulFilter(Tracer tracer, SpanInjector spanInjector, + HttpTraceKeysInjector httpTraceKeysInjector) { this.tracer = tracer; this.spanInjector = spanInjector; + this.httpTraceKeysInjector = httpTraceKeysInjector; } @Override @@ -71,6 +76,7 @@ public class TracePreZuulFilter extends ZuulFilter { Span newSpan = this.tracer.createSpan(span.getName(), span); newSpan.tag(Span.SPAN_LOCAL_COMPONENT_TAG_NAME, ZUUL_COMPONENT); this.spanInjector.inject(newSpan, ctx); + this.httpTraceKeysInjector.addRequestTags(newSpan, URI.create(ctx.getRequest().getRequestURI()), ctx.getRequest().getMethod()); if (log.isTraceEnabled()) { log.trace("New Zuul Span is " + newSpan + ""); } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactory.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactory.java index dafdcd4e6..a6971170e 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactory.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactory.java @@ -102,7 +102,7 @@ public class TraceRestClientRibbonCommandFactory extends RestClientRibbonCommand this.httpTraceKeysInjector.addRequestTags(span, getUri(), getVerb().verb()); span.logEvent(Span.CLIENT_SEND); if (log.isTraceEnabled()) { - log.trace("Span is " + span); + log.trace("Span from RibbonCommandFactory is " + span); } } 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 index eaedb0fa0..54101331e 100644 --- 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 @@ -23,6 +23,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.sleuth.SpanInjector; +import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration; import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; @@ -51,8 +52,8 @@ public class TraceZuulAutoConfiguration { @Bean @ConditionalOnMissingBean public TracePreZuulFilter tracePreZuulFilter(Tracer tracer, - SpanInjector spanInjector) { - return new TracePreZuulFilter(tracer, spanInjector); + SpanInjector spanInjector, HttpTraceKeysInjector httpTraceKeysInjector) { + return new TracePreZuulFilter(tracer, spanInjector, httpTraceKeysInjector); } @Bean @@ -64,8 +65,8 @@ public class TraceZuulAutoConfiguration { @Bean @ConditionalOnMissingBean - public TracePostZuulFilter tracePostZuulFilter(Tracer tracer) { - return new TracePostZuulFilter(tracer); + public TracePostZuulFilter tracePostZuulFilter(Tracer tracer, TraceKeys traceKeys) { + return new TracePostZuulFilter(tracer, traceKeys); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/assertions/ListOfSpansAssert.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/assertions/ListOfSpansAssert.java index 0a8252abe..cd3e6ee98 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/assertions/ListOfSpansAssert.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/assertions/ListOfSpansAssert.java @@ -17,11 +17,9 @@ package org.springframework.cloud.sleuth.assertions; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; -import java.util.stream.Collectors; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -29,6 +27,12 @@ import org.assertj.core.api.AbstractAssert; import org.assertj.core.api.Assertions; import org.springframework.cloud.sleuth.Span; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; + public class ListOfSpansAssert extends AbstractAssert { private static final Log log = LogFactory.getLog(ListOfSpansAssert.class); @@ -47,18 +51,34 @@ public class ListOfSpansAssert extends AbstractAssert parentSpanIds = this.actual.spans.stream().flatMap(span -> span.getParents().stream()) - .distinct().collect(Collectors.toList()); + .distinct().collect(toList()); List spanIds = this.actual.spans.stream() .map(Span::getSpanId).distinct() - .collect(Collectors.toList()); + .collect(toList()); List difference = new ArrayList<>(parentSpanIds); difference.removeAll(spanIds); log.info("Difference between parent ids and span ids " + - difference.stream().map(span -> "id as long [" + span + "] and as hex [" + Span.idToHex(span) + "]").collect(Collectors.joining("\n"))); + difference.stream().map(span -> "id as long [" + span + "] and as hex [" + Span.idToHex(span) + "]").collect( + joining("\n"))); Assertions.assertThat(spanIds).containsAll(parentSpanIds); return this; } + public ListOfSpansAssert clientSideSpanWithNameHasTags(String name, Map tags) { + isNotNull(); + printSpans(); + List matchingSpans = this.actual.spans.stream() + .filter(span -> span.getName().equals(name) && span.logs().stream().filter(entry -> + entry.getEvent().equals(Span.CLIENT_SEND)).findAny().isPresent()).collect(toList()); + Assertions.assertThat(matchingSpans).isNotEmpty(); + List> matchingSpansTags = matchingSpans.stream().map(Span::tags).collect( + toList()); + Map spanTags = new HashMap<>(); + matchingSpansTags.forEach(spanTags::putAll); + Assertions.assertThat(spanTags.entrySet()).containsAll(tags.entrySet()); + return this; + } + private void printSpans() { try { log.info("Stored spans " + this.objectMapper.writeValueAsString(this.actual.spans)); diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilterTests.java index a2bd48a6d..14e521771 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilterTests.java @@ -16,39 +16,56 @@ package org.springframework.cloud.sleuth.instrument.zuul; +import javax.servlet.http.HttpServletResponse; import java.util.Random; +import com.netflix.zuul.context.RequestContext; + import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.BDDMockito; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; import org.springframework.cloud.sleuth.DefaultSpanNamer; import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.log.NoOpSpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; -import com.netflix.zuul.context.RequestContext; - import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; /** * @author Dave Syer * */ +@RunWith(MockitoJUnitRunner.class) public class TracePostZuulFilterTests { + @Mock HttpServletResponse httpServletResponse; + private DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), new DefaultSpanNamer(), new NoOpSpanLogger(), new NoOpSpanReporter()); - private TracePostZuulFilter filter = new TracePostZuulFilter(this.tracer); + private TracePostZuulFilter filter = new TracePostZuulFilter(this.tracer, new TraceKeys()); @After - @Before public void clean() { RequestContext.getCurrentContext().unset(); TestSpanContextHolder.removeCurrentSpan(); + RequestContext.testSetCurrentContext(null); + } + + @Before + public void setup() { + RequestContext requestContext = new RequestContext(); + BDDMockito.given(this.httpServletResponse.getStatus()).willReturn(200); + requestContext.setResponse(this.httpServletResponse); + RequestContext.testSetCurrentContext(requestContext); } @Test @@ -56,7 +73,9 @@ public class TracePostZuulFilterTests { Span span = this.tracer.createSpan("http:start"); this.filter.run(); - then(span).hasLoggedAnEvent(Span.CLIENT_RECV); + then(span) + .hasLoggedAnEvent(Span.CLIENT_RECV) + .hasATag("http.status_code", "200"); then(this.tracer.getCurrentSpan()).isNull(); } } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilterTests.java index 5a26ec59d..fd4bf49af 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilterTests.java @@ -16,47 +16,63 @@ package org.springframework.cloud.sleuth.instrument.zuul; +import javax.servlet.http.HttpServletRequest; import java.util.Random; import java.util.concurrent.atomic.AtomicReference; +import com.netflix.zuul.context.RequestContext; +import com.netflix.zuul.monitoring.MonitoringHelper; + import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.BDDMockito; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; import org.springframework.cloud.sleuth.DefaultSpanNamer; import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.TraceKeys; +import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; import org.springframework.cloud.sleuth.log.NoOpSpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.sampler.NeverSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.monitoring.MonitoringHelper; - -import static org.assertj.core.api.BDDAssertions.then; +import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; /** * @author Dave Syer * */ +@RunWith(MockitoJUnitRunner.class) public class TracePreZuulFilterTests { + @Mock HttpServletRequest httpServletRequest; + private DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), new DefaultSpanNamer(), new NoOpSpanLogger(), new NoOpSpanReporter()); - private TracePreZuulFilter filter = new TracePreZuulFilter(this.tracer, new RequestContextInjector()); + private TracePreZuulFilter filter = new TracePreZuulFilter(this.tracer, new RequestContextInjector(), + new HttpTraceKeysInjector(this.tracer, new TraceKeys())); + + @After + public void clean() { + RequestContext.getCurrentContext().unset(); + TestSpanContextHolder.removeCurrentSpan(); + RequestContext.testSetCurrentContext(null); + } @Before public void setup() { MonitoringHelper.initMocks(); - } - - @After - @Before - public void clean() { - RequestContext.getCurrentContext().unset(); - TestSpanContextHolder.removeCurrentSpan(); + RequestContext requestContext = new RequestContext(); + BDDMockito.given(this.httpServletRequest.getRequestURI()).willReturn("http://foo.bar"); + BDDMockito.given(this.httpServletRequest.getMethod()).willReturn("GET"); + requestContext.setRequest(this.httpServletRequest); + RequestContext.testSetCurrentContext(requestContext); } @Test @@ -85,13 +101,13 @@ public class TracePreZuulFilterTests { .isEqualTo(Span.SPAN_NOT_SAMPLED); } - @Test public void shouldCloseSpanWhenExceptionIsThrown() throws Exception { - Span startedSpan = this.tracer.createSpan("http:start", NeverSampler.INSTANCE); + Span startedSpan = this.tracer.createSpan("http:start"); final AtomicReference span = new AtomicReference<>(); - new TracePreZuulFilter(this.tracer, new RequestContextInjector()) { + new TracePreZuulFilter(this.tracer, new RequestContextInjector(), + new HttpTraceKeysInjector(this.tracer, new TraceKeys())) { @Override public Object run() { super.run(); @@ -102,15 +118,17 @@ public class TracePreZuulFilterTests { then(startedSpan).isNotEqualTo(span.get()); then(span.get().logs()).extracting("event").contains(Span.CLIENT_SEND); + then(span.get()).hasATag("http.method", "GET"); then(this.tracer.getCurrentSpan()).isEqualTo(startedSpan); } @Test public void shouldNotCloseSpanWhenNoExceptionIsThrown() throws Exception { - Span startedSpan = this.tracer.createSpan("http:start", NeverSampler.INSTANCE); + Span startedSpan = this.tracer.createSpan("http:start"); final AtomicReference span = new AtomicReference<>(); - new TracePreZuulFilter(this.tracer, new RequestContextInjector()) { + new TracePreZuulFilter(this.tracer, new RequestContextInjector(), + new HttpTraceKeysInjector(this.tracer, new TraceKeys())) { @Override public Object run() { span.set(TracePreZuulFilterTests.this.tracer.getCurrentSpan()); diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactoryTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactoryTest.java index 4f58d3bfe..26ebf11fb 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactoryTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactoryTest.java @@ -18,7 +18,9 @@ package org.springframework.cloud.sleuth.instrument.zuul; import com.netflix.client.http.HttpRequest; import com.netflix.niws.client.http.RestClient; +import com.netflix.zuul.context.RequestContext; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -31,6 +33,7 @@ import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanInjector; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.instrument.web.HttpTraceKeysInjector; +import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; import static org.assertj.core.api.BDDAssertions.then; import static org.mockito.BDDMockito.given; @@ -63,6 +66,12 @@ public class TraceRestClientRibbonCommandFactoryTest { given(this.tracer.isTracing()).willReturn(true); } + @After + public void cleanup() { + RequestContext.getCurrentContext().unset(); + TestSpanContextHolder.removeCurrentSpan(); + } + @Test public void should_wrap_ribbon_command_in_a_sleuth_representation() throws Exception { RestClientRibbonCommand restClientRibbonCommand = this.traceRestClientRibbonCommandFactory diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulIntegrationTests.java index a69589774..7de79b9a1 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceZuulIntegrationTests.java @@ -1,10 +1,11 @@ package org.springframework.cloud.sleuth.instrument.zuul; import java.io.IOException; +import java.lang.invoke.MethodHandles; +import java.util.HashMap; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; - +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -26,6 +27,7 @@ import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.assertions.ListOfSpans; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; +import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; import org.springframework.cloud.sleuth.util.ArrayListSpanAccumulator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -42,15 +44,21 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.DefaultResponseErrorHandler; import org.springframework.web.client.RestTemplate; +import com.netflix.loadbalancer.Server; +import com.netflix.loadbalancer.ServerList; +import com.netflix.zuul.context.RequestContext; + import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = SampleZuulProxyApplication.class) @WebAppConfiguration -@IntegrationTest({ "server.port: 0", "zuul.routes.simple: /simple/**", "hystrix.command.default.execution.isolation.strategy: SEMAPHORE"}) +@IntegrationTest({ "server.port: 0", "zuul.routes.simple: /simple/**" }) @DirtiesContext public class TraceZuulIntegrationTests { + private static final Log log = LogFactory.getLog(MethodHandles.lookup().lookupClass()); + @Value("${local.server.port}") private int port; @Autowired Tracer tracer; @@ -59,14 +67,17 @@ public class TraceZuulIntegrationTests { @Before public void cleanup() { + TestSpanContextHolder.removeCurrentSpan(); + RequestContext.getCurrentContext().unset(); this.spanAccumulator.getSpans().clear(); } @Test public void should_close_span_when_routing_to_service_via_discovery() { Span span = this.tracer.createSpan("new_span"); + log.info("Started span " + span); ResponseEntity result = this.restTemplate.exchange( - "http://localhost:" + this.port + "/simple/", HttpMethod.GET, + "http://localhost:" + this.port + "/simple/foo", HttpMethod.GET, new HttpEntity<>((Void) null), String.class); this.tracer.close(span); @@ -75,12 +86,17 @@ public class TraceZuulIntegrationTests { then(result.getBody()).isEqualTo("Hello world"); then(this.tracer.getCurrentSpan()).isNull(); then(new ListOfSpans(this.spanAccumulator.getSpans())) - .everyParentIdHasItsCorrespondingSpan(); + .everyParentIdHasItsCorrespondingSpan() + .clientSideSpanWithNameHasTags("http:/simple/foo", TestTag.tag() + .tag("http.method", "GET") + .tag("http.status_code", "200") + .tag("http.path", "/simple/foo")); } @Test public void should_close_span_when_routing_to_service_via_discovery_to_a_non_existent_url() { Span span = this.tracer.createSpan("new_span"); + log.info("Started span " + span); ResponseEntity result = this.restTemplate.exchange( "http://localhost:" + this.port + "/simple/nonExistentUrl", HttpMethod.GET, new HttpEntity<>((Void) null), String.class); @@ -90,7 +106,23 @@ public class TraceZuulIntegrationTests { then(result.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); then(this.tracer.getCurrentSpan()).isNull(); then(new ListOfSpans(this.spanAccumulator.getSpans())) - .everyParentIdHasItsCorrespondingSpan(); + .everyParentIdHasItsCorrespondingSpan() + .clientSideSpanWithNameHasTags("http:/simple/nonExistentUrl", TestTag.tag() + .tag("http.method", "GET") + .tag("http.status_code", "404") + .tag("http.path", "/simple/nonExistentUrl")); + } + + private static class TestTag extends HashMap { + + public static TestTag tag() { + return new TestTag(); + } + + public TestTag tag(String key, String value) { + put(key, value); + return this; + } } } @@ -103,7 +135,7 @@ public class TraceZuulIntegrationTests { class SampleZuulProxyApplication { - @RequestMapping("/") + @RequestMapping("/foo") public String home() { return "Hello world"; }