@Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Request.Builder requestBuilder = request.newBuilder(); Span span = handler.handleSend(injector, requestBuilder, request); parseRouteAddress(chain, span); Response response = null; Throwable error = null; try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) { return response = chain.proceed(requestBuilder.build()); } catch (IOException | RuntimeException | Error e) { error = e; throw e; } finally { handler.handleReceive(response, error, span); } }
@SuppressWarnings("unchecked") HttpClientHandler<ClientRequest, ClientResponse> handler() { if (this.handler == null) { this.handler = HttpClientHandler.create( this.beanFactory.getBean(HttpTracing.class), new TraceExchangeFilterFunction.HttpAdapter()); } return this.handler; }
/** * Like {@link #handleSend(TraceContext.Injector, Object)}, except for when the carrier of trace * data is not the same as the request. * * @see HttpClientParser#request(HttpAdapter, Object, SpanCustomizer) */ public <C> Span handleSend(TraceContext.Injector<C> injector, C carrier, Req request) { return handleSend(injector, carrier, request, nextSpan(request)); }
@Override public CloseableHttpResponse execute(HttpRoute route, HttpRequestWrapper request, HttpClientContext clientContext, HttpExecutionAware execAware) throws IOException, HttpException { Span span = handler.nextSpan(request); CloseableHttpResponse response = null; Throwable error = null; try (SpanInScope ws = tracer.withSpanInScope(span)) { return response = protocolExec.execute(route, request, clientContext, execAware); } catch (IOException | HttpException | RuntimeException | Error e) { error = e; throw e; } finally { handler.handleReceive(response, error, span); } } }
@Override public void onSuccess(ClientHttpResponse result) { handler.handleReceive(result, null, span); } }
/** * Starts the client span after assigning it a name and tags. This {@link * TraceContext.Injector#inject(TraceContext, Object) injects} the trace context onto the request * before returning. * * <p>Call this before sending the request on the wire. */ public Span handleSend(TraceContext.Injector<Req> injector, Req request) { return handleSend(injector, request, request); }
protected TraceScopeHolder<TraceScope> startTraceSpan(final Map<String, List<String>> requestHeaders, URI uri, String method) { final Request request = HttpAdapterFactory.request(requestHeaders, uri, method); final HttpClientAdapter<Request, ?> adapter = HttpClientAdapterFactory.create(request); final HttpClientHandler<Request, ?> handler = HttpClientHandler.create(brave, adapter); final Span span = handler.handleSend( brave .tracing() .propagation() .injector(inject(requestHeaders)), request); // In case of asynchronous client invocation, the span should be detached as JAX-RS // client request / response filters are going to be executed in different threads. SpanInScope scope = null; if (!isAsyncInvocation() && span != null) { scope = brave.tracing().tracer().withSpanInScope(span); } return new TraceScopeHolder<TraceScope>(new TraceScope(span, scope), scope == null /* detached */); }
protected void stopTraceSpan(final TraceScopeHolder<TraceScope> holder, final int responseStatus) { if (holder == null) { return; } final TraceScope scope = holder.getScope(); if (scope != null) { try { // If the client invocation was asynchronous , the trace span has been created // in another thread and should be re-attached to the current one. if (holder.isDetached()) { brave.tracing().tracer().joinSpan(scope.getSpan().context()); } final Response response = HttpAdapterFactory.response(responseStatus); final HttpClientAdapter<?, Response> adapter = HttpClientAdapterFactory.create(response); final HttpClientHandler<?, Response> handler = HttpClientHandler.create(brave, adapter); handler.handleReceive(response, null, scope.getSpan()); } finally { scope.close(); } } } }
@Override public void onFailure(Throwable ex) { handler.handleReceive(null, ex, span); }
/** * Like {@link #handleSend(TraceContext.Injector, Object)}, except explicitly controls the span * representing the request. * * @since 4.4 */ public Span handleSend(TraceContext.Injector<Req> injector, Req request, Span span) { return handleSend(injector, request, request, span); }
protected TraceScopeHolder<TraceScope> startTraceSpan(final Map<String, List<String>> requestHeaders, URI uri, String method) { final Request request = HttpAdapterFactory.request(requestHeaders, uri, method); final HttpClientAdapter<Request, ?> adapter = HttpClientAdapterFactory.create(request); final HttpClientHandler<Request, ?> handler = HttpClientHandler.create(brave, adapter); final Span span = handler.handleSend( brave .tracing() .propagation() .injector(inject(requestHeaders)), request); // In case of asynchronous client invocation, the span should be detached as JAX-RS // client request / response filters are going to be executed in different threads. SpanInScope scope = null; if (!isAsyncInvocation() && span != null) { scope = brave.tracing().tracer().withSpanInScope(span); } return new TraceScopeHolder<TraceScope>(new TraceScope(span, scope), scope == null /* detached */); }
protected void stopTraceSpan(final TraceScopeHolder<TraceScope> holder, final int responseStatus) { if (holder == null) { return; } final TraceScope scope = holder.getScope(); if (scope != null) { try { // If the client invocation was asynchronous , the trace span has been created // in another thread and should be re-attached to the current one. if (holder.isDetached()) { brave.tracing().tracer().joinSpan(scope.getSpan().context()); } final Response response = HttpAdapterFactory.response(responseStatus); final HttpClientAdapter<?, Response> adapter = HttpClientAdapterFactory.create(response); final HttpClientHandler<?, Response> handler = HttpClientHandler.create(brave, adapter); handler.handleReceive(response, null, scope.getSpan()); } finally { scope.close(); } } } }
@Override public CloseableHttpResponse execute(HttpRoute route, HttpRequestWrapper request, HttpClientContext clientContext, HttpExecutionAware execAware) throws IOException, HttpException { Span span = handler.nextSpan(request); CloseableHttpResponse response = null; Throwable error = null; try (SpanInScope ws = tracer.withSpanInScope(span)) { return response = protocolExec.execute(route, request, clientContext, execAware); } catch (IOException | HttpException | RuntimeException | Error e) { error = e; throw e; } finally { handler.handleReceive(response, error, span); } } }
TracingProtocolExec(HttpTracing httpTracing, ClientExecChain protocolExec) { this.tracer = httpTracing.tracing().tracer(); this.handler = HttpClientHandler.create(httpTracing, new HttpAdapter()); this.protocolExec = protocolExec; }
@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); } }
void handleReceive(Span span, Response response, Throwable error) { this.handler.handleReceive(response, error, span); }
Span handleSend(Map<String, Collection<String>> headers, Request request, Span clientSpan) { if (clientSpan != null) { return this.handler.handleSend(this.injector, headers, request, clientSpan); } return this.handler.handleSend(this.injector, headers, request); }
@Override public void process(HttpRequest request, HttpContext context) { HttpHost host = HttpClientContext.adapt(context).getTargetHost(); TraceContext parent = (TraceContext) context.getAttribute(TraceContext.class.getName()); Span span; try (Scope scope = currentTraceContext.maybeScope(parent)) { span = handler.nextSpan(request); } HttpRequestWrapper requestWrapper = HttpRequestWrapper.wrap(request, host); parseTargetAddress(requestWrapper, span); handler.handleSend(injector, request, requestWrapper, span); context.setAttribute(Span.class.getName(), span); context.setAttribute(Scope.class.getName(), currentTraceContext.newScope(span.context())); } }
@Inject TracingClientFilter(HttpTracing httpTracing) { if (httpTracing == null) throw new NullPointerException("HttpTracing == null"); tracer = httpTracing.tracing().tracer(); handler = HttpClientHandler.create(httpTracing, new HttpAdapter()); injector = httpTracing.tracing().propagation().injector(SETTER); }
@Override public ListenableFuture<ClientHttpResponse> intercept(HttpRequest request, byte[] body, AsyncClientHttpRequestExecution execution) throws IOException { Span span = handler.handleSend(injector, request.getHeaders(), request); try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) { ListenableFuture<ClientHttpResponse> result = execution.executeAsync(request, body); result.addCallback(new TraceListenableFutureCallback(span, handler)); return result; } catch (IOException | RuntimeException | Error e) { handler.handleReceive(null, e, span); throw e; } }