Skip to content

Commit

Permalink
make extended tracer easier to use (#6943)
Browse files Browse the repository at this point in the history
Co-authored-by: Jack Berg <[email protected]>
  • Loading branch information
zeitlinger and jack-berg authored Jan 14, 2025
1 parent d71db3a commit 4b3cedd
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import io.opentelemetry.api.incubator.propagation.ExtendedContextPropagators;
import io.opentelemetry.api.internal.ApiUsageLogger;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.Tracer;
Expand All @@ -33,7 +32,7 @@ static Tracer getNoop() {
}

@Override
public SpanBuilder spanBuilder(String spanName) {
public ExtendedSpanBuilder spanBuilder(String spanName) {
return NoopSpanBuilder.create();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ public interface ExtendedTracer extends Tracer {
default boolean isEnabled() {
return true;
}

@Override
ExtendedSpanBuilder spanBuilder(String spanName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,27 +166,32 @@ void startAndCallOrRun() {

// Get a Tracer for a scope
Tracer tracer = tracerProvider.get("org.foo.my-scope");
ExtendedTracer extendedTracer = (ExtendedTracer) tracer;

// Wrap the resetCheckout method in a span
String cartId =
((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout_and_return"))
.setAttribute("key123", "val456")
.startAndCall(() -> resetCheckoutAndReturn("abc123", /* throwException= */ false));
assertThat(cartId).isEqualTo("abc123");
// ...or use ExtendedTracer instance
// ...or runnable variation
((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout"))
extendedTracer
.spanBuilder("reset_checkout")
.startAndRun(() -> resetCheckout("abc123", /* throwException= */ false));

// Wrap the resetCheckout method in a span; resetCheckout throws an exception
try {
((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout_and_return"))
extendedTracer
.spanBuilder("reset_checkout_and_return")
.startAndCall(() -> resetCheckoutAndReturn("def456", /* throwException= */ true));
} catch (Throwable e) {
// Ignore expected exception
}
// ...or runnable variation
try {
((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout"))
extendedTracer
.spanBuilder("reset_checkout")
.startAndRun(() -> resetCheckout("def456", /* throwException= */ true));
} catch (Throwable e) {
// Ignore expected exception
Expand All @@ -195,7 +200,8 @@ void startAndCallOrRun() {
// Wrap the resetCheckout method in a span; resetCheckout throws an exception; use custom error
// handler
try {
((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout_and_return"))
extendedTracer
.spanBuilder("reset_checkout_and_return")
.startAndCall(
() -> resetCheckoutAndReturn("ghi789", /* throwException= */ true),
(span, throwable) -> span.setAttribute("my-attribute", "error"));
Expand All @@ -204,7 +210,8 @@ void startAndCallOrRun() {
}
// ...or runnable variation
try {
((ExtendedSpanBuilder) tracer.spanBuilder("reset_checkout"))
extendedTracer
.spanBuilder("reset_checkout")
.startAndRun(
() -> resetCheckout("ghi789", /* throwException= */ true),
(span, throwable) -> span.setAttribute("my-attribute", "error"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import static org.assertj.core.api.Assertions.assertThat;

import io.opentelemetry.api.incubator.logs.ExtendedLogRecordBuilder;
import io.opentelemetry.api.incubator.logs.ExtendedLogger;
import io.opentelemetry.api.incubator.metrics.ExtendedDoubleCounter;
import io.opentelemetry.api.incubator.metrics.ExtendedDoubleGauge;
Expand All @@ -18,7 +17,6 @@
import io.opentelemetry.api.incubator.metrics.ExtendedLongGauge;
import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogram;
import io.opentelemetry.api.incubator.metrics.ExtendedLongUpDownCounter;
import io.opentelemetry.api.incubator.trace.ExtendedSpanBuilder;
import io.opentelemetry.api.incubator.trace.ExtendedTracer;
import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.api.metrics.Meter;
Expand Down Expand Up @@ -53,7 +51,7 @@ void incubatingLogSdk() {

ExtendedLogger logger = (ExtendedLogger) loggerProvider.get("logger");
logger.isEnabled();
((ExtendedLogRecordBuilder) logger.logRecordBuilder()).setBody("message").emit();
logger.logRecordBuilder().setBody("message").emit();
}

@Test
Expand All @@ -64,7 +62,7 @@ void incubatingTraceSdk() {

ExtendedTracer tracer = (ExtendedTracer) tracerProvider.get("tracer");
tracer.isEnabled();
((ExtendedSpanBuilder) tracer.spanBuilder("span")).startAndRun(() -> {});
tracer.spanBuilder("span").startAndRun(() -> {});
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package io.opentelemetry.sdk.trace;

import io.opentelemetry.api.incubator.trace.ExtendedSpanBuilder;
import io.opentelemetry.api.incubator.trace.ExtendedTracer;
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import io.opentelemetry.sdk.trace.internal.TracerConfig;
Expand All @@ -27,4 +28,9 @@ final class ExtendedSdkTracer extends SdkTracer implements ExtendedTracer {
public boolean isEnabled() {
return tracerEnabled;
}

@Override
public ExtendedSpanBuilder spanBuilder(String spanName) {
return (ExtendedSpanBuilder) super.spanBuilder(spanName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ static SdkTracer create(
: new SdkTracer(sharedState, instrumentationScopeInfo, tracerConfig);
}

/**
* Note that {@link ExtendedSdkTracer#spanBuilder(String)} calls this and depends on it returning
* {@link ExtendedSdkTracer} in all cases when the incubator is present.
*/
@Override
public SpanBuilder spanBuilder(String spanName) {
if (!tracerEnabled) {
Expand All @@ -62,8 +66,7 @@ public SpanBuilder spanBuilder(String spanName) {
spanName = FALLBACK_SPAN_NAME;
}
if (sharedState.hasBeenShutdown()) {
Tracer tracer = TracerProvider.noop().get(instrumentationScopeInfo.getName());
return tracer.spanBuilder(spanName);
return NOOP_TRACER.spanBuilder(spanName);
}
return INCUBATOR_AVAILABLE
? IncubatingUtil.createExtendedSpanBuilder(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.trace;

import static io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder.nameEquals;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static io.opentelemetry.sdk.trace.internal.TracerConfig.disabled;

import io.opentelemetry.api.incubator.trace.ExtendedSpanBuilder;
import io.opentelemetry.api.incubator.trace.ExtendedTracer;
import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
import java.util.function.Supplier;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

class ExtendedTracerTest {

/**
* {@link ExtendedTracer#spanBuilder(String)} delegates to {@link SdkTracer#spanBuilder(String)}
* and casts the result to {@link ExtendedSpanBuilder}. Therefore, we need to confirm that {@link
* SdkTracer#spanBuilder(String)} correctly returns {@link ExtendedSpanBuilder} and not {@link
* io.opentelemetry.api.trace.SpanBuilder} in all cases, else the user will get {@link
* ClassCastException}.
*/
@ParameterizedTest
@MethodSource("spanBuilderArgs")
void spanBuilder(Supplier<ExtendedSpanBuilder> spanBuilderSupplier) {
ExtendedSpanBuilder spanBuilder = spanBuilderSupplier.get();
assertThat(spanBuilder).isInstanceOf(ExtendedSpanBuilder.class);
}

private static Stream<Arguments> spanBuilderArgs() {
SdkTracerProvider tracerProvider =
SdkTracerProvider.builder()
.addSpanProcessor(SimpleSpanProcessor.create(InMemorySpanExporter.create()))
.addTracerConfiguratorCondition(nameEquals("tracerB"), disabled())
.build();

ExtendedTracer tracerA = (ExtendedTracer) tracerProvider.get("tracerA");
ExtendedTracer tracerB = (ExtendedTracer) tracerProvider.get("tracerB");

SdkTracerProvider tracerProvider2 =
SdkTracerProvider.builder()
.addSpanProcessor(SimpleSpanProcessor.create(InMemorySpanExporter.create()))
.build();
ExtendedTracer tracerC = (ExtendedTracer) tracerProvider.get("tracerC");
tracerProvider2.shutdown();

return Stream.of(
// Simple case
Arguments.of(spanBuilderSupplier(() -> tracerA.spanBuilder("span"))),
// Disabled tracer
Arguments.of(spanBuilderSupplier(() -> tracerB.spanBuilder("span"))),
// Invalid span name
Arguments.of(spanBuilderSupplier(() -> tracerB.spanBuilder(null))),
Arguments.of(spanBuilderSupplier(() -> tracerB.spanBuilder(" "))),
// Shutdown tracer provider
Arguments.of(spanBuilderSupplier(() -> tracerC.spanBuilder("span"))));
}

private static Supplier<ExtendedSpanBuilder> spanBuilderSupplier(
Supplier<ExtendedSpanBuilder> spanBuilderSupplier) {
return spanBuilderSupplier;
}
}

0 comments on commit 4b3cedd

Please sign in to comment.