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.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<SpanProcessor> 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.
*
* <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}.
*/
@ -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();
}

View File

@ -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

View File

@ -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() {}

View File

@ -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<SpanProcessor> 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() {

View File

@ -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();