Skip to content

Commit

Permalink
Add methods to create wrapped executor with new span (#71)
Browse files Browse the repository at this point in the history
Fixes #63

~This PR preserves the existing executor wrapping methods and their behavior. So users must explicitly opt-in to the new span-creating behavior.~

This is no longer true. The existing executor methods will now create a new span for tasks they run.
  • Loading branch information
pkoenig10 authored and bulldozer-bot[bot] committed Feb 21, 2019
1 parent 3c30134 commit b75b467
Show file tree
Hide file tree
Showing 3 changed files with 285 additions and 139 deletions.
12 changes: 12 additions & 0 deletions tracing/src/main/java/com/palantir/tracing/DeferredTracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,19 @@
*/
public final class DeferredTracer {
private final Optional<Trace> trace;
private final Optional<String> operation;

public DeferredTracer() {
this(Optional.empty());
}

public DeferredTracer(String operation) {
this(Optional.of(operation));
}

DeferredTracer(Optional<String> operation) {
this.trace = Tracer.copyTrace();
this.operation = operation;
}

/**
Expand All @@ -54,9 +64,11 @@ public <T, E extends Throwable> T withTrace(Tracers.ThrowingCallable<T, E> inner
}
Optional<Trace> originalTrace = Tracer.copyTrace();
Tracer.setTrace(trace.get());
operation.ifPresent(Tracer::startSpan);
try {
return inner.call();
} finally {
operation.ifPresent(op -> Tracer.fastCompleteSpan());
if (originalTrace.isPresent()) {
Tracer.setTrace(originalTrace.get());
} else {
Expand Down
101 changes: 78 additions & 23 deletions tracing/src/main/java/com/palantir/tracing/Tracers.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
public final class Tracers {
/** The key under which trace ids are inserted into SLF4J {@link org.slf4j.MDC MDCs}. */
public static final String TRACE_ID_KEY = "traceId";
private static final String ROOT_SPAN_OPERATION = "root";
private static final String DEFAULT_ROOT_SPAN_OPERATION = "root";
private static final String DEFAULT_EXECUTOR_SPAN_OPERATION = "executor";
private static final char[] HEX_DIGITS =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

Expand Down Expand Up @@ -68,10 +69,18 @@ static String longToPaddedHex(long number) {
* #wrap wrapped} in order to be trace-aware.
*/
public static ExecutorService wrap(ExecutorService executorService) {
return wrap(DEFAULT_EXECUTOR_SPAN_OPERATION, executorService);
}

/**
* Like {@link #wrap(ExecutorService)}, but using the given {@link String operation} is used to create a span for
* submitted tasks.
*/
public static ExecutorService wrap(String operation, ExecutorService executorService) {
return new WrappingExecutorService(executorService) {
@Override
protected <T> Callable<T> wrapTask(Callable<T> callable) {
return wrap(callable);
return wrap(operation, callable);
}
};
}
Expand All @@ -83,10 +92,19 @@ protected <T> Callable<T> wrapTask(Callable<T> callable) {
* trace will be generated for each execution, effectively bypassing the intent of this method.
*/
public static ScheduledExecutorService wrap(ScheduledExecutorService executorService) {
return wrap(DEFAULT_EXECUTOR_SPAN_OPERATION, executorService);
}

/**
* Like {@link #wrap(ScheduledExecutorService)}, but using the given {@link String operation} is used to create a
* span for submitted tasks.
*/
public static ScheduledExecutorService wrap(String operation,
ScheduledExecutorService executorService) {
return new WrappingScheduledExecutorService(executorService) {
@Override
protected <T> Callable<T> wrapTask(Callable<T> callable) {
return wrap(callable);
return wrap(operation, callable);
}
};
}
Expand All @@ -96,27 +114,49 @@ protected <T> Callable<T> wrapTask(Callable<T> callable) {
* it's construction during its {@link Callable#call() execution}.
*/
public static <V> Callable<V> wrap(Callable<V> delegate) {
return new TracingAwareCallable<>(delegate);
return new TracingAwareCallable<>(Optional.empty(), delegate);
}

/**
* Like {@link #wrap(Callable)}, but using the given {@link String operation} is used to create a span for the
* execution.
*/
public static <V> Callable<V> wrap(String operation, Callable<V> delegate) {
return new TracingAwareCallable<>(Optional.of(operation), delegate);
}

/** Like {@link #wrap(Callable)}, but for Runnables. */
/**
* Wraps the given {@link Runnable} such that it uses the thread-local {@link Trace tracing state} at the time of
* it's construction during its {@link Runnable#run()} execution}.
*/
public static Runnable wrap(Runnable delegate) {
return new TracingAwareRunnable(delegate);
return new TracingAwareRunnable(Optional.empty(), delegate);
}

/**
* Like {@link #wrapWithNewTrace(String, ExecutorService)}, but with a default initial span operation.
* Like {@link #wrap(Runnable)}, but using the given {@link String operation} is used to create a span for the
* execution.
*/
public static Runnable wrap(String operation, Runnable delegate) {
return new TracingAwareRunnable(Optional.of(operation), delegate);
}

/**
* Deprecated.
*
* @deprecated Use {@link #wrapWithNewTrace(String, ExecutorService)}
*/
@Deprecated
public static ExecutorService wrapWithNewTrace(ExecutorService executorService) {
return wrapWithNewTrace(ROOT_SPAN_OPERATION, executorService);
return wrapWithNewTrace(DEFAULT_ROOT_SPAN_OPERATION, executorService);
}

/**
* Wraps the provided executor service to make submitted tasks traceable with a fresh {@link Trace trace}
* for each execution, see {@link #wrapWithNewTrace(String, ExecutorService)}. This method should not be used to
* wrap a ScheduledExecutorService that has already been {@link #wrap(ExecutorService) wrapped}. If this is
* done, a new trace will be generated for each execution, effectively bypassing the intent of the previous
* wrapping. The given {@link String operation} is used to create the initial span.
* wrapping. The given {@link String operation} is used to create the initial span.
*/
public static ExecutorService wrapWithNewTrace(String operation, ExecutorService executorService) {
return new WrappingExecutorService(executorService) {
Expand All @@ -128,18 +168,21 @@ protected <T> Callable<T> wrapTask(Callable<T> callable) {
}

/**
* Like {@link #wrapWithNewTrace(String, ScheduledExecutorService)}, but with a default initial span operation.
* Deprecated.
*
* @deprecated Use {@link #wrapWithNewTrace(String, ScheduledExecutorService)}
*/
@Deprecated
public static ScheduledExecutorService wrapWithNewTrace(ScheduledExecutorService executorService) {
return wrapWithNewTrace(ROOT_SPAN_OPERATION, executorService);
return wrapWithNewTrace(DEFAULT_ROOT_SPAN_OPERATION, executorService);
}

/**
* Wraps the provided scheduled executor service to make submitted tasks traceable with a fresh {@link Trace trace}
* for each execution, see {@link #wrapWithNewTrace(String, ScheduledExecutorService)}. This method should not be
* used to wrap a ScheduledExecutorService that has already been {@link #wrap(ScheduledExecutorService) wrapped}.
* If this is done, a new trace will be generated for each execution, effectively bypassing the intent of the
* previous wrapping. The given {@link String operation} is used to create the initial span.
* previous wrapping. The given {@link String operation} is used to create the initial span.
*/
public static ScheduledExecutorService wrapWithNewTrace(String operation,
ScheduledExecutorService executorService) {
Expand All @@ -152,10 +195,13 @@ protected <T> Callable<T> wrapTask(Callable<T> callable) {
}

/**
* Like {@link #wrapWithNewTrace(String, Callable)}, but with a default initial span operation.
* Deprecated.
*
* @deprecated Use {@link #wrapWithNewTrace(String, Callable)}
*/
@Deprecated
public static <V> Callable<V> wrapWithNewTrace(Callable<V> delegate) {
return wrapWithNewTrace(ROOT_SPAN_OPERATION, delegate);
return wrapWithNewTrace(DEFAULT_ROOT_SPAN_OPERATION, delegate);
}

/**
Expand All @@ -181,14 +227,20 @@ public static <V> Callable<V> wrapWithNewTrace(String operation, Callable<V> del
}

/**
* Like {@link #wrapWithAlternateTraceId(String, Runnable)}, but with a default initial span operation.
* Deprecated.
*
* @deprecated Use {@link #wrapWithNewTrace(String, Runnable)}
*/
@Deprecated
public static Runnable wrapWithNewTrace(Runnable delegate) {
return wrapWithNewTrace(ROOT_SPAN_OPERATION, delegate);
return wrapWithNewTrace(DEFAULT_ROOT_SPAN_OPERATION, delegate);
}

/**
* Like {@link #wrapWithNewTrace(String, Callable)}, but for Runnables.
* Wraps the given {@link Runnable} such that it creates a fresh {@link Trace tracing state} for its execution.
* That is, the trace during its {@link Runnable#run() execution} is entirely separate from the trace at
* construction or any trace already set on the thread used to execute the runnable. Each execution of the runnable
* will have a fresh trace. The given {@link String operation} is used to create the initial span.
*/
public static Runnable wrapWithNewTrace(String operation, Runnable delegate) {
return () -> {
Expand All @@ -207,10 +259,13 @@ public static Runnable wrapWithNewTrace(String operation, Runnable delegate) {
}

/**
* Like {@link #wrapWithAlternateTraceId(String, String, Runnable)}, but with a default initial span operation.
* Deprecated.
*
* @deprecated Use {@link #wrapWithAlternateTraceId(String, String, Runnable)}
*/
@Deprecated
public static Runnable wrapWithAlternateTraceId(String traceId, Runnable delegate) {
return wrapWithAlternateTraceId(traceId, ROOT_SPAN_OPERATION, delegate);
return wrapWithAlternateTraceId(traceId, DEFAULT_ROOT_SPAN_OPERATION, delegate);
}

/**
Expand Down Expand Up @@ -264,9 +319,9 @@ private static class TracingAwareCallable<V> implements Callable<V> {
private final Callable<V> delegate;
private final DeferredTracer deferredTracer;

TracingAwareCallable(Callable<V> delegate) {
TracingAwareCallable(Optional<String> operation, Callable<V> delegate) {
this.delegate = delegate;
this.deferredTracer = new DeferredTracer();
this.deferredTracer = new DeferredTracer(operation);
}

@Override
Expand All @@ -283,9 +338,9 @@ private static class TracingAwareRunnable implements Runnable {
private final Runnable delegate;
private DeferredTracer deferredTracer;

TracingAwareRunnable(Runnable delegate) {
TracingAwareRunnable(Optional<String> operation, Runnable delegate) {
this.delegate = delegate;
this.deferredTracer = new DeferredTracer();
this.deferredTracer = new DeferredTracer(operation);
}

@Override
Expand Down
Loading

0 comments on commit b75b467

Please sign in to comment.