package brave.spring.web;
import brave.Span;
import brave.Tracer;
import brave.Tracing;
import brave.http.HttpClientHandler;
import brave.http.HttpTracing;
import brave.propagation.TraceContext;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
public final class TracingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
public static ClientHttpRequestInterceptor create(Tracing tracing) {
return create(HttpTracing.create(tracing));
}
public static ClientHttpRequestInterceptor create(HttpTracing httpTracing) {
return new TracingClientHttpRequestInterceptor(httpTracing);
}
final Tracer tracer;
final HttpClientHandler<HttpRequest, ClientHttpResponse> handler;
final TraceContext.Injector<HttpHeaders> injector;
@Autowired TracingClientHttpRequestInterceptor(HttpTracing httpTracing) {
tracer = httpTracing.tracing().tracer();
handler = HttpClientHandler.create(httpTracing, new HttpAdapter());
injector = httpTracing.tracing().propagation().injector(HttpHeaders::set);
}
@Override public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
Span span = handler.handleSend(injector, request.getHeaders(), request);
ClientHttpResponse response = null;
Throwable error = null;
try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) {
return response = execution.execute(request, body);
} catch (IOException | RuntimeException | Error e) {
error = e;
throw e;
} finally {
handler.handleReceive(response, error, span);
}
}
static final class HttpAdapter
extends brave.http.HttpClientAdapter<HttpRequest, ClientHttpResponse> {
@Override public String method(HttpRequest request) {
return request.getMethod().name();
}
@Override public String url(HttpRequest request) {
return request.getURI().toString();
}
@Override public String requestHeader(HttpRequest request, String name) {
Object result = request.getHeaders().getFirst(name);
return result != null ? result.toString() : null;
}
@Override public Integer statusCode(ClientHttpResponse response) {
try {
return response.getRawStatusCode();
} catch (IOException e) {
return null;
}
}
}
}