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}:
- *
- *
- * - Accessing the active {@link Handle}/{@link Span}: first, call {@link Tracer#spanSource()}, then use
- * {@link ActiveSpanSource#active()} and {@link Handle#span}.
- *
- *
- Propagating the active {@link Handle} to another (async) executor. First, call {@link Handle#defer()} to
- * defer a reference to the active Span, then pass that to the async method (even via a final local variable
- * that's used within a closure). Within that closure, code should call {@link Continuation#activate()} to install
- * the deferred {@link Handle}/{@link Span} for subsequent calls to {@link ActiveSpanSource#active)}. (Helper
- * libraries can abstract away much of the above behind {@link java.util.concurrent.ExecutorService} wrappers)
- *
- *
+ * @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 extends Callable> tasks) throws InterruptedException {
+ return executor.invokeAll(tasksWithTracing(tasks));
+ }
+
+ @Override
+ public List> invokeAll(Collection extends Callable> tasks, long timeout, TimeUnit unit)
+ throws InterruptedException {
+ return executor.invokeAll(tasksWithTracing(tasks), timeout, unit);
+ }
+
+ @Override
+ public T invokeAny(Collection extends Callable> tasks) throws InterruptedException, ExecutionException {
+ return executor.invokeAny(tasksWithTracing(tasks));
+ }
+
+ @Override
+ public T invokeAny(Collection extends Callable> 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 extends Callable> tasksWithTracing(
+ Collection extends Callable> 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