diff --git a/opentracing-api/src/main/java/io/opentracing/Span.java b/opentracing-api/src/main/java/io/opentracing/Span.java index 2ab7d57e..0419da54 100644 --- a/opentracing-api/src/main/java/io/opentracing/Span.java +++ b/opentracing-api/src/main/java/io/opentracing/Span.java @@ -22,18 +22,34 @@ public interface Span extends AutoCloseable { /** * Retrieve the associated SpanContext. * + * This may be called at any time, including after calls to finish(). + * * @return the SpanContext that encapsulates Span state that should propagate across process boundaries. */ SpanContext context(); /** - * Sets the end timestamp and records the span. + * Sets the end timestamp to now and records the span. + * + *

With the exception of calls to Span.context(), this should be the last call made to the span instance, and to + * do otherwise leads to undefined behavior. * - *

This should be the last call made to any span instance, and to do otherwise leads to - * undefined behavior. + * @see Span#context() */ void finish(); + /** + * Sets an explicit end timestamp and records the span. + * + *

With the exception of calls to Span.context(), this should be the last call made to the span instance, and to + * do otherwise leads to undefined behavior. + * + * @param finishMicros an explicit finish time, in microseconds since the epoch + * + * @see Span#context() + */ + void finish(long finishMicros); + void close(); /** diff --git a/opentracing-impl-java8/src/main/java/io/opentracing/AbstractSpan.java b/opentracing-impl-java8/src/main/java/io/opentracing/AbstractSpan.java index b7ae5305..77f75816 100644 --- a/opentracing-impl-java8/src/main/java/io/opentracing/AbstractSpan.java +++ b/opentracing-impl-java8/src/main/java/io/opentracing/AbstractSpan.java @@ -43,6 +43,13 @@ public void finish() { assert null == duration; duration = Duration.between(start, Instant.now()); } + @Override + public void finish(long finishMicros) { + long finishEpochSeconds = TimeUnit.MICROSECONDS.toSeconds(finishMicros); + long nanos = TimeUnit.MICROSECONDS.toNanos(finishMicros) - TimeUnit.SECONDS.toNanos(finishEpochSeconds); + assert null == duration; + duration = Duration.between(start, Instant.ofEpochSecond(finishEpochSeconds, nanos)); + } @Override public void close() { diff --git a/opentracing-impl/src/main/java/io/opentracing/NoopSpan.java b/opentracing-impl/src/main/java/io/opentracing/NoopSpan.java index 0cc19283..d8152835 100644 --- a/opentracing-impl/src/main/java/io/opentracing/NoopSpan.java +++ b/opentracing-impl/src/main/java/io/opentracing/NoopSpan.java @@ -26,6 +26,9 @@ private NoopSpan() {} @Override public void finish() {} + @Override + public void finish(long finishMicros) {} + @Override public void close() { finish();