From e447e347e143ebb1838b01c6bb23bd40e3c4f723 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Mon, 4 Dec 2023 09:40:09 -0800 Subject: [PATCH] Allow for simpler creation of start-only and end-only SpanProcessors. (#5923) --- .../TestTracerProviderConfigurer.java | 27 ++-------- .../incubator/trace/OnEndSpanProcessor.java | 49 ++++++++++++++++++ .../incubator/trace/OnStartSpanProcessor.java | 50 +++++++++++++++++++ .../trace/OnEndSpanProcessorTest.java | 31 ++++++++++++ .../trace/OnStartSpanProcessorTest.java | 39 +++++++++++++++ 5 files changed, 173 insertions(+), 23 deletions(-) create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessor.java create mode 100644 sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessor.java create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessorTest.java create mode 100644 sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessorTest.java diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestTracerProviderConfigurer.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestTracerProviderConfigurer.java index 3546b8f816..31d5e8a2dd 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestTracerProviderConfigurer.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/provider/TestTracerProviderConfigurer.java @@ -5,12 +5,9 @@ package io.opentelemetry.sdk.autoconfigure.provider; -import io.opentelemetry.context.Context; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import io.opentelemetry.sdk.trace.ReadWriteSpan; -import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.extension.incubator.trace.OnStartSpanProcessor; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; -import io.opentelemetry.sdk.trace.SpanProcessor; @SuppressWarnings("deprecation") // Support testing of SdkTracerProviderConfigurer public class TestTracerProviderConfigurer @@ -18,24 +15,8 @@ public class TestTracerProviderConfigurer @Override public void configure(SdkTracerProviderBuilder tracerProvider, ConfigProperties config) { tracerProvider.addSpanProcessor( - new SpanProcessor() { - @Override - public void onStart(Context parentContext, ReadWriteSpan span) { - span.setAttribute("configured", config.getBoolean("otel.test.configured")); - } - - @Override - public boolean isStartRequired() { - return true; - } - - @Override - public void onEnd(ReadableSpan span) {} - - @Override - public boolean isEndRequired() { - return false; - } - }); + OnStartSpanProcessor.create( + (ctx, span) -> + span.setAttribute("configured", config.getBoolean("otel.test.configured")))); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessor.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessor.java new file mode 100644 index 0000000000..4a20727720 --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessor.java @@ -0,0 +1,49 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.trace; + +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.trace.SpanProcessor; + +/** A SpanProcessor implementation that is only capable of processing spans when they end. */ +public final class OnEndSpanProcessor implements SpanProcessor { + private final OnEnd onEnd; + + private OnEndSpanProcessor(OnEnd onEnd) { + this.onEnd = onEnd; + } + + static SpanProcessor create(OnEnd onEnd) { + return new OnEndSpanProcessor(onEnd); + } + + @Override + public void onEnd(ReadableSpan span) { + onEnd.apply(span); + } + + @Override + public boolean isEndRequired() { + return true; + } + + @Override + public void onStart(Context parentContext, ReadWriteSpan span) { + // nop + } + + @Override + public boolean isStartRequired() { + return false; + } + + @FunctionalInterface + public interface OnEnd { + void apply(ReadableSpan span); + } +} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessor.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessor.java new file mode 100644 index 0000000000..1ef96c2e88 --- /dev/null +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessor.java @@ -0,0 +1,50 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.trace; + +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.trace.SpanProcessor; + +/** A SpanProcessor that only handles onStart(). */ +public final class OnStartSpanProcessor implements SpanProcessor { + + private final OnStart onStart; + + private OnStartSpanProcessor(OnStart onStart) { + this.onStart = onStart; + } + + public static SpanProcessor create(OnStart onStart) { + return new OnStartSpanProcessor(onStart); + } + + @Override + public void onStart(Context parentContext, ReadWriteSpan span) { + onStart.apply(parentContext, span); + } + + @Override + public boolean isStartRequired() { + return true; + } + + @Override + public void onEnd(ReadableSpan span) { + // nop + } + + @Override + public boolean isEndRequired() { + return false; + } + + @FunctionalInterface + public interface OnStart { + void apply(Context context, ReadWriteSpan span); + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessorTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessorTest.java new file mode 100644 index 0000000000..426b68e813 --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnEndSpanProcessorTest.java @@ -0,0 +1,31 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.trace; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.trace.SpanProcessor; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.jupiter.api.Test; + +class OnEndSpanProcessorTest { + + @Test + void endOnly() { + AtomicReference seenSpan = new AtomicReference<>(); + ReadWriteSpan inputSpan = mock(ReadWriteSpan.class); + + SpanProcessor processor = OnEndSpanProcessor.create(seenSpan::set); + + assertThat(processor.isStartRequired()).isFalse(); + assertThat(processor.isEndRequired()).isTrue(); + processor.onEnd(inputSpan); + assertThat(seenSpan.get()).isSameAs(inputSpan); + } +} diff --git a/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessorTest.java b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessorTest.java new file mode 100644 index 0000000000..245486ec9e --- /dev/null +++ b/sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/trace/OnStartSpanProcessorTest.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.extension.incubator.trace; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.SpanProcessor; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.jupiter.api.Test; + +class OnStartSpanProcessorTest { + + @Test + void startOnly() { + AtomicReference seenContext = new AtomicReference<>(); + AtomicReference seenSpan = new AtomicReference<>(); + Context context = mock(Context.class); + ReadWriteSpan inputSpan = mock(ReadWriteSpan.class); + + SpanProcessor processor = + OnStartSpanProcessor.create( + (ctx, span) -> { + seenContext.set(ctx); + seenSpan.set(span); + }); + + assertThat(processor.isStartRequired()).isTrue(); + assertThat(processor.isEndRequired()).isFalse(); + processor.onStart(context, inputSpan); + assertThat(seenContext.get()).isSameAs(context); + assertThat(seenSpan.get()).isSameAs(inputSpan); + } +}