Improved span passing for NettyClient.
without this change the child span has a wrong parent span id
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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<>();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user