diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java index 1f1687716..2e6d240d1 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilter.java @@ -22,6 +22,7 @@ import brave.http.HttpClientHandler; import brave.http.HttpTracing; import brave.propagation.Propagation; import brave.propagation.TraceContext; +import brave.propagation.TraceContextOrSamplingFlags; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -47,10 +48,12 @@ final class TraceRequestHttpHeadersFilter extends AbstractHttpHeadersFilter { @Override public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) { if (log.isDebugEnabled()) { - log.debug("Will instrument the HTTP request headers"); + log.debug("Will instrument the HTTP request headers [" + + exchange.getRequest().getHeaders() + "]"); } TraceCarrier carrier = new TraceCarrier(exchange.getRequest(), input); - Span span = this.handler.handleSend(this.injector, carrier); + Span currentSpan = currentSpan(carrier); + Span span = injectedSpan(carrier, currentSpan); if (log.isDebugEnabled()) { log.debug( "Client span " + span + " created for the request. New headers are " @@ -63,6 +66,22 @@ final class TraceRequestHttpHeadersFilter extends AbstractHttpHeadersFilter { return headersWithInput; } + private Span currentSpan(TraceCarrier carrier) { + Span currentSpan = this.tracer.currentSpan(); + if (currentSpan != null) { + return currentSpan; + } + TraceContextOrSamplingFlags contextOrFlags = this.extractor.extract(carrier); + return this.tracer.nextSpan(contextOrFlags); + } + + private Span injectedSpan(TraceCarrier carrier, Span currentSpan) { + if (currentSpan == null) { + return this.handler.handleSend(this.injector, carrier); + } + return this.handler.handleSend(this.injector, carrier, currentSpan); + } + @Override public boolean supports(Type type) { return type.equals(Type.REQUEST); @@ -136,18 +155,33 @@ abstract class AbstractHttpHeadersFilter implements HttpHeadersFilter { } }; + private static final Propagation.Getter GETTER = new Propagation.Getter() { + @Override + public String get(TraceCarrier carrier, String key) { + return carrier.filteredHeaders.getFirst(key); + } + + @Override + public String toString() { + return "TraceCarrier::httpHeaders::getFirst"; + } + }; + final Tracer tracer; final HttpClientHandler handler; final TraceContext.Injector injector; + final TraceContext.Extractor extractor; + final HttpTracing httpTracing; AbstractHttpHeadersFilter(HttpTracing httpTracing) { this.tracer = httpTracing.tracing().tracer(); this.handler = HttpClientHandler.create(httpTracing, new ServerHttpAdapter()); this.injector = httpTracing.tracing().propagation().injector(SETTER); + this.extractor = httpTracing.tracing().propagation().extractor(GETTER); this.httpTracing = httpTracing; } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java index 9dfb6aefd..ae2e1ce73 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java @@ -57,8 +57,10 @@ public class TraceRequestHttpHeadersFilterTests { HttpHeaders filteredHeaders = filter.filter(requestHeaders(httpHeaders), exchange); + // we want to continue the trace BDDAssertions.then(filteredHeaders.get("X-B3-TraceId")) - .isNotEqualTo(httpHeaders.get("X-B3-TraceId")); + .isEqualTo(httpHeaders.get("X-B3-TraceId")); + // but we want to have a new span id BDDAssertions.then(filteredHeaders.get("X-B3-SpanId")) .isNotEqualTo(httpHeaders.get("X-B3-SpanId")); BDDAssertions.then(filteredHeaders.get("X-Hello"))