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
This commit is contained in:
John Watson 2020-12-03 21:12:48 -08:00 committed by GitHub
parent b3bf869c54
commit c03efbcc13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 9 deletions

View File

@ -22,6 +22,7 @@ import io.opentelemetry.sdk.trace.IdGenerator;
import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.SpanProcessor;
import io.opentelemetry.sdk.trace.TracerSdkManagement; import io.opentelemetry.sdk.trace.TracerSdkManagement;
import io.opentelemetry.sdk.trace.TracerSdkProvider; import io.opentelemetry.sdk.trace.TracerSdkProvider;
import io.opentelemetry.sdk.trace.config.TraceConfig;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@ -114,6 +115,7 @@ public final class OpenTelemetrySdk extends DefaultOpenTelemetry {
private Resource resource; private Resource resource;
private final List<SpanProcessor> spanProcessors = new ArrayList<>(); private final List<SpanProcessor> spanProcessors = new ArrayList<>();
private IdGenerator idGenerator; private IdGenerator idGenerator;
private TraceConfig traceConfig;
/** /**
* Sets the {@link TracerSdkProvider} to use. This can be used to configure tracing settings by * 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; return this;
} }
/**
* Set the {@link TraceConfig} that will be initially set on the Tracing SDK.
*
* <p>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}. * 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) { if (idGenerator != null) {
tracerProviderBuilder.setIdGenerator(idGenerator); tracerProviderBuilder.setIdGenerator(idGenerator);
} }
if (traceConfig != null) {
tracerProviderBuilder.setTraceConfig(traceConfig);
}
return tracerProviderBuilder.build(); return tracerProviderBuilder.build();
} }

View File

@ -27,6 +27,7 @@ import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.IdGenerator; import io.opentelemetry.sdk.trace.IdGenerator;
import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.SpanProcessor;
import io.opentelemetry.sdk.trace.TracerSdkProvider; import io.opentelemetry.sdk.trace.TracerSdkProvider;
import io.opentelemetry.sdk.trace.config.TraceConfig;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock; import org.mockito.Mock;
@ -116,11 +117,13 @@ class OpenTelemetrySdkTest {
void testConfiguration_tracerSettings() { void testConfiguration_tracerSettings() {
Resource resource = Resource.create(Attributes.builder().put("cat", "meow").build()); Resource resource = Resource.create(Attributes.builder().put("cat", "meow").build());
IdGenerator idGenerator = mock(IdGenerator.class); IdGenerator idGenerator = mock(IdGenerator.class);
TraceConfig traceConfig = mock(TraceConfig.class);
OpenTelemetrySdk openTelemetry = OpenTelemetrySdk openTelemetry =
OpenTelemetrySdk.builder() OpenTelemetrySdk.builder()
.setClock(clock) .setClock(clock)
.setResource(resource) .setResource(resource)
.setIdGenerator(idGenerator) .setIdGenerator(idGenerator)
.setTraceConfig(traceConfig)
.build(); .build();
TracerProvider unobfuscatedTracerProvider = TracerProvider unobfuscatedTracerProvider =
((ObfuscatedTracerProvider) openTelemetry.getTracerProvider()).unobfuscate(); ((ObfuscatedTracerProvider) openTelemetry.getTracerProvider()).unobfuscate();
@ -132,7 +135,8 @@ class OpenTelemetrySdkTest {
.extracting("sharedState") .extracting("sharedState")
.hasFieldOrPropertyWithValue("clock", clock) .hasFieldOrPropertyWithValue("clock", clock)
.hasFieldOrPropertyWithValue("resource", resource) .hasFieldOrPropertyWithValue("resource", resource)
.hasFieldOrPropertyWithValue("idGenerator", idGenerator); .hasFieldOrPropertyWithValue("idGenerator", idGenerator)
.hasFieldOrPropertyWithValue("activeTraceConfig", traceConfig);
assertThat(openTelemetry.getMeterProvider()).isInstanceOf(MeterSdkProvider.class); assertThat(openTelemetry.getMeterProvider()).isInstanceOf(MeterSdkProvider.class);
// Since MeterProvider is in a different package, the only alternative to this reflective // Since MeterProvider is in a different package, the only alternative to this reflective

View File

@ -42,8 +42,9 @@ public class TracerSdkProvider implements TracerProvider, TracerSdkManagement {
return new Builder(); return new Builder();
} }
private TracerSdkProvider(Clock clock, IdGenerator idsGenerator, Resource resource) { private TracerSdkProvider(
this.sharedState = new TracerSharedState(clock, idsGenerator, resource); Clock clock, IdGenerator idsGenerator, Resource resource, TraceConfig traceConfig) {
this.sharedState = new TracerSharedState(clock, idsGenerator, resource, traceConfig);
this.tracerSdkComponentRegistry = new TracerSdkComponentRegistry(sharedState); 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. * three required interfaces.
*/ */
public static class Builder { public static class Builder {
@ -100,6 +101,7 @@ public class TracerSdkProvider implements TracerProvider, TracerSdkManagement {
private Clock clock = SystemClock.getInstance(); private Clock clock = SystemClock.getInstance();
private IdGenerator idsGenerator = IdGenerator.random(); private IdGenerator idsGenerator = IdGenerator.random();
private Resource resource = Resource.getDefault(); private Resource resource = Resource.getDefault();
private TraceConfig traceConfig = TraceConfig.getDefault();
/** /**
* Assign a {@link Clock}. * 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() { public TracerSdkProvider build() {
return new TracerSdkProvider(clock, idsGenerator, resource); return new TracerSdkProvider(clock, idsGenerator, resource, traceConfig);
} }
private Builder() {} private Builder() {}

View File

@ -22,17 +22,19 @@ final class TracerSharedState {
// Reads and writes are atomic for reference variables. Use volatile to ensure that these // Reads and writes are atomic for reference variables. Use volatile to ensure that these
// operations are visible on other CPUs as well. // 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 SpanProcessor activeSpanProcessor = NoopSpanProcessor.getInstance();
private volatile boolean isStopped = false; private volatile boolean isStopped = false;
@GuardedBy("lock") @GuardedBy("lock")
private final List<SpanProcessor> registeredSpanProcessors = new ArrayList<>(); private final List<SpanProcessor> registeredSpanProcessors = new ArrayList<>();
TracerSharedState(Clock clock, IdGenerator idGenerator, Resource resource) { TracerSharedState(
Clock clock, IdGenerator idGenerator, Resource resource, TraceConfig traceConfig) {
this.clock = clock; this.clock = clock;
this.idGenerator = idGenerator; this.idGenerator = idGenerator;
this.resource = resource; this.resource = resource;
this.activeTraceConfig = traceConfig;
} }
Clock getClock() { Clock getClock() {

View File

@ -48,10 +48,19 @@ class TracerSdkProviderTest {
.setClock(mock(Clock.class)) .setClock(mock(Clock.class))
.setResource(mock(Resource.class)) .setResource(mock(Resource.class))
.setIdGenerator(mock(IdGenerator.class)) .setIdGenerator(mock(IdGenerator.class))
.setTraceConfig(mock(TraceConfig.class))
.build()) .build())
.isNotNull(); .isNotNull();
} }
@Test
void builder_NullTraceConfig() {
assertThrows(
NullPointerException.class,
() -> TracerSdkProvider.builder().setTraceConfig(null),
"traceConfig");
}
@Test @Test
void builder_NullClock() { void builder_NullClock() {
assertThrows( assertThrows(
@ -107,6 +116,15 @@ class TracerSdkProviderTest {
assertThat(tracerFactory.getActiveTraceConfig()).isEqualTo(newConfig); 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 @Test
void shutdown() { void shutdown() {
tracerFactory.shutdown(); tracerFactory.shutdown();