Skip to content

Commit

Permalink
Revert "Remove getCurrentContext and withSpan from Tracer (#1809)"
Browse files Browse the repository at this point in the history
This reverts commit b73a063.
  • Loading branch information
Bogdan Drutu authored Oct 15, 2020
1 parent 62a96ae commit d7d21d8
Show file tree
Hide file tree
Showing 42 changed files with 279 additions and 140 deletions.
10 changes: 5 additions & 5 deletions QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ To create a basic span, you only need to specify the name of the span.
The start and end time of the span is automatically set by the OpenTelemetry SDK.
```java
Span span = tracer.spanBuilder("my span").startSpan();
try (Scope scope = TracingContextUtils.currentContextWith(span)) {
try (Scope scope = tracer.withSpan(span)) {
// your use case
...
} catch (Throwable t) {
Expand Down Expand Up @@ -87,7 +87,7 @@ The OpenTelemetry API offers also an automated way to propagate the `parentSpan`
```java
void a() {
Span parentSpan = tracer.spanBuilder("a").startSpan();
try(Scope scope = TracingContextUtils.currentContextWith(parentSpan)) {
try(Scope scope = tracer.withSpan(parentSpan)) {
b();
} finally {
parentSpan.end();
Expand All @@ -96,9 +96,9 @@ void a() {
void b() {
Span childSpan = tracer.spanBuilder("b")
// NOTE: setParent(parentSpan) is not required;
// `TracingContextUtils.getCurrentSpan()` is automatically added as parent
// `tracer.getCurrentSpan()` is automatically added as parent
.startSpan();
try(Scope scope = TracingContextUtils.currentContextWith(childSpan)) {
try(Scope scope = tracer.withSpan(childSpan)) {
// do stuff
} finally {
childSpan.end();
Expand Down Expand Up @@ -185,7 +185,7 @@ TextMapPropagator.Setter<HttpURLConnection> setter =

URL url = new URL("http://127.0.0.1:8080/resource");
Span outGoing = tracer.spanBuilder("/resource").setSpanKind(Span.Kind.CLIENT).startSpan();
try (Scope scope = TracingContextUtils.currentContextWith(outGoing)) {
try (Scope scope = tracer.withSpan(outGoing)) {
// Semantic Convention.
// (Observe that to set these, Span does not *need* to be the current instance.)
outGoing.setAttribute("http.method", "GET");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class DefaultTracerBenchmarks {
@Warmup(iterations = 5, time = 1)
public void measureFullSpanLifecycle() {
span = tracer.spanBuilder("span").startSpan();
try (io.opentelemetry.context.Scope ignored = TracingContextUtils.currentContextWith(span)) {
try (io.opentelemetry.context.Scope ignored = tracer.withSpan(span)) {
// no-op
} finally {
span.end();
Expand All @@ -59,7 +59,7 @@ public void measureSpanBuilding() {
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 1)
public void measureScopeLifecycle() {
try (io.opentelemetry.context.Scope ignored = TracingContextUtils.currentContextWith(span)) {
try (io.opentelemetry.context.Scope ignored = tracer.withSpan(span)) {
// no-op
}
}
Expand All @@ -71,7 +71,7 @@ public void measureScopeLifecycle() {
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 1)
public void measureGetCurrentSpan() {
TracingContextUtils.getCurrentSpan();
tracer.getCurrentSpan();
}

@TearDown(Level.Iteration)
Expand Down
11 changes: 11 additions & 0 deletions api/src/main/java/io/opentelemetry/trace/DefaultTracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.opentelemetry.common.AttributeKey;
import io.opentelemetry.common.Attributes;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.internal.Utils;
import java.util.Objects;
import javax.annotation.Nullable;
Expand All @@ -27,6 +28,16 @@ public static Tracer getInstance() {
return INSTANCE;
}

@Override
public Span getCurrentSpan() {
return TracingContextUtils.getCurrentSpan();
}

@Override
public Scope withSpan(Span span) {
return TracingContextUtils.currentContextWith(span);
}

@Override
public Span.Builder spanBuilder(String spanName) {
return NoopSpanBuilder.create(spanName);
Expand Down
8 changes: 4 additions & 4 deletions api/src/main/java/io/opentelemetry/trace/Span.java
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,8 @@ default void setAttribute(AttributeKey<Long> key, int value) {
* void doWork {
* // Create a Span as a child of the current Span.
* Span span = tracer.spanBuilder("MyChildSpan").startSpan();
* try (Scope ss = TracingContextUtils.currentContextWith(span)) {
* TracingContextUtils.getCurrentSpan().addEvent("my event");
* try (Scope ss = tracer.withSpan(span)) {
* tracer.getCurrentSpan().addEvent("my event");
* doSomeWork(); // Here the new span is in the current Context, so it can be used
* // implicitly anywhere down the stack.
* } finally {
Expand All @@ -327,8 +327,8 @@ default void setAttribute(AttributeKey<Long> key, int value) {
* }
*
* public void onExecuteHandler(ServerCallHandler serverCallHandler) {
* try (Scope ws = TracingContextUtils.currentContextWith(mySpan)) {
* TracingContextUtils.getCurrentSpan().addEvent("Start rpc execution.");
* try (Scope ws = tracer.withSpan(mySpan)) {
* tracer.getCurrentSpan().addEvent("Start rpc execution.");
* serverCallHandler.run(); // Here the new span is in the current Context, so it can be
* // used implicitly anywhere down the stack.
* }
Expand Down
74 changes: 71 additions & 3 deletions api/src/main/java/io/opentelemetry/trace/Tracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

package io.opentelemetry.trace;

import com.google.errorprone.annotations.MustBeClosed;
import io.opentelemetry.context.Scope;
import javax.annotation.concurrent.ThreadSafe;

/**
Expand All @@ -25,10 +27,10 @@
* private static final Tracer tracer = OpenTelemetry.getTracer();
* void doWork() {
* Span span = tracer.spanBuilder("MyClass.DoWork").startSpan();
* try(Scope ss = TracingContextUtils.currentContextWith(span)) {
* TracingContextUtils.getCurrentSpan().addEvent("Starting the work.");
* try(Scope ss = tracer.withSpan(span)) {
* tracer.getCurrentSpan().addEvent("Starting the work.");
* doWorkInternal();
* TracingContextUtils.getCurrentSpan().addEvent("Finished working.");
* tracer.getCurrentSpan().addEvent("Finished working.");
* } finally {
* span.end();
* }
Expand Down Expand Up @@ -57,6 +59,72 @@
*/
@ThreadSafe
public interface Tracer {
/**
* Gets the current Span from the current Context.
*
* <p>To install a {@link Span} to the current Context use {@link #withSpan(Span)}.
*
* <p>startSpan methods do NOT modify the current Context {@code Span}.
*
* @return a default {@code Span} that does nothing and has an invalid {@link SpanContext} if no
* {@code Span} is associated with the current Context, otherwise the current {@code Span}
* from the Context.
*/
Span getCurrentSpan();

/**
* Enters the scope of code where the given {@link Span} is in the current Context, and returns an
* object that represents that scope. The scope is exited when the returned object is closed.
*
* <p>Supports try-with-resource idiom.
*
* <p>Can be called with {@code Span.getPropagated(span.getContext())} to enter a scope of code
* where tracing is stopped.
*
* <p>Example of usage:
*
* <pre>{@code
* private static Tracer tracer = OpenTelemetry.getTracer();
* void doWork() {
* // Create a Span as a child of the current Span.
* Span span = tracer.spanBuilder("my span").startSpan();
* try (Scope ws = tracer.withSpan(span)) {
* tracer.getCurrentSpan().addEvent("my event");
* doSomeOtherWork(); // Here "span" is the current Span.
* }
* span.end();
* }
* }</pre>
*
* <p>Prior to Java SE 7, you can use a finally block to ensure that a resource is closed
* regardless of whether the try statement completes normally or abruptly.
*
* <p>Example of usage prior to Java SE7:
*
* <pre>{@code
* private static Tracer tracer = OpenTelemetry.getTracer();
* void doWork() {
* // Create a Span as a child of the current Span.
* Span span = tracer.spanBuilder("my span").startSpan();
* Scope ws = tracer.withSpan(span);
* try {
* tracer.getCurrentSpan().addEvent("my event");
* doSomeOtherWork(); // Here "span" is the current Span.
* } finally {
* ws.close();
* }
* span.end();
* }
* }</pre>
*
* @param span The {@link Span} to be set to the current Context.
* @return an object that defines a scope where the given {@link Span} will be set to the current
* Context.
* @throws NullPointerException if {@code span} is {@code null}.
*/
@MustBeClosed
Scope withSpan(Span span);

/**
* Returns a {@link Span.Builder} to create and start a new {@link Span}.
*
Expand Down
17 changes: 0 additions & 17 deletions api/src/main/java/io/opentelemetry/trace/TracingContextUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

package io.opentelemetry.trace;

import com.google.errorprone.annotations.MustBeClosed;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
import io.opentelemetry.context.Scope;
Expand Down Expand Up @@ -67,25 +66,9 @@ public static Span getSpanWithoutDefault(Context context) {
* Returns a new {@link Scope} encapsulating the provided {@link Span} added to the current {@code
* Context}.
*
* <p>Example of usage:
*
* <pre>{@code
* private static Tracer tracer = OpenTelemetry.getTracer();
* void doWork() {
* // Create a Span as a child of the current Span.
* Span span = tracer.spanBuilder("my span").startSpan();
* try (Scope ws = TracingContextUtils.currentContextWith(span)) {
* TracingContextUtils.getCurrentSpan().addEvent("my event");
* doSomeOtherWork(); // Here "span" is the current Span.
* }
* span.end();
* }
* }</pre>
*
* @param span the {@link Span} to be added to the current {@code Context}.
* @return the {@link Scope} for the updated {@code Context}.
*/
@MustBeClosed
public static Scope currentContextWith(Span span) {
return withSpan(span, io.opentelemetry.context.Context.current()).makeCurrent();
}
Expand Down
12 changes: 12 additions & 0 deletions api/src/test/java/io/opentelemetry/OpenTelemetryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,18 @@ public Tracer get(String instrumentationName, String instrumentationVersion) {
return get(instrumentationName);
}

@Nullable
@Override
public Span getCurrentSpan() {
return null;
}

@Nullable
@Override
public Scope withSpan(Span span) {
return null;
}

@Nullable
@Override
public Span.Builder spanBuilder(String spanName) {
Expand Down
51 changes: 50 additions & 1 deletion api/src/test/java/io/opentelemetry/trace/DefaultTracerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static org.junit.jupiter.api.Assertions.assertThrows;

import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import org.junit.jupiter.api.Test;

/** Unit tests for {@link DefaultTracer}. */
Expand All @@ -28,6 +29,20 @@ class DefaultTracerTest {
TraceFlags.getDefault(),
TraceState.getDefault());

@Test
void defaultGetCurrentSpan() {
assertThat(defaultTracer.getCurrentSpan().getContext().isValid()).isFalse();
}

@Test
void getCurrentSpan_WithSpan() {
assertThat(defaultTracer.getCurrentSpan().getContext().isValid()).isFalse();
try (Scope ws = defaultTracer.withSpan(Span.getInvalid())) {
assertThat(defaultTracer.getCurrentSpan().getContext().isValid()).isFalse();
}
assertThat(defaultTracer.getCurrentSpan().getContext().isValid()).isFalse();
}

@Test
void spanBuilderWithName_NullName() {
assertThrows(NullPointerException.class, () -> defaultTracer.spanBuilder(null));
Expand All @@ -38,6 +53,21 @@ void defaultSpanBuilderWithName() {
assertThat(defaultTracer.spanBuilder(SPAN_NAME).startSpan().getContext().isValid()).isFalse();
}

@Test
void testInProcessContext() {
Span span = defaultTracer.spanBuilder(SPAN_NAME).startSpan();
try (Scope scope = defaultTracer.withSpan(span)) {
assertThat(defaultTracer.getCurrentSpan()).isEqualTo(span);
Span secondSpan = defaultTracer.spanBuilder(SPAN_NAME).startSpan();
try (Scope secondScope = defaultTracer.withSpan(secondSpan)) {
assertThat(defaultTracer.getCurrentSpan()).isEqualTo(secondSpan);
} finally {
assertThat(defaultTracer.getCurrentSpan()).isEqualTo(span);
}
}
assertThat(defaultTracer.getCurrentSpan().getContext().isValid()).isFalse();
}

@Test
void testSpanContextPropagationExplicitParent() {
Span span =
Expand Down Expand Up @@ -69,7 +99,8 @@ void noSpanContextMakesInvalidSpans() {
@Test
void testSpanContextPropagation_nullContext() {
assertThrows(
NullPointerException.class, () -> defaultTracer.spanBuilder(SPAN_NAME).setParent(null));
NullPointerException.class,
() -> defaultTracer.spanBuilder(SPAN_NAME).setParent((Context) null));
}

@Test
Expand All @@ -95,4 +126,22 @@ void testSpanContextPropagation_fromContextThenNoParent() {
Span span = defaultTracer.spanBuilder(SPAN_NAME).setParent(context).setNoParent().startSpan();
assertThat(span.getContext()).isEqualTo(SpanContext.getInvalid());
}

@Test
void testSpanContextPropagationCurrentSpan() {
Span parent = Span.wrap(spanContext);
try (Scope scope = defaultTracer.withSpan(parent)) {
Span span = defaultTracer.spanBuilder(SPAN_NAME).startSpan();
assertThat(span.getContext()).isSameAs(spanContext);
}
}

@Test
void testSpanContextPropagationCurrentSpanContext() {
Context context = TracingContextUtils.withSpan(Span.wrap(spanContext), Context.current());
try (Scope scope = context.makeCurrent()) {
Span span = defaultTracer.spanBuilder(SPAN_NAME).startSpan();
assertThat(span.getContext()).isSameAs(spanContext);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.junit.jupiter.api.Test;

class TracingContextUtilsTest {

@Test
void testGetCurrentSpan_Default() {
Span span = TracingContextUtils.getCurrentSpan();
Expand Down Expand Up @@ -51,19 +52,4 @@ void testGetSpanWithoutDefault_ExplicitContext() {
Context context = TracingContextUtils.withSpan(span, Context.current());
assertThat(TracingContextUtils.getSpanWithoutDefault(context)).isSameAs(span);
}

@Test
void testInProcessContext() {
Span span = Span.wrap(SpanContext.getInvalid());
try (Scope scope = TracingContextUtils.currentContextWith(span)) {
assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(span);
Span secondSpan = Span.wrap(SpanContext.getInvalid());
try (Scope secondScope = TracingContextUtils.currentContextWith(secondSpan)) {
assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(secondSpan);
} finally {
assertThat(TracingContextUtils.getCurrentSpan()).isSameAs(span);
}
}
assertThat(TracingContextUtils.getCurrentSpan().getContext().isValid()).isFalse();
}
}
2 changes: 1 addition & 1 deletion context/src/main/java/io/opentelemetry/context/Scope.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* you use this class with a {@code try-with-resources} block:
*
* <pre>{@code
* try (Scope ignored = TracingContextUtils.currentContextWith(span)) {
* try (Scope ignored = tracer.withSpan(span)) {
* ...
* }
* }</pre>
Expand Down
Loading

0 comments on commit d7d21d8

Please sign in to comment.