public static void startOutboundSpan()

in tchannel-core/src/main/java/com/uber/tchannel/tracing/Tracing.java [61:129]


    public static <V extends Response> void startOutboundSpan(
            @NotNull OutRequest<V> outRequest,
            @Nullable Tracer tracer,
            @Nullable TracingContext tracingContext
    ) throws RuntimeException {
        if (tracer == null || tracingContext == null) {
            return;
        }

        Request request = outRequest.getRequest();

        Tracer.SpanBuilder builder = tracer.buildSpan(request.getEndpoint());
        if (tracingContext.hasSpan()) {
            builder.asChildOf(tracingContext.currentSpan().context());
        }
        // TODO add tags for peer host:port
        builder
            .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
            .withTag(Tags.PEER_SERVICE.getKey(), request.getService())
            .withTag("as", request.getArgScheme().name());

        final Span span = builder.startManual();

        if (tracingContext instanceof RequestSpanInterceptor) {
            try {
                ((RequestSpanInterceptor) tracingContext).interceptOutbound(request, span);
            } catch (RuntimeException e) {
                span.log(ImmutableMap.of("exception", e));
                span.finish();
                throw e;
            }
        }

        // if Jaeger span context, set Trace fields
        if (span.context() instanceof JaegerSpanContext) {
            JaegerSpanContext jaegerSpanContext = (JaegerSpanContext) span.context();
            Trace trace = new Trace(
                jaegerSpanContext.getSpanId(),
                jaegerSpanContext.getParentId(),
                // tchannel only support 64bit IDs, https://github.com/uber/tchannel/blob/master/docs/protocol.md#tracing
                jaegerSpanContext.getTraceIdLow(),
                jaegerSpanContext.getFlags());
            request.setTrace(trace);
        }

        // if request has headers, inject tracing context
        if (request instanceof TraceableRequest) {
            TraceableRequest traceableRequest = (TraceableRequest) request;
            //Format.Builtin.TEXT_MAP
            Map<String, String> headers = traceableRequest.getHeaders();
            PrefixedHeadersCarrier carrier = new PrefixedHeadersCarrier(headers);
            try {
                tracer.inject(span.context(), Format.Builtin.TEXT_MAP, carrier);
                traceableRequest.setHeaders(headers);
            } catch (Exception e) {
                logger.error("Failed to inject span context into headers", e);
            }
        }
        outRequest.getFuture().addCallback(new TFutureCallback<V>() {
            @Override
            public void onResponse(Response response) {
                if (response.isError()) {
                    Tags.ERROR.set(span, true);
                    span.log(response.getError().getMessage());
                }
                span.finish();
            }
        });
    }