/** Returns a random ID suitable for span and trace IDs. */ public static String randomId() { return longToPaddedHex(ThreadLocalRandom.current().nextLong()); }
@Override protected <T> Callable<T> wrapTask(Callable<T> callable) { return wrap(callable); } };
@Override protected <T> Callable<T> wrapTask(Callable<T> callable) { return wrapWithNewTrace(callable); } };
/** * Like {@link #wrapWithNewTrace(Callable)}, but for Runnables. */ public static Runnable wrapWithNewTrace(Runnable delegate) { return () -> { // clear the existing trace and keep it around for restoration when we're done Trace originalTrace = Tracer.getAndClearTrace(); try { Tracer.initTrace(Optional.empty(), Tracers.randomId()); delegate.run(); } finally { // restore the trace Tracer.setTrace(originalTrace); } }; }
/** * Like {@link #wrapWithNewTrace(Callable)}, but for Runnables. */ public static Runnable wrapWithNewTrace(Runnable delegate) { return () -> { // clear the existing trace and keep it around for restoration when we're done Trace originalTrace = Tracer.getAndClearTrace(); try { Tracer.initTrace(Optional.empty(), Tracers.randomId()); delegate.run(); } finally { // restore the trace Tracer.setTrace(originalTrace); } }; }
/** * Wraps the given {@link Callable} such that it creates a fresh {@link Trace tracing state} for its execution. * That is, the trace during its {@link Callable#call() execution} is entirely separate from the trace at * construction or any trace already set on the thread used to execute the callable. Each execution of the callable * will have a fresh trace. */ public static <V> Callable<V> wrapWithNewTrace(Callable<V> delegate) { return () -> { // clear the existing trace and keep it around for restoration when we're done Trace originalTrace = Tracer.getAndClearTrace(); try { Tracer.initTrace(Optional.empty(), Tracers.randomId()); return delegate.call(); } finally { // restore the trace Tracer.setTrace(originalTrace); } }; }
@Override protected <T> Callable<T> wrapTask(Callable<T> callable) { return wrap(callable); } };
@Override protected <T> Callable<T> wrapTask(Callable<T> callable) { return wrapWithNewTrace(callable); } };
/** Returns a random ID suitable for span and trace IDs. */ public static String randomId() { return longToPaddedHex(ThreadLocalRandom.current().nextLong()); }
/** * Wraps the given {@link Callable} such that it creates a fresh {@link Trace tracing state} for its execution. * That is, the trace during its {@link Callable#call() execution} is entirely separate from the trace at * construction or any trace already set on the thread used to execute the callable. Each execution of the callable * will have a fresh trace. */ public static <V> Callable<V> wrapWithNewTrace(Callable<V> delegate) { return () -> { // clear the existing trace and keep it around for restoration when we're done Trace originalTrace = Tracer.getAndClearTrace(); try { Tracer.initTrace(Optional.empty(), Tracers.randomId()); return delegate.call(); } finally { // restore the trace Tracer.setTrace(originalTrace); } }; }
@Override protected <T> Callable<T> wrapTask(Callable<T> callable) { return wrap(callable); } };
@Override protected <T> Callable<T> wrapTask(Callable<T> callable) { return wrapWithNewTrace(callable); } };
/** * Opens a new span for this thread's call trace, labeled with the provided operation and parent span. Only allowed * when the current trace is empty. */ public static OpenSpan startSpan(String operation, String parentSpanId, SpanType type) { Preconditions.checkState(currentTrace.get().isEmpty(), "Cannot start a span with explicit parent if the current thread's trace is non-empty"); Preconditions.checkArgument(parentSpanId != null && !parentSpanId.isEmpty(), "parentTraceId must be non-empty: %s", parentSpanId); OpenSpan span = OpenSpan.builder() .spanId(Tracers.randomId()) .operation(operation) .parentSpanId(parentSpanId) .type(type) .build(); currentTrace.get().push(span); return span; }
@Override protected <T> Callable<T> wrapTask(Callable<T> callable) { return wrap(callable); } };
@Override protected <T> Callable<T> wrapTask(Callable<T> callable) { return wrapWithNewTrace(callable); } };
/** * Opens a new span for this thread's call trace, labeled with the provided operation and parent span. Only allowed * when the current trace is empty. */ public static OpenSpan startSpan(String operation, String parentSpanId, SpanType type) { Preconditions.checkState(currentTrace.get().isEmpty(), "Cannot start a span with explicit parent if the current thread's trace is non-empty"); Preconditions.checkArgument(parentSpanId != null && !parentSpanId.isEmpty(), "parentTraceId must be non-empty: %s", parentSpanId); OpenSpan span = OpenSpan.builder() .spanId(Tracers.randomId()) .operation(operation) .parentSpanId(parentSpanId) .type(type) .build(); currentTrace.get().push(span); return span; }
private static OpenSpan startSpanInternal(String operation, SpanType type) { OpenSpan.Builder spanBuilder = OpenSpan.builder() .operation(operation) .spanId(Tracers.randomId()) .type(type); Optional<OpenSpan> prevState = currentTrace.get().top(); if (prevState.isPresent()) { spanBuilder.parentSpanId(prevState.get().getSpanId()); } OpenSpan span = spanBuilder.build(); currentTrace.get().push(span); return span; }
private static OpenSpan startSpanInternal(String operation, SpanType type) { OpenSpan.Builder spanBuilder = OpenSpan.builder() .operation(operation) .spanId(Tracers.randomId()) .type(type); Optional<OpenSpan> prevState = currentTrace.get().top(); if (prevState.isPresent()) { spanBuilder.parentSpanId(prevState.get().getSpanId()); } OpenSpan span = spanBuilder.build(); currentTrace.get().push(span); return span; }
@Override public void filter(ContainerRequestContext requestContext) throws IOException { String path = Optional.ofNullable(uriInfo) .map(ExtendedUriInfo::getMatchedModelResource) .map(Resource::getPath) .orElse("(unknown)"); String operation = requestContext.getMethod() + " " + path; // The following strings are all nullable String traceId = requestContext.getHeaderString(TraceHttpHeaders.TRACE_ID); String spanId = requestContext.getHeaderString(TraceHttpHeaders.SPAN_ID); // Set up thread-local span that inherits state from HTTP headers if (Strings.isNullOrEmpty(traceId)) { // HTTP request did not indicate a trace; initialize trace state and create a span. Tracer.initTrace(hasSampledHeader(requestContext), Tracers.randomId()); Tracer.startSpan(operation, SpanType.SERVER_INCOMING); } else { Tracer.initTrace(hasSampledHeader(requestContext), traceId); if (spanId == null) { Tracer.startSpan(operation, SpanType.SERVER_INCOMING); } else { // caller's span is this span's parent. Tracer.startSpan(operation, spanId, SpanType.SERVER_INCOMING); } } // Give asynchronous downstream handlers access to the trace id requestContext.setProperty("com.palantir.conjure.java.traceId", Tracer.getTraceId()); }