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();
}
});
}