Improved span passing for NettyClient.

without this change the child span has a wrong parent span id
This commit is contained in:
Marcin Grzejszczak
2018-11-02 13:31:37 +01:00
parent aa2a0209de
commit 9b2def2be1
8 changed files with 27 additions and 35 deletions

View File

@@ -20,7 +20,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Utility class to retrieve data from Servlet HTTP request and handle.
* Utility class to retrieve data from Servlet HTTP request and response.
*
* @author Marcin Grzejszczak
* @since 1.0.0

View File

@@ -72,7 +72,7 @@ class SleuthHttpServerParser extends HttpServerParser {
return;
}
if (httpStatus == HttpServletResponse.SC_OK && error != null) {
// Filter chain threw exception but the handle status may not have been set
// Filter chain threw exception but the response status may not have been set
// yet, so we have to guess.
customizer.tag(STATUS_CODE_KEY,
String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));

View File

@@ -19,6 +19,7 @@ package org.springframework.cloud.sleuth.instrument.web.client;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
@@ -349,8 +350,8 @@ class HttpClientBeanPostProcessor implements BeanPostProcessor {
@Override
public Mono<? extends Connection> apply(Mono<? extends Connection> mono,
Bootstrap bootstrap) {
return mono.subscriberContext(
context -> context.put(Span.class, tracer().nextSpan()));
return mono.subscriberContext(context -> context.put(AtomicReference.class,
new AtomicReference<>(tracer().currentSpan())));
}
private Tracer tracer() {
@@ -378,17 +379,6 @@ class HttpClientBeanPostProcessor implements BeanPostProcessor {
return "HttpHeaders::add";
}
};
static final Propagation.Getter<HttpHeaders, String> GETTER = new Propagation.Getter<HttpHeaders, String>() {
@Override
public String get(HttpHeaders carrier, String key) {
return carrier.get(key);
}
@Override
public String toString() {
return "HttpHeaders::get";
}
};
private static final Logger log = LoggerFactory
.getLogger(TracingDoOnRequest.class);
@@ -414,12 +404,11 @@ class HttpClientBeanPostProcessor implements BeanPostProcessor {
@Override
public void accept(HttpClientRequest req, Connection connection) {
Span span = req.currentContext().getOrDefault(Span.class,
this.tracer.nextSpan());
if (log.isDebugEnabled()) {
log.debug("Wrapping do on request");
}
this.handler.handleSend(this.injector, req.requestHeaders(), req, span);
AtomicReference reference = req.currentContext()
.getOrDefault(AtomicReference.class, new AtomicReference());
Span span = this.handler.handleSend(this.injector, req.requestHeaders(), req,
(Span) reference.get());
reference.set(span);
}
}
@@ -491,12 +480,13 @@ class HttpClientBeanPostProcessor implements BeanPostProcessor {
protected void handle(HttpClientResponse httpClientResponse,
Throwable throwable) {
Span span = httpClientResponse.currentContext().getOrDefault(Span.class,
null);
if (span == null) {
AtomicReference reference = httpClientResponse.currentContext()
.getOrDefault(AtomicReference.class, null);
if (reference == null || reference.get() == null) {
return;
}
this.handler.handleReceive(httpClientResponse, throwable, span);
this.handler.handleReceive(httpClientResponse, throwable,
(Span) reference.get());
}
}

View File

@@ -155,7 +155,7 @@ class TraceExchangeFilterFunction implements ExchangeFilterFunction {
|| clientResponse.statusCode() == null) {
if (log.isDebugEnabled()) {
log.debug(
"No handle was returned. Will close the span ["
"No response was returned. Will close the span ["
+ clientSpan + "]");
}
handleReceive(clientSpan, ws, clientResponse,
@@ -172,7 +172,7 @@ class TraceExchangeFilterFunction implements ExchangeFilterFunction {
+ clientSpan + "]");
}
throwable = new RestClientException(
"Status code of the handle is ["
"Status code of the response is ["
+ clientResponse.statusCode().value()
+ "] and the reason is ["
+ clientResponse.statusCode()

View File

@@ -281,7 +281,7 @@ class JmsTestTracingConfiguration {
/**
* When testing servers or asynchronous clients, spans are reported on a worker
* thread. In order to read them on the main thread, we use a concurrent queue. As
* some implementations report after a handle is sent, we use a blocking queue to
* some implementations report after a response is sent, we use a blocking queue to
* prevent race conditions in tests.
*/
BlockingQueue<Span> spans = new LinkedBlockingQueue<>();

View File

@@ -80,7 +80,7 @@ public class TraceCustomFilterResponseInjectorTests {
Map.class);
then(responseEntity.getHeaders()).containsKeys(TRACE_ID_NAME, SPAN_ID_NAME)
.as("Trace headers must be present in handle headers");
.as("Trace headers must be present in response headers");
}
@Configuration

View File

@@ -293,11 +293,13 @@ public class WebClientTests {
then(response).isNotNull();
}
then(this.tracer.currentSpan()).isNull();
System.out.println("Collected span " + this.reporter.getSpans());
then(this.reporter.getSpans()).isNotEmpty().extracting("traceId", String.class)
.containsOnly(span.context().traceIdString());
then(this.reporter.getSpans()).extracting("kind.name").contains("CLIENT");
Awaitility.await().untilAsserted(() -> {
then(this.tracer.currentSpan()).isNull();
System.out.println("Collected span " + this.reporter.getSpans());
then(this.reporter.getSpans()).isNotEmpty().extracting("traceId", String.class)
.containsOnly(span.context().traceIdString());
then(this.reporter.getSpans()).extracting("kind.name").contains("CLIENT");
});
}
@Test

View File

@@ -68,7 +68,7 @@ public class RequestSendingRunnable implements Runnable {
ResponseEntity<String> responseEntity = this.restTemplate
.exchange(requestWithTraceId(), String.class);
then(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
log.info(String.format("Received the following handle [%s]", responseEntity));
log.info(String.format("Received the following response [%s]", responseEntity));
}
private RequestEntity<Void> requestWithTraceId() {