diff --git a/opentracing-api/src/main/java/io/opentracing/ActiveSpan.java b/opentracing-api/src/main/java/io/opentracing/ActiveSpan.java new file mode 100644 index 00000000..bbf4e944 --- /dev/null +++ b/opentracing-api/src/main/java/io/opentracing/ActiveSpan.java @@ -0,0 +1,71 @@ +package io.opentracing; + +import java.io.Closeable; + +/** + * In any execution context (or any thread, etc), there is at most one "active" {@link Span} primarily responsible for + * the work accomplished by the surrounding application code. That active Span may be accessed via the + * {@link ActiveSpanSource#active()} method. If the application needs to defer work that should be part of the same Span, the + * Source provides a {@link ActiveSpan#defer} method that returns a {@link Continuation}; this continuation may be used + * to re-activate and continue the {@link Span} in that other asynchronous executor and/or thread. + * + *

+ * {@link ActiveSpan}s are created via {@link Tracer.SpanBuilder#startAndActivate()} or {@link ActiveSpanSource#adopt}. They can + * be {@link ActiveSpan#defer()}ed as {@link ActiveSpan.Continuation}s, then re-{@link Continuation#activate()}d later. + * + * @see ActiveSpanSource + */ +public interface ActiveSpan extends Closeable, Span { + /** + * Mark the end of the active period for the {@link Span} pinned by this {@link ActiveSpan}. When the last + * {@link ActiveSpan} is deactivated for a given {@link Span}, it is automatically {@link Span#finish()}ed. + *

+ *

+ * NOTE: It is an error to call deactivate() more than once on a single {@link ActiveSpan}. + * + * @see Closeable#close() {@link ActiveSpan}s are auto-closeable and may be used in try-with-resources blocks + */ + void deactivate(); + + /** + * "Fork" a new {@link Continuation} associated with this {@link ActiveSpan} and {@link Span}, as well as any + * 3rd-party execution context of interest. + *

+ *

+ * The associated {@link Span} will not {@link Span#finish()} while a {@link Continuation} is outstanding; in + * this way, it provides a reference/pin just like an active @{Handle} does. + * + * @return a new {@link Continuation} to {@link Continuation#activate()} at the appropriate time. + */ + Continuation defer(); + + /** + * A {@link Continuation} can be used *once* to activate a Span along with any non-OpenTracing execution context + * (e.g., MDC), then deactivate when processing activity moves on to another Span. (In practice, this active period + * typically extends for the length of a deferred async closure invocation.) + * + *

+ * Most users do not directly interact with {@link Continuation}, {@link Continuation#activate()} or + * {@link ActiveSpan#deactivate()}, but rather use {@link ActiveSpanSource}-aware Runnables/Callables/Executors. + * Those higher-level primitives need not be defined within the OpenTracing core API, and so they are not. + * + *

+ * NOTE: {@link Continuation} extends {@link Closeable} rather than AutoCloseable in order to keep support + * for JDK1.6. + * + * @see ActiveSpanSource#adopt(Span) + */ + interface Continuation { + /** + * Make the Span (and other execution context) encapsulated by this Continuation active and return it. + * + *

+ * NOTE: It is an error to call activate() more than once on a single Continuation instance. + * + * @see ActiveSpanSource#adopt(Span) + * @return a handle to the newly-activated Span + */ + ActiveSpan activate(); + } + +} diff --git a/opentracing-api/src/main/java/io/opentracing/ActiveSpanSource.java b/opentracing-api/src/main/java/io/opentracing/ActiveSpanSource.java index b6ae8b0f..84d5bcb5 100644 --- a/opentracing-api/src/main/java/io/opentracing/ActiveSpanSource.java +++ b/opentracing-api/src/main/java/io/opentracing/ActiveSpanSource.java @@ -1,108 +1,26 @@ package io.opentracing; -import java.io.Closeable; - /** * {@link ActiveSpanSource} allows an existing (possibly thread-local-aware) execution context provider to act as a * source for an actively-scheduled OpenTracing Span. * - *

- * In any execution context (or any thread, etc), there is at most one "active" Span primarily responsible for the - * work accomplished by the surrounding application code. That active Span may be accessed -- via an - * {@link ActiveSpanSource.Handle} -- with the {@link ActiveSpanSource#active()} method. If the application needs - * to defer work that should be part of the same Span, the ActiveSpanSource provides a - * {@link Handle#defer} method that returns a {@link Continuation}; this continuation may be used to re-activate and - * the Span in that other asynchronous executor and/or thread. - * - *

- * There are two important use cases for {@link ActiveSpanSource} and {@link ActiveSpanSource.Continuation}: - *

+ * @see ActiveSpan */ public interface ActiveSpanSource { - interface Handle extends Closeable { - /** - * @return the active {@link Span} pinned by this {@link Handle}. - */ - Span span(); - - /** - * Mark the end of the active period for the {@link Span} pinned by this {@link Handle}. When the last - * {@link Handle} is deactivated for a given {@link Span}, it is automatically {@link Span#finish()}ed. - * - *

- * NOTE: It is an error to call deactivate() more than once on a single {@link Handle}. - * - * @see Closeable#close() {@link Handle}s are auto-closeable and may be used in try-with-resources blocks - */ - void deactivate(); - - /** - * "Fork" a new {@link Continuation} associated with this {@link Handle} and {@link Span}, as well as any - * 3rd-party execution context of interest. - * - *

- * The associated {@link Span} will not {@link Span#finish()} while a {@link Continuation} is outstanding; in - * this way, it provides a reference/pin just like an active @{Handle} does. - * - * @return a new {@link Continuation} to {@link Continuation#activate()} at the appropriate time. - */ - Continuation defer(); - } - - /** - * A {@link Continuation} can be used *once* to activate a Span along with any non-OpenTracing execution context - * (e.g., MDC), then deactivate when processing activity moves on to another Span. (In practice, this active period - * typically extends for the length of a deferred async closure invocation.) - * - *

- * Most users do not directly interact with {@link Continuation}, {@link Continuation#activate()} or - * {@link Handle#deactivate()}, but rather use {@link ActiveSpanSource}-aware Runnables/Callables/Executors. - * Those higher-level primitives need not be defined within the OpenTracing core API, and so they are not. - * - *

- * NOTE: {@link Continuation} extends {@link java.io.Closeable} rather than AutoCloseable in order to keep support - * for JDK1.6. - * - * @see ActiveSpanSource#adopt(Span) - */ - interface Continuation { - /** - * Make the Span (and other execution context) encapsulated by this Continuation active and return it. - * - *

- * NOTE: It is an error to call activate() more than once on a single Continuation instance. - * - * @see ActiveSpanSource#adopt(Span) - * @return a handle to the newly-activated Span - */ - Handle activate(); - } - /** - * @return the active {@link Handle}, or null if none could be found. This does not affect the reference count for - * the {@link Handle}. + * @return the active {@link ActiveSpan}, or null if none could be found. This does not affect the reference count for + * the {@link ActiveSpan}. */ - Handle active(); + ActiveSpan active(); /** * Wrap and "adopt" a @{link Span} by encapsulating it – and any active state (e.g., MDC state) in the execution * context – in a new @{link Handle}. * * @param span the Span just started - * @return a @{link Handle} that encapsulates the given Span and any other ActiveSpanSource-specific context (e.g., + * @return a @{link Handle} that encapsulates the given Span and any other Source-specific context (e.g., * MDC data) */ - Handle adopt(Span span); + ActiveSpan adopt(Span span); } diff --git a/opentracing-api/src/main/java/io/opentracing/Span.java b/opentracing-api/src/main/java/io/opentracing/Span.java index 7a670c46..3c6aa0cb 100644 --- a/opentracing-api/src/main/java/io/opentracing/Span.java +++ b/opentracing-api/src/main/java/io/opentracing/Span.java @@ -21,7 +21,7 @@ * *

Spans are created by the {@link Tracer#buildSpan} interface. */ -public interface Span extends Closeable { +public interface Span { /** * Retrieve the associated SpanContext. * diff --git a/opentracing-api/src/main/java/io/opentracing/ThreadLocalActiveSpan.java b/opentracing-api/src/main/java/io/opentracing/ThreadLocalActiveSpan.java new file mode 100644 index 00000000..429e9a99 --- /dev/null +++ b/opentracing-api/src/main/java/io/opentracing/ThreadLocalActiveSpan.java @@ -0,0 +1,143 @@ +package io.opentracing; + +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + + /** + * {@link ThreadLocalActiveSpan} is a trivial {@link ActiveSpan} implementation that relies on Java's thread-local + * storage primitive. + * + * @see ActiveSpanSource + * @see Tracer#spanSource() + */ +public class ThreadLocalActiveSpan implements ActiveSpan { + private ThreadLocalActiveSpanSource source; + private final Span wrapped; + private ThreadLocalActiveSpan toRestore = null; + private final AtomicInteger refCount; + + ThreadLocalActiveSpan(ThreadLocalActiveSpanSource source, Span wrapped, AtomicInteger refCount) { + this.source = source; + this.refCount = refCount; + this.wrapped = wrapped; + this.toRestore = source.tlsSnapshot.get(); + source.tlsSnapshot.set(this); + } + + @Override + public void deactivate() { + if (source.tlsSnapshot.get() != this) { + // This shouldn't happen if users call methods in the expected order. Bail out. + return; + } + source.tlsSnapshot.set(toRestore); + + if (0 == refCount.decrementAndGet()) { + wrapped.finish(); + } + } + + @Override + public Continuation defer() { + refCount.incrementAndGet(); + return source.makeContinuation(wrapped, refCount); + } + + @Override + public SpanContext context() { + return wrapped.context(); + } + + @Override + public void finish() { + wrapped.finish(); + } + + @Override + public void finish(long finishMicros) { + wrapped.finish(finishMicros); + } + + @Override + public Span setTag(String key, String value) { + return wrapped.setTag(key, value); + } + + @Override + public Span setTag(String key, boolean value) { + return wrapped.setTag(key, value); + } + + @Override + public Span setTag(String key, Number value) { + return wrapped.setTag(key, value); + } + + @Override + public Span log(Map fields) { + return wrapped.log(fields); + } + + @Override + public Span log(long timestampMicroseconds, Map fields) { + return wrapped.log(timestampMicroseconds, fields); + } + + @Override + public Span log(String event) { + return wrapped.log(event); + } + + @Override + public Span log(long timestampMicroseconds, String event) { + return wrapped.log(timestampMicroseconds, event); + } + + @Override + public Span setBaggageItem(String key, String value) { + return wrapped.setBaggageItem(key, value); + } + + @Override + public String getBaggageItem(String key) { + return wrapped.getBaggageItem(key); + } + + @Override + public Span setOperationName(String operationName) { + return wrapped.setOperationName(operationName); + } + + @Override + public Span log(String eventName, Object payload) { + return wrapped.log(eventName, payload); + } + + @Override + public Span log(long timestampMicroseconds, String eventName, Object payload) { + return wrapped.log(timestampMicroseconds, eventName, payload); + } + + @Override + public void close() { + + } + + static class Continuation implements ActiveSpan.Continuation { + private ThreadLocalActiveSpanSource source; + private final Span span; + private final AtomicInteger refCount; + + Continuation(ThreadLocalActiveSpanSource source, Span span, AtomicInteger refCount) { + this.source = source; + this.refCount = refCount; + this.span = span; + } + + @Override + public ThreadLocalActiveSpan activate() { + return new ThreadLocalActiveSpan(source, span, refCount); + } + } + + } diff --git a/opentracing-api/src/main/java/io/opentracing/ThreadLocalActiveSpanSource.java b/opentracing-api/src/main/java/io/opentracing/ThreadLocalActiveSpanSource.java index 85fc0bac..d0b6f105 100644 --- a/opentracing-api/src/main/java/io/opentracing/ThreadLocalActiveSpanSource.java +++ b/opentracing-api/src/main/java/io/opentracing/ThreadLocalActiveSpanSource.java @@ -1,88 +1,24 @@ package io.opentracing; -import java.io.IOException; import java.util.concurrent.atomic.AtomicInteger; /** - * ThreadLocalActiveSpanSource is a trivial ActiveSpanSource implementation that relies on Java's thread-local storage primitive. - * - * @see ActiveSpanSource - * @see Tracer#spanSource() + * Created by bhs on 4/4/17. */ public class ThreadLocalActiveSpanSource implements ActiveSpanSource { - private final ThreadLocal tlsSnapshot = new ThreadLocal(); + final ThreadLocal tlsSnapshot = new ThreadLocal(); - class ThreadLocalHandle implements Handle { - private final Span span; - private ThreadLocalHandle toRestore = null; - private final AtomicInteger refCount; - - ThreadLocalHandle(Span span, AtomicInteger refCount) { - this.refCount = refCount; - this.span = span; - this.toRestore = tlsSnapshot.get(); - tlsSnapshot.set(this); - } - - @Override - public Span span() { - return span; - } - - @Override - public void deactivate() { - if (tlsSnapshot.get() != this) { - // This shouldn't happen if users call methods in the expected order. Bail out. - return; - } - tlsSnapshot.set(toRestore); - - if (0 == refCount.decrementAndGet()) { - Span span = this.span(); - if (span != null) { - this.span().finish(); - } - } - } - - @Override - public ThreadLocalContinuation defer() { - refCount.incrementAndGet(); - return ThreadLocalActiveSpanSource.this.makeContinuation(span(), refCount); - } - - @Override - public void close() throws IOException { - deactivate(); - } - } - - class ThreadLocalContinuation implements Continuation { - private final Span span; - private final AtomicInteger refCount; - - ThreadLocalContinuation(Span span, AtomicInteger refCount) { - this.refCount = refCount; - this.span = span; - } - - @Override - public ThreadLocalHandle activate() { - return new ThreadLocalHandle(span, refCount); - } - } - - ThreadLocalContinuation makeContinuation(Span span, AtomicInteger refCount) { - return new ThreadLocalContinuation(span, refCount); + ThreadLocalActiveSpan.Continuation makeContinuation(Span span, AtomicInteger refCount) { + return new ThreadLocalActiveSpan.Continuation(this, span, refCount); } @Override - public ThreadLocalHandle active() { + public ThreadLocalActiveSpan active() { return tlsSnapshot.get(); } @Override - public Handle adopt(Span span) { + public ActiveSpan adopt(Span span) { return makeContinuation(span, new AtomicInteger(1)).activate(); } diff --git a/opentracing-api/src/main/java/io/opentracing/Tracer.java b/opentracing-api/src/main/java/io/opentracing/Tracer.java index 231d7076..db2ac037 100644 --- a/opentracing-api/src/main/java/io/opentracing/Tracer.java +++ b/opentracing-api/src/main/java/io/opentracing/Tracer.java @@ -32,8 +32,8 @@ public interface Tracer { *

{@code
      *   Tracer tracer = ...
      *
-     *   // Note: if there is an {@link ActiveSpanSource#activeContext()}, it will be treated as the parent of workSpan.
-     *   try (ActiveSpanSource.Handle workHandle = tracer.buildSpan("DoWork").startAndActivate()) {
+     *   // Note: if there is an {@link ActiveSpanSource#active()}, it will be treated as the parent of workSpan.
+     *   try (Source.Handle workHandle = tracer.buildSpan("DoWork").startAndActivate()) {
      *       workHandle.span().setTag("...", "...");
      *       // etc, etc
      *   }
@@ -49,10 +49,10 @@ public interface Tracer {
     SpanBuilder buildSpan(String operationName);
 
     /**
-     * @return the ActiveSpanSource associated with this Tracer. Must not be null.
+     * @return the Source associated with this Tracer. Must not be null.
      *
      * @see ActiveSpanSource
-     * @see ThreadLocalActiveSpanSource a simple built-in thread-local-storage-based ActiveSpanSource
+     * @see ThreadLocalActiveSpanSource a simple built-in thread-local-storage-based Source
      */
     ActiveSpanSource spanSource();
 
@@ -162,18 +162,18 @@ interface SpanBuilder extends SpanContext {
         SpanBuilder withStartTimestamp(long microseconds);
 
         /**
-         * Returns a newly started and {@linkplain ActiveSpanSource.Continuation#activate() activated}
-         * {@link ActiveSpanSource.Handle}.
+         * Returns a newly started and {@linkplain ActiveSpan.Continuation#activate() activated}
+         * {@link ActiveSpan}.
          *
          * 

* - * The returned {@link ActiveSpanSource.Handle} supports try-with-resources. For example: + * The returned {@link ActiveSpan} supports try-with-resources. For example: *

{@code
-         *     try (ActiveSpanSource.Handle handle = tracer.buildSpan("...").startAndActivate()) {
+         *     try (Source.Handle handle = tracer.buildSpan("...").startAndActivate()) {
          *         // Do work
          *         Span span = tracer.spanSource().activeSpan();
          *         span.setTag( ... );  // etc, etc
-         *     }  // Span finishes automatically unless pinned via {@link ActiveSpanSource.Handle#defer}
+         *     }  // Span finishes automatically unless pinned via {@link ActiveSpan#defer}
          * }
* *

@@ -191,13 +191,13 @@ interface SpanBuilder extends SpanContext { * {@code tracer.spanSource().adopt(SpanBuilder.start()).activate()} *

* - * @return a pre-activated {@link ActiveSpanSource.Handle} + * @return a pre-activated {@link ActiveSpan} * * @see Tracer#spanSource() - * @see ActiveSpanSource.Continuation#activate() + * @see ActiveSpan.Continuation#activate() * @see ActiveSpanSource#adopt(Span) */ - ActiveSpanSource.Handle startAndActivate(); + ActiveSpan startAndActivate(); /** * @see SpanBuilder#startAndActivate() diff --git a/opentracing-impl/src/main/java/io/opentracing/impl/AbstractActiveSpan.java b/opentracing-impl/src/main/java/io/opentracing/impl/AbstractActiveSpan.java new file mode 100644 index 00000000..3f8144ec --- /dev/null +++ b/opentracing-impl/src/main/java/io/opentracing/impl/AbstractActiveSpan.java @@ -0,0 +1,158 @@ +package io.opentracing.impl; + +import io.opentracing.ActiveSpan; +import io.opentracing.ActiveSpanSource; +import io.opentracing.Span; +import io.opentracing.SpanContext; + +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * {@link AbstractActiveSpan} deals with {@link ActiveSpanSource}/{@link ActiveSpan}/{@link Continuation} + * reference counting while allowing subclasses to extend with bindings to ThreadLocals, etc. + */ +public abstract class AbstractActiveSpan implements ActiveSpan { + private final AtomicInteger refCount; + protected final Span wrapped; + + protected AbstractActiveSpan(Span wrapped, AtomicInteger refCount) { + this.wrapped = wrapped; + this.refCount = refCount; + } + + @Override + public final void deactivate() { + doDeactivate(); + decRef(); + } + + /** + * Per the {@link java.io.Closeable} API. + */ + @Override + public final void close() { + this.deactivate(); + } + + /** + * Implementations must clean up any state (including thread-locals, etc) associated with the previosly active + * {@link Span}. + */ + protected abstract void doDeactivate(); + + /** + * Return the {@link ActiveSpanSource} associated wih this {@link Continuation}. + */ + protected abstract ActiveSpanSource spanSource(); + + /** + * Decrement the {@link Continuation}'s reference count, calling {@link Span#finish()} if no more references + * remain. + */ + final void decRef() { + if (0 == refCount.decrementAndGet()) { + this.finish(); + } + } + + /** + * Fork and take a reference to the {@link Span} associated with this {@link Continuation} and any 3rd-party + * execution context of interest. + * + * @return a new {@link Continuation} to {@link Continuation#activate()} at the appropriate time. + */ + @Override + public final Continuation defer() { + refCount.incrementAndGet(); + return ((AbstractActiveSpanSource) spanSource()).makeContinuation(this.wrapped, refCount); + } + + @Override + public SpanContext context() { + return wrapped.context(); + } + + @Override + public void finish() { + wrapped.finish(); + } + + @Override + public void finish(long finishMicros) { + wrapped.finish(finishMicros); + } + + @Override + public Span setTag(String key, String value) { + return wrapped.setTag(key, value); + } + + @Override + public Span setTag(String key, boolean value) { + return wrapped.setTag(key, value); + } + + @Override + public Span setTag(String key, Number value) { + return wrapped.setTag(key, value); + } + + @Override + public Span log(Map fields) { + return wrapped.log(fields); + } + + @Override + public Span log(long timestampMicroseconds, Map fields) { + return wrapped.log(timestampMicroseconds, fields); + } + + @Override + public Span log(String event) { + return wrapped.log(event); + } + + @Override + public Span log(long timestampMicroseconds, String event) { + return wrapped.log(timestampMicroseconds, event); + } + + @Override + public Span setBaggageItem(String key, String value) { + return wrapped.setBaggageItem(key, value); + } + + @Override + public String getBaggageItem(String key) { + return wrapped.getBaggageItem(key); + } + + @Override + public Span setOperationName(String operationName) { + return wrapped.setOperationName(operationName); + } + + @Override + public Span log(String eventName, Object payload) { + return wrapped.log(eventName, payload); + } + + @Override + public Span log(long timestampMicroseconds, String eventName, Object payload) { + return wrapped.log(timestampMicroseconds, eventName, payload); + } + + /** + * A helper implementation that does the grunt work of the {@link Continuation} API. + */ + public abstract static class AbstractContinuation implements Continuation { + protected final AtomicInteger refCount; + + protected AbstractContinuation(AtomicInteger refCount) { + this.refCount = refCount; + } + + } + +} diff --git a/opentracing-impl/src/main/java/io/opentracing/impl/AbstractActiveSpanSource.java b/opentracing-impl/src/main/java/io/opentracing/impl/AbstractActiveSpanSource.java index b28d7d31..d738dbe6 100644 --- a/opentracing-impl/src/main/java/io/opentracing/impl/AbstractActiveSpanSource.java +++ b/opentracing-impl/src/main/java/io/opentracing/impl/AbstractActiveSpanSource.java @@ -1,87 +1,20 @@ package io.opentracing.impl; +import io.opentracing.ActiveSpan; import io.opentracing.ActiveSpanSource; import io.opentracing.Span; import java.util.concurrent.atomic.AtomicInteger; /** - * AbstractActiveSpanSource deals with {@link ActiveSpanSource}/{@link Handle}/{@link Continuation} - * reference counting while allowing subclasses to extend with bindings to ThreadLocals, etc. + * {@link AbstractActiveSpanSource} implements {@link #adopt} for {@link AbstractActiveSpan}. */ public abstract class AbstractActiveSpanSource implements ActiveSpanSource { - public abstract class AbstractHandle implements Handle { - private final AtomicInteger refCount; - - protected AbstractHandle(AtomicInteger refCount) { - this.refCount = refCount; - } - - @Override - public final void deactivate() { - doDeactivate(); - decRef(); - } - - /** - * Per the {@link java.io.Closeable} API. - */ - @Override - public final void close() { - this.deactivate(); - } - - /** - * Implementations must clean up any state (including thread-locals, etc) associated with the previosly active - * {@link Span}. - */ - protected abstract void doDeactivate(); - - /** - * Return the {@link ActiveSpanSource} associated wih this {@link Continuation}. - */ - protected abstract ActiveSpanSource spanSource(); - - /** - * Decrement the {@link Continuation}'s reference count, calling {@link Span#finish()} if no more references - * remain. - */ - final void decRef() { - if (0 == refCount.decrementAndGet()) { - Span span = this.span(); - if (span != null) { - this.span().finish(); - } - } - } - - /** - * Fork and take a reference to the {@link Span} associated with this {@link Continuation} and any 3rd-party - * execution context of interest. - * - * @return a new {@link Continuation} to {@link Continuation#activate()} at the appropriate time. - */ - @Override - public final Continuation defer() { - refCount.incrementAndGet(); - return ((AbstractActiveSpanSource) spanSource()).makeContinuation(span(), refCount); - } - } - - public abstract class AbstractContinuation implements ActiveSpanSource.Continuation { - protected final AtomicInteger refCount; - - protected AbstractContinuation(AtomicInteger refCount) { - this.refCount = refCount; - } - - } - @Override - public final Handle adopt(Span span) { + public final ActiveSpan adopt(Span span) { return makeContinuation(span, new AtomicInteger(1)).activate(); } - protected abstract Continuation makeContinuation(Span span, AtomicInteger refCount); + protected abstract AbstractActiveSpan.Continuation makeContinuation(Span wrapped, AtomicInteger refCount); } diff --git a/opentracing-impl/src/main/java/io/opentracing/impl/AbstractSpanBuilder.java b/opentracing-impl/src/main/java/io/opentracing/impl/AbstractSpanBuilder.java index bc2a8966..fa7d88d0 100644 --- a/opentracing-impl/src/main/java/io/opentracing/impl/AbstractSpanBuilder.java +++ b/opentracing-impl/src/main/java/io/opentracing/impl/AbstractSpanBuilder.java @@ -13,8 +13,12 @@ */ package io.opentracing.impl; -import io.opentracing.*; +import io.opentracing.ActiveSpan; import io.opentracing.ActiveSpanSource; +import io.opentracing.References; +import io.opentracing.Span; +import io.opentracing.SpanContext; +import io.opentracing.Tracer; import java.time.Instant; import java.util.ArrayList; @@ -31,15 +35,15 @@ abstract class AbstractSpanBuilder implements Tracer.SpanBuilder { protected boolean forceRoot = false; protected Instant start = Instant.now(); - private final ActiveSpanSource activeSpanSource; + private final ActiveSpanSource spanSource; private final Map stringTags = new HashMap<>(); private final Map booleanTags = new HashMap<>(); private final Map numberTags = new HashMap<>(); private final Map baggage = new HashMap<>(); - AbstractSpanBuilder(String operationName, ActiveSpanSource activeSpanSource) { + AbstractSpanBuilder(String operationName, ActiveSpanSource spanSource) { this.operationName = operationName; - this.activeSpanSource = activeSpanSource; + this.spanSource = spanSource; } /** Create a Span, using the builder fields. */ @@ -133,8 +137,8 @@ public final Span start() { } @Override - public ActiveSpanSource.Handle startAndActivate() { - return activeSpanSource.adopt(start()); + public ActiveSpan startAndActivate() { + return spanSource.adopt(start()); } private void withBaggageFrom(SpanContext from) { diff --git a/opentracing-impl/src/main/java/io/opentracing/impl/AbstractTracer.java b/opentracing-impl/src/main/java/io/opentracing/impl/AbstractTracer.java index b368844f..ecec78a5 100644 --- a/opentracing-impl/src/main/java/io/opentracing/impl/AbstractTracer.java +++ b/opentracing-impl/src/main/java/io/opentracing/impl/AbstractTracer.java @@ -13,9 +13,10 @@ */ package io.opentracing.impl; -import io.opentracing.*; import io.opentracing.ActiveSpanSource; +import io.opentracing.SpanContext; import io.opentracing.ThreadLocalActiveSpanSource; +import io.opentracing.Tracer; import io.opentracing.propagation.Extractor; import io.opentracing.propagation.Format; import io.opentracing.propagation.Injector; @@ -29,15 +30,15 @@ abstract class AbstractTracer implements Tracer { static final boolean BAGGAGE_ENABLED = !Boolean.getBoolean("opentracing.propagation.dropBaggage"); private final PropagationRegistry registry = new PropagationRegistry(); - private ActiveSpanSource activeSpanSource; + private ActiveSpanSource spanSource; protected AbstractTracer() { this(new ThreadLocalActiveSpanSource()); } - protected AbstractTracer(ActiveSpanSource activeSpanSource) { - this.activeSpanSource = activeSpanSource; + protected AbstractTracer(ActiveSpanSource spanSource) { + this.spanSource = spanSource; registry.register(Format.Builtin.TEXT_MAP, new TextMapInjectorImpl(this)); registry.register(Format.Builtin.TEXT_MAP, new TextMapExtractorImpl(this)); } @@ -46,7 +47,7 @@ protected AbstractTracer(ActiveSpanSource activeSpanSource) { @Override public ActiveSpanSource spanSource() { - return this.activeSpanSource; + return this.spanSource; } @Override diff --git a/opentracing-impl/src/main/java/io/opentracing/impl/NoopSpanBuilder.java b/opentracing-impl/src/main/java/io/opentracing/impl/NoopSpanBuilder.java index c8b80540..82abd127 100644 --- a/opentracing-impl/src/main/java/io/opentracing/impl/NoopSpanBuilder.java +++ b/opentracing-impl/src/main/java/io/opentracing/impl/NoopSpanBuilder.java @@ -13,16 +13,16 @@ */ package io.opentracing.impl; -import io.opentracing.NoopSpanContext; import io.opentracing.ActiveSpanSource; +import io.opentracing.NoopSpanContext; import io.opentracing.ThreadLocalActiveSpanSource; final class NoopSpanBuilder extends AbstractSpanBuilder implements io.opentracing.NoopSpanBuilder, NoopSpanContext { static final NoopSpanBuilder INSTANCE = new NoopSpanBuilder("noop", new ThreadLocalActiveSpanSource()); - public NoopSpanBuilder(String operationName, ActiveSpanSource activeSpanSource) { - super(operationName, activeSpanSource); + public NoopSpanBuilder(String operationName, ActiveSpanSource spanSource) { + super(operationName, spanSource); } @Override diff --git a/opentracing-impl/src/test/java/io/opentracing/impl/TestSpanBuilder.java b/opentracing-impl/src/test/java/io/opentracing/impl/TestSpanBuilder.java index 2c3d50cd..8ff272c6 100644 --- a/opentracing-impl/src/test/java/io/opentracing/impl/TestSpanBuilder.java +++ b/opentracing-impl/src/test/java/io/opentracing/impl/TestSpanBuilder.java @@ -18,8 +18,8 @@ final class TestSpanBuilder extends AbstractSpanBuilder { - public TestSpanBuilder(String operationName, ActiveSpanSource activeSpanSource) { - super(operationName, activeSpanSource); + public TestSpanBuilder(String operationName, ActiveSpanSource spanSource) { + super(operationName, spanSource); } @Override diff --git a/opentracing-mdc-demo/pom.xml b/opentracing-mdc-demo/pom.xml new file mode 100644 index 00000000..bb26e046 --- /dev/null +++ b/opentracing-mdc-demo/pom.xml @@ -0,0 +1,64 @@ + + + + 4.0.0 + + + io.opentracing + parent + 0.20.11-SNAPSHOT + + + opentracing-mdc-demo + OpenTracing-mdc-demo + OpenTracing MDC Demo + + + ${project.basedir}/.. + + + + + ${project.groupId} + opentracing-api + + + ${project.groupId} + opentracing-mock + + + org.slf4j + slf4j-api + 1.7.23 + + + log4j + log4j + 1.2.17 + + + org.slf4j + slf4j-log4j12 + 1.7.23 + + + ${project.groupId} + opentracing-impl + + + + diff --git a/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/MDCActiveSpan.java b/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/MDCActiveSpan.java new file mode 100644 index 00000000..b0efc85c --- /dev/null +++ b/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/MDCActiveSpan.java @@ -0,0 +1,59 @@ +package io.opentracing.mdcdemo; + +import io.opentracing.ActiveSpanSource; +import io.opentracing.Span; +import io.opentracing.impl.AbstractActiveSpan; +import org.slf4j.MDC; + +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * MDCActiveSpan illustrates the core ActiveSpan concepts and capabilities to a first approximation. Not + * production-quality code. + */ +class MDCActiveSpan extends AbstractActiveSpan { + private MDCActiveSpanSource mdcActiveSpanSource; + private MDCActiveSpan toRestore = null; + + MDCActiveSpan(MDCActiveSpanSource mdcActiveSpanSource, Span span, Map mdcContext, AtomicInteger refCount) { + super(span, refCount); + this.mdcActiveSpanSource = mdcActiveSpanSource; + this.toRestore = mdcActiveSpanSource.tlsSnapshot.get(); + mdcActiveSpanSource.tlsSnapshot.set(this); + MDC.setContextMap(mdcContext); + } + + @Override + protected void doDeactivate() { + if (mdcActiveSpanSource.tlsSnapshot.get() != this) { + // This shouldn't happen if users call methods in the expected order. Bail out. + return; + } + mdcActiveSpanSource.tlsSnapshot.set(toRestore); + } + + @Override + protected ActiveSpanSource spanSource() { + return mdcActiveSpanSource; + } + + static class MDCContinuation extends AbstractActiveSpan.AbstractContinuation { + private MDCActiveSpanSource mdcActiveSpanSource; + private final Map mdcContext; + private final Span span; + + MDCContinuation(MDCActiveSpanSource source, Span span, AtomicInteger refCount) { + super(refCount); + this.mdcActiveSpanSource = source; + this.mdcContext = MDC.getCopyOfContextMap(); + this.span = span; + } + + @Override + public MDCActiveSpan activate() { + return new MDCActiveSpan(mdcActiveSpanSource, span, mdcContext, refCount); + } + } + +} diff --git a/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/MDCActiveSpanSource.java b/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/MDCActiveSpanSource.java new file mode 100644 index 00000000..05c4abb7 --- /dev/null +++ b/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/MDCActiveSpanSource.java @@ -0,0 +1,31 @@ +package io.opentracing.mdcdemo; + +import io.opentracing.Span; +import io.opentracing.impl.AbstractActiveSpan; +import io.opentracing.impl.AbstractActiveSpanSource; +import org.slf4j.MDC; + +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * MDCActiveSpanSource illustrates the core Source concepts and capabilities to a first approximation. Not + * production-quality code. + */ +public class MDCActiveSpanSource extends AbstractActiveSpanSource { + final ThreadLocal tlsSnapshot = new ThreadLocal(); + + @Override + protected MDCActiveSpan.MDCContinuation makeContinuation(Span span, AtomicInteger refCount) { + if (span instanceof AbstractActiveSpan) { + throw new IllegalArgumentException("Should only adopt the wrapped Span"); + } + return new MDCActiveSpan.MDCContinuation(this, span, refCount); + } + + @Override + public MDCActiveSpan active() { + return tlsSnapshot.get(); + } + +} diff --git a/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/MDCDemo.java b/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/MDCDemo.java new file mode 100644 index 00000000..705b6372 --- /dev/null +++ b/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/MDCDemo.java @@ -0,0 +1,120 @@ +package io.opentracing.mdcdemo; + +import io.opentracing.ActiveSpan; +import io.opentracing.Span; +import io.opentracing.Tracer; +import io.opentracing.mock.MockSpan; +import io.opentracing.mock.MockTracer; +import org.slf4j.Logger; +import org.slf4j.MDC; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +public class MDCDemo { + Tracer tracer; + + private MDCDemo(Tracer tracer) { + this.tracer = tracer; + } + + public void trivialSpan() { + Span span = this.tracer.buildSpan("trivial").start(); + span.finish(); + } + + public void trivialChild() throws Exception { + try (ActiveSpan c = this.tracer.buildSpan("trivialParent").startAndActivate()) { + // The child will automatically know about the parent. + Span child = this.tracer.buildSpan("trivialChild").start(); + child.finish(); + } + } + + public void asyncSpans() throws Exception { + final Tracer tracer = this.tracer; // save typing + + // Create an ExecutorService and adopt it in a TracedExecutorService. + ExecutorService realExecutor = Executors.newFixedThreadPool(500); + final ExecutorService otExecutor = new TracedExecutorService(realExecutor, tracer.spanSource()); + + // Hacky lists of futures we wait for before exiting async Spans. + final List> futures = new ArrayList<>(); + final List> subfutures = new ArrayList<>(); + + // Create a parent Continuation for all of the async activity. + try (final ActiveSpan parentHandle = tracer.buildSpan("parent").startAndActivate();) { + + // Create 10 async children. + for (int i = 0; i < 10; i++) { + final int j = i; + MDC.put("parent number", new Integer(i).toString()); + futures.add(otExecutor.submit(new Runnable() { + @Override + public void run() { + // START child body + + try (final ActiveSpan childHandle = + tracer.buildSpan("child_" + j).startAndActivate();) { + Thread.currentThread().sleep(1000); + tracer.spanSource().active().log("awoke"); + Runnable r = new Runnable() { + @Override + public void run() { + Span active = tracer.spanSource().active(); + active.log("awoke again"); + System.out.println("MDC parent number: " + MDC.get("parent number")); + // Create a grandchild for each child... note that we don't *need* to use the + // Continuation mechanism. + Span grandchild = tracer.buildSpan("grandchild_" + j).start(); + grandchild.finish(); + } + }; + subfutures.add(otExecutor.submit(r)); + } catch (Exception e) { } + + // END child body + } + })); + } + + // Hacky cleanup... grossness has nothing to do with OT :) + for (Future f : futures) { + f.get(); + } + for (Future f : subfutures) { + f.get(); + } + } + + otExecutor.shutdown(); + otExecutor.awaitTermination(3, TimeUnit.SECONDS); + } + + public static void main(String[] args) throws Exception { + org.apache.log4j.BasicConfigurator.configure(); + final Logger logger = org.slf4j.LoggerFactory.getLogger("MDCDemo"); + MDC.put("mdcKey", "mdcVal"); + + final MockTracer tracer = new MockTracer(new MDCActiveSpanSource()); + + // Do stuff with the MockTracer. + { + MDCDemo demo = new MDCDemo(tracer); + demo.trivialSpan(); + demo.trivialChild(); + demo.asyncSpans(); + } + + // Print out all mock-Spans + List finishedSpans = tracer.finishedSpans(); + for (MockSpan span : finishedSpans) { + logger.info("finished Span '{}'. trace={}, span={}, parent={}", span.operationName(), span.context().traceId(), span.context().spanId(), span.parentId()); + } + + } +} diff --git a/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/TracedCallable.java b/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/TracedCallable.java new file mode 100644 index 00000000..a0a2f3cc --- /dev/null +++ b/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/TracedCallable.java @@ -0,0 +1,27 @@ +package io.opentracing.mdcdemo; + +import io.opentracing.ActiveSpan; +import io.opentracing.ActiveSpanSource; + +import java.util.concurrent.Callable; + +public class TracedCallable implements Callable { + private ActiveSpan.Continuation continuation; + private Callable callable; + + public TracedCallable(Callable callable, ActiveSpanSource spanSource) { + this(callable, spanSource.active()); + } + + public TracedCallable(Callable callable, ActiveSpan handle) { + if (callable == null) throw new NullPointerException("Callable is ."); + this.callable = callable; + this.continuation = handle.defer(); + } + + public T call() throws Exception { + try (ActiveSpan handle = continuation.activate()) { + return callable.call(); + } + } +} diff --git a/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/TracedExecutorService.java b/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/TracedExecutorService.java new file mode 100644 index 00000000..8c6a87af --- /dev/null +++ b/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/TracedExecutorService.java @@ -0,0 +1,100 @@ +package io.opentracing.mdcdemo; + +import io.opentracing.ActiveSpanSource; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class TracedExecutorService implements ExecutorService { + private ExecutorService executor; + private ActiveSpanSource spanSource; + + public TracedExecutorService(ExecutorService executor, ActiveSpanSource spanSource) { + if (executor == null) throw new NullPointerException("Executor is ."); + if (spanSource == null) throw new NullPointerException("Source is ."); + this.executor = executor; + this.spanSource = spanSource; + } + + @Override + public void execute(Runnable command) { + executor.execute(new TracedRunnable(command, spanSource)); + } + + @Override + public Future submit(Runnable task) { + return executor.submit(new TracedRunnable(task, spanSource)); + } + + @Override + public Future submit(Runnable task, T result) { + return executor.submit(new TracedRunnable(task, spanSource), result); + } + + @Override + public Future submit(Callable task) { + return executor.submit(new TracedCallable(task, spanSource)); + } + + @Override + public List> invokeAll(Collection> tasks) throws InterruptedException { + return executor.invokeAll(tasksWithTracing(tasks)); + } + + @Override + public List> invokeAll(Collection> tasks, long timeout, TimeUnit unit) + throws InterruptedException { + return executor.invokeAll(tasksWithTracing(tasks), timeout, unit); + } + + @Override + public T invokeAny(Collection> tasks) throws InterruptedException, ExecutionException { + return executor.invokeAny(tasksWithTracing(tasks)); + } + + @Override + public T invokeAny(Collection> tasks, long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return executor.invokeAny(tasksWithTracing(tasks), timeout, unit); + } + + @Override + public void shutdown() { + executor.shutdown(); + } + + @Override + public List shutdownNow() { + return executor.shutdownNow(); + } + + @Override + public boolean isShutdown() { + return executor.isShutdown(); + } + + @Override + public boolean isTerminated() { + return executor.isTerminated(); + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { + return executor.awaitTermination(timeout, unit); + } + + private Collection> tasksWithTracing( + Collection> tasks) { + if (tasks == null) throw new NullPointerException("Collection of tasks is ."); + Collection> result = new ArrayList>(tasks.size()); + for (Callable task : tasks) result.add(new TracedCallable(task, spanSource)); + return result; + } +} diff --git a/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/TracedRunnable.java b/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/TracedRunnable.java new file mode 100644 index 00000000..919227fc --- /dev/null +++ b/opentracing-mdc-demo/src/main/java/io/opentracing/mdcdemo/TracedRunnable.java @@ -0,0 +1,29 @@ +package io.opentracing.mdcdemo; + +import io.opentracing.ActiveSpan; +import io.opentracing.ActiveSpanSource; + +public class TracedRunnable implements Runnable { + private Runnable runnable; + private ActiveSpan.Continuation continuation; + + public TracedRunnable(Runnable runnable, ActiveSpanSource spanSource) { + this(runnable, spanSource.active()); + } + + public TracedRunnable(Runnable runnable, ActiveSpan handle) { + if (runnable == null) throw new NullPointerException("Runnable is ."); + this.runnable = runnable; + this.continuation = handle.defer(); + } + + @Override + public void run() { + // NOTE: There's no way to be sure about the finishOnDeactivate parameter to activate(), so we play it safe. + try (ActiveSpan handle = this.continuation.activate()) { + runnable.run(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java b/opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java index 8ae7d75d..2c18cb70 100644 --- a/opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java +++ b/opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java @@ -13,12 +13,16 @@ */ package io.opentracing.mock; -import java.util.*; -import java.util.concurrent.atomic.AtomicLong; - import io.opentracing.Span; import io.opentracing.SpanContext; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; + /** * MockSpans are created via MockTracer.buildSpan(...), but they are also returned via calls to * MockTracer.finishedSpans(). They provide accessors to all Span state. @@ -98,6 +102,9 @@ public synchronized MockContext context() { return this.context; } + @Override + public void close() { this.finish(); } + @Override public void finish() { this.finish(nowMicros()); diff --git a/opentracing-mock/src/main/java/io/opentracing/mock/MockTracer.java b/opentracing-mock/src/main/java/io/opentracing/mock/MockTracer.java index 652bfb67..0aeb81e2 100644 --- a/opentracing-mock/src/main/java/io/opentracing/mock/MockTracer.java +++ b/opentracing-mock/src/main/java/io/opentracing/mock/MockTracer.java @@ -13,6 +13,16 @@ */ package io.opentracing.mock; +import io.opentracing.ActiveSpan; +import io.opentracing.ActiveSpanSource; +import io.opentracing.References; +import io.opentracing.Span; +import io.opentracing.SpanContext; +import io.opentracing.ThreadLocalActiveSpanSource; +import io.opentracing.Tracer; +import io.opentracing.propagation.Format; +import io.opentracing.propagation.TextMap; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -20,11 +30,6 @@ import java.util.List; import java.util.Map; -import io.opentracing.*; -import io.opentracing.ActiveSpanSource; -import io.opentracing.propagation.Format; -import io.opentracing.propagation.TextMap; - /** * MockTracer makes it easy to test the semantics of OpenTracing instrumentation. * @@ -36,19 +41,19 @@ public class MockTracer implements Tracer { private List finishedSpans = new ArrayList<>(); private final Propagator propagator; - private ActiveSpanSource activeSpanSource; + private ActiveSpanSource spanSource; public MockTracer() { this(Propagator.PRINTER); } - public MockTracer(ActiveSpanSource activeSpanSource) { - this(activeSpanSource, Propagator.PRINTER); + public MockTracer(ActiveSpanSource spanSource) { + this(spanSource, Propagator.PRINTER); } - public MockTracer(ActiveSpanSource activeSpanSource, Propagator propagator) { + public MockTracer(ActiveSpanSource spanSource, Propagator propagator) { this.propagator = propagator; - this.activeSpanSource = activeSpanSource; + this.spanSource = spanSource; } /** @@ -155,24 +160,24 @@ public MockSpan.MockContext extract(Format format, C carrier) { @Override public SpanBuilder buildSpan(String operationName) { SpanBuilder sb = new SpanBuilder(operationName); - if (this.activeSpanSource != null) { + if (this.spanSource != null) { sb.asChildOf(activeSpanContext()); } return sb; } private SpanContext activeSpanContext() { - ActiveSpanSource.Handle handle = this.activeSpanSource.active(); + ActiveSpan handle = this.spanSource.active(); if (handle == null) { return null; } - return handle.span().context(); + return handle.context(); } @Override public ActiveSpanSource spanSource() { - return activeSpanSource; + return spanSource; } @Override @@ -257,9 +262,9 @@ public MockSpan start() { } @Override - public ActiveSpanSource.Handle startAndActivate() { + public ActiveSpan startAndActivate() { MockSpan span = this.start(); - return activeSpanSource.adopt(span); + return spanSource.adopt(span); } @Override diff --git a/opentracing-mock/src/test/java/io/opentracing/mock/MockTracerTest.java b/opentracing-mock/src/test/java/io/opentracing/mock/MockTracerTest.java index 22c23cd9..27b126ac 100644 --- a/opentracing-mock/src/test/java/io/opentracing/mock/MockTracerTest.java +++ b/opentracing-mock/src/test/java/io/opentracing/mock/MockTracerTest.java @@ -13,22 +13,21 @@ */ package io.opentracing.mock; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; +import io.opentracing.Span; +import io.opentracing.SpanContext; +import io.opentracing.Tracer; +import io.opentracing.propagation.Format; +import io.opentracing.propagation.TextMapExtractAdapter; +import io.opentracing.propagation.TextMapInjectAdapter; +import org.junit.Assert; +import org.junit.Test; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import io.opentracing.*; -import io.opentracing.mock.MockTracer; -import org.junit.Assert; -import org.junit.Test; - -import io.opentracing.propagation.Format; -import io.opentracing.propagation.TextMapExtractAdapter; -import io.opentracing.propagation.TextMapInjectAdapter; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; public class MockTracerTest { @Test diff --git a/opentracing-noop/src/main/java/io/opentracing/NoopActiveSpanSource.java b/opentracing-noop/src/main/java/io/opentracing/NoopActiveSpanSource.java deleted file mode 100644 index e527ea92..00000000 --- a/opentracing-noop/src/main/java/io/opentracing/NoopActiveSpanSource.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.opentracing; - -import java.io.IOException; - -/** - * A noop (i.e., cheap-as-possible) implementation of a ActiveSpanSource. - */ -public class NoopActiveSpanSource implements ActiveSpanSource { - public static final Handle NOOP_ACTIVE_SPAN = new NoopHandle(); - public static final Continuation NOOP_CONTINUATION = new NoopContinuation(); - - @Override - public Handle adopt(Span span) { - return NOOP_ACTIVE_SPAN; - } - - @Override - public Handle active() { return NOOP_ACTIVE_SPAN; } - - public static class NoopHandle implements Handle { - @Override - public Span span() { - return null; - } - - @Override - public void deactivate() {} - - @Override - public ActiveSpanSource.Continuation defer() { - return NOOP_CONTINUATION; - } - - @Override - public void close() throws IOException {} - } - public static class NoopContinuation implements ActiveSpanSource.Continuation { - @Override - public Handle activate() { - return NOOP_ACTIVE_SPAN; - } - } -} diff --git a/opentracing-noop/src/main/java/io/opentracing/NoopSource.java b/opentracing-noop/src/main/java/io/opentracing/NoopSource.java new file mode 100644 index 00000000..2f8833e8 --- /dev/null +++ b/opentracing-noop/src/main/java/io/opentracing/NoopSource.java @@ -0,0 +1,115 @@ +package io.opentracing; + +import java.util.Map; + +/** + * A noop (i.e., cheap-as-possible) implementation of a Source. + */ +public class NoopSource implements ActiveSpanSource { + public static final ActiveSpan NOOP_ACTIVE_SPAN = new NoopHandle(); + public static final ActiveSpan.Continuation NOOP_CONTINUATION = new NoopContinuation(); + + @Override + public ActiveSpan adopt(Span span) { + return NOOP_ACTIVE_SPAN; + } + + @Override + public ActiveSpan active() { return NOOP_ACTIVE_SPAN; } + + public static class NoopHandle implements ActiveSpan { + @Override + public void deactivate() {} + + @Override + public Continuation defer() { + return NOOP_CONTINUATION; + } + + @Override + // XXX audit + public SpanContext context() { + return null; + } + + @Override + public void finish() { + + } + + @Override + public void finish(long finishMicros) { + + } + + @Override + public void close() {} + + @Override + public Span setTag(String key, String value) { + return null; + } + + @Override + public Span setTag(String key, boolean value) { + return null; + } + + @Override + public Span setTag(String key, Number value) { + return null; + } + + @Override + public Span log(Map fields) { + return null; + } + + @Override + public Span log(long timestampMicroseconds, Map fields) { + return null; + } + + @Override + public Span log(String event) { + return null; + } + + @Override + public Span log(long timestampMicroseconds, String event) { + return null; + } + + @Override + public Span setBaggageItem(String key, String value) { + return null; + } + + @Override + public String getBaggageItem(String key) { + return null; + } + + @Override + public Span setOperationName(String operationName) { + return null; + } + + @Override + public Span log(String eventName, Object payload) { + return null; + } + + @Override + public Span log(long timestampMicroseconds, String eventName, Object payload) { + return null; + } + } + + public static class NoopContinuation implements ActiveSpan.Continuation { + @Override + public ActiveSpan activate() { + return NOOP_ACTIVE_SPAN; + } + } +} diff --git a/opentracing-noop/src/main/java/io/opentracing/NoopSpan.java b/opentracing-noop/src/main/java/io/opentracing/NoopSpan.java index a30ce47e..4d47859e 100644 --- a/opentracing-noop/src/main/java/io/opentracing/NoopSpan.java +++ b/opentracing-noop/src/main/java/io/opentracing/NoopSpan.java @@ -21,7 +21,6 @@ public interface NoopSpan extends Span { final class NoopSpanImpl implements NoopSpan { - @Override public SpanContext context() { return NoopSpanContextImpl.INSTANCE; } @@ -67,5 +66,8 @@ public void finish(long finishMicros) {} @Override public Span setOperationName(String operationName) { return this; } + @Override + public void close() { finish(); } + } diff --git a/opentracing-noop/src/main/java/io/opentracing/NoopSpanBuilder.java b/opentracing-noop/src/main/java/io/opentracing/NoopSpanBuilder.java index 41dd27a5..4db92b4d 100644 --- a/opentracing-noop/src/main/java/io/opentracing/NoopSpanBuilder.java +++ b/opentracing-noop/src/main/java/io/opentracing/NoopSpanBuilder.java @@ -66,8 +66,8 @@ public Span start() { } @Override - public ActiveSpanSource.Handle startAndActivate() { - return NoopActiveSpanSource.NOOP_ACTIVE_SPAN; + public ActiveSpan startAndActivate() { + return NoopSource.NOOP_ACTIVE_SPAN; } @Override