From c03efbcc13f9912e172801c2b6bc57c30a5644dd Mon Sep 17 00:00:00 2001 From: John Watson Date: Thu, 3 Dec 2020 21:12:48 -0800 Subject: [PATCH] Add an option to the SDK builder to specify an initial TraceConfig (#2192) * Add an option to set the initial TraceConfig when building an SDK, and a TracerSdkProvider. * add the missing javadoc --- .../opentelemetry/sdk/OpenTelemetrySdk.java | 17 +++++++++++++ .../sdk/OpenTelemetrySdkTest.java | 6 ++++- .../sdk/trace/TracerSdkProvider.java | 25 ++++++++++++++----- .../sdk/trace/TracerSharedState.java | 6 +++-- .../sdk/trace/TracerSdkProviderTest.java | 18 +++++++++++++ 5 files changed, 63 insertions(+), 9 deletions(-) diff --git a/sdk/all/src/main/java/io/opentelemetry/sdk/OpenTelemetrySdk.java b/sdk/all/src/main/java/io/opentelemetry/sdk/OpenTelemetrySdk.java index 0044a82b29..51272f41c0 100644 --- a/sdk/all/src/main/java/io/opentelemetry/sdk/OpenTelemetrySdk.java +++ b/sdk/all/src/main/java/io/opentelemetry/sdk/OpenTelemetrySdk.java @@ -22,6 +22,7 @@ import io.opentelemetry.sdk.trace.IdGenerator; import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.TracerSdkManagement; import io.opentelemetry.sdk.trace.TracerSdkProvider; +import io.opentelemetry.sdk.trace.config.TraceConfig; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -114,6 +115,7 @@ public final class OpenTelemetrySdk extends DefaultOpenTelemetry { private Resource resource; private final List spanProcessors = new ArrayList<>(); private IdGenerator idGenerator; + private TraceConfig traceConfig; /** * Sets the {@link TracerSdkProvider} to use. This can be used to configure tracing settings by @@ -212,6 +214,18 @@ public final class OpenTelemetrySdk extends DefaultOpenTelemetry { return this; } + /** + * Set the {@link TraceConfig} that will be initially set on the Tracing SDK. + * + *

Using {@link #setTracerProvider(TracerProvider)} will override this setting. + * + * @return this + */ + public Builder setTraceConfig(TraceConfig traceConfig) { + this.traceConfig = traceConfig; + return this; + } + /** * Returns a new {@link OpenTelemetrySdk} built with the configuration of this {@link Builder}. */ @@ -253,6 +267,9 @@ public final class OpenTelemetrySdk extends DefaultOpenTelemetry { if (idGenerator != null) { tracerProviderBuilder.setIdGenerator(idGenerator); } + if (traceConfig != null) { + tracerProviderBuilder.setTraceConfig(traceConfig); + } return tracerProviderBuilder.build(); } diff --git a/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java b/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java index 945936be26..9707656d77 100644 --- a/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java +++ b/sdk/all/src/test/java/io/opentelemetry/sdk/OpenTelemetrySdkTest.java @@ -27,6 +27,7 @@ import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.IdGenerator; import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.TracerSdkProvider; +import io.opentelemetry.sdk.trace.config.TraceConfig; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; @@ -116,11 +117,13 @@ class OpenTelemetrySdkTest { void testConfiguration_tracerSettings() { Resource resource = Resource.create(Attributes.builder().put("cat", "meow").build()); IdGenerator idGenerator = mock(IdGenerator.class); + TraceConfig traceConfig = mock(TraceConfig.class); OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder() .setClock(clock) .setResource(resource) .setIdGenerator(idGenerator) + .setTraceConfig(traceConfig) .build(); TracerProvider unobfuscatedTracerProvider = ((ObfuscatedTracerProvider) openTelemetry.getTracerProvider()).unobfuscate(); @@ -132,7 +135,8 @@ class OpenTelemetrySdkTest { .extracting("sharedState") .hasFieldOrPropertyWithValue("clock", clock) .hasFieldOrPropertyWithValue("resource", resource) - .hasFieldOrPropertyWithValue("idGenerator", idGenerator); + .hasFieldOrPropertyWithValue("idGenerator", idGenerator) + .hasFieldOrPropertyWithValue("activeTraceConfig", traceConfig); assertThat(openTelemetry.getMeterProvider()).isInstanceOf(MeterSdkProvider.class); // Since MeterProvider is in a different package, the only alternative to this reflective diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSdkProvider.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSdkProvider.java index 2c633dc421..81341a6642 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSdkProvider.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSdkProvider.java @@ -42,8 +42,9 @@ public class TracerSdkProvider implements TracerProvider, TracerSdkManagement { return new Builder(); } - private TracerSdkProvider(Clock clock, IdGenerator idsGenerator, Resource resource) { - this.sharedState = new TracerSharedState(clock, idsGenerator, resource); + private TracerSdkProvider( + Clock clock, IdGenerator idsGenerator, Resource resource, TraceConfig traceConfig) { + this.sharedState = new TracerSharedState(clock, idsGenerator, resource, traceConfig); this.tracerSdkComponentRegistry = new TracerSdkComponentRegistry(sharedState); } @@ -92,7 +93,7 @@ public class TracerSdkProvider implements TracerProvider, TracerSdkManagement { } /** - * Builder class for the TracerSdkFactory. Has fully functional default implementations of all + * Builder class for the TraceSdkProvider. Has fully functional default implementations of all * three required interfaces. */ public static class Builder { @@ -100,6 +101,7 @@ public class TracerSdkProvider implements TracerProvider, TracerSdkManagement { private Clock clock = SystemClock.getInstance(); private IdGenerator idsGenerator = IdGenerator.random(); private Resource resource = Resource.getDefault(); + private TraceConfig traceConfig = TraceConfig.getDefault(); /** * Assign a {@link Clock}. @@ -139,12 +141,23 @@ public class TracerSdkProvider implements TracerProvider, TracerSdkManagement { } /** - * Create a new TracerSdkFactory instance. + * Assign an initial {@link TraceConfig} that should be used with this SDK. * - * @return An initialized TracerSdkFactory. + * @return this + */ + public Builder setTraceConfig(TraceConfig traceConfig) { + this.traceConfig = traceConfig; + Objects.requireNonNull(traceConfig); + return this; + } + + /** + * Create a new TraceSdkProvider instance. + * + * @return An initialized TraceSdkProvider. */ public TracerSdkProvider build() { - return new TracerSdkProvider(clock, idsGenerator, resource); + return new TracerSdkProvider(clock, idsGenerator, resource, traceConfig); } private Builder() {} diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java index a6b038db31..0fa38aa587 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/TracerSharedState.java @@ -22,17 +22,19 @@ final class TracerSharedState { // Reads and writes are atomic for reference variables. Use volatile to ensure that these // operations are visible on other CPUs as well. - private volatile TraceConfig activeTraceConfig = TraceConfig.getDefault(); + private volatile TraceConfig activeTraceConfig; private volatile SpanProcessor activeSpanProcessor = NoopSpanProcessor.getInstance(); private volatile boolean isStopped = false; @GuardedBy("lock") private final List registeredSpanProcessors = new ArrayList<>(); - TracerSharedState(Clock clock, IdGenerator idGenerator, Resource resource) { + TracerSharedState( + Clock clock, IdGenerator idGenerator, Resource resource, TraceConfig traceConfig) { this.clock = clock; this.idGenerator = idGenerator; this.resource = resource; + this.activeTraceConfig = traceConfig; } Clock getClock() { diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerSdkProviderTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerSdkProviderTest.java index afa724b7f8..2b1a7eee88 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerSdkProviderTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/TracerSdkProviderTest.java @@ -48,10 +48,19 @@ class TracerSdkProviderTest { .setClock(mock(Clock.class)) .setResource(mock(Resource.class)) .setIdGenerator(mock(IdGenerator.class)) + .setTraceConfig(mock(TraceConfig.class)) .build()) .isNotNull(); } + @Test + void builder_NullTraceConfig() { + assertThrows( + NullPointerException.class, + () -> TracerSdkProvider.builder().setTraceConfig(null), + "traceConfig"); + } + @Test void builder_NullClock() { assertThrows( @@ -107,6 +116,15 @@ class TracerSdkProviderTest { assertThat(tracerFactory.getActiveTraceConfig()).isEqualTo(newConfig); } + @Test + void build_traceConfig() { + TraceConfig initialTraceConfig = mock(TraceConfig.class); + TracerSdkProvider tracerSdkProvider = + TracerSdkProvider.builder().setTraceConfig(initialTraceConfig).build(); + + assertThat(tracerSdkProvider.getActiveTraceConfig()).isSameAs(initialTraceConfig); + } + @Test void shutdown() { tracerFactory.shutdown();