diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java index 0238d897907..d2527061954 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracer.java @@ -30,9 +30,8 @@ class SdkTracer implements Tracer { private final TracerSharedState sharedState; private final InstrumentationScopeInfo instrumentationScopeInfo; - - // TODO: add dedicated API for updating scope config. - @SuppressWarnings("FieldCanBeFinal") // For now, allow updating reflectively. + // deliberately not volatile because of performance concerns + // - which means its eventually consistent private boolean tracerEnabled; SdkTracer( @@ -79,4 +78,15 @@ public SpanBuilder spanBuilder(String spanName) { InstrumentationScopeInfo getInstrumentationScopeInfo() { return instrumentationScopeInfo; } + + // Visible for testing + boolean isEnabled() { + return tracerEnabled; + } + + // currently not public as experimental + void updateTracerConfig(TracerConfig tracerConfig) { + this.tracerEnabled = tracerConfig.isEnabled(); + } + } diff --git a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java index 14ccc37c41f..5d70bee0e36 100644 --- a/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java +++ b/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/SdkTracerProvider.java @@ -30,7 +30,9 @@ public final class SdkTracerProvider implements TracerProvider, Closeable { static final String DEFAULT_TRACER_NAME = ""; private final TracerSharedState sharedState; private final ComponentRegistry tracerSdkComponentRegistry; - private final ScopeConfigurator tracerConfigurator; + // deliberately not volatile because of performance concerns + // - which means its eventually consistent + private ScopeConfigurator tracerConfigurator; /** * Returns a new {@link SdkTracerProviderBuilder} for {@link SdkTracerProvider}. @@ -100,6 +102,17 @@ public Sampler getSampler() { return sharedState.getSampler(); } + // currently not public as experimental + void setScopeConfigurator(ScopeConfigurator scopeConfigurator) { + this.tracerConfigurator = scopeConfigurator; + this.tracerSdkComponentRegistry + .getComponents() + .forEach( + sdkTracer -> + sdkTracer.updateTracerConfig( + getTracerConfig(sdkTracer.getInstrumentationScopeInfo()))); + } + /** * Attempts to stop all the activity for {@link Tracer}s created by this provider. Calls {@link * SpanProcessor#shutdown()} for all registered {@link SpanProcessor}s. diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java index 44f75373cb1..923ad31f4cf 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerProviderTest.java @@ -184,6 +184,21 @@ void propagatesInstrumentationScopeInfoToTracer() { assertThat(((SdkTracer) tracer).getInstrumentationScopeInfo()).isEqualTo(expected); } + @Test + void propagatesEnablementToTracer() { + final SdkTracer tracer = tracerFactory.get("test"); + final boolean isEnabled = tracer.isEnabled(); + ScopeConfigurator flipConfigurator = new ScopeConfigurator() { + @Override + public TracerConfig apply(InstrumentationScopeInfo scopeInfo) { + return isEnabled ? TracerConfig.disabled() : TracerConfig.enabled(); + } + } + //all in the same thread, so should see enablement change immediately + tracerFactory.setScopeConfigurator(flipConfigurator); + assertThat(tracer.isEnabled()).isEqualTo(!isEnabled); + } + @Test void build_SpanLimits() { SpanLimits initialSpanLimits = SpanLimits.builder().build(); diff --git a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerTest.java b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerTest.java index c17c121a36e..b98f7caf1f9 100644 --- a/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerTest.java +++ b/sdk/trace/src/test/java/io/opentelemetry/sdk/trace/SdkTracerTest.java @@ -50,6 +50,14 @@ void getInstrumentationScopeInfo() { assertThat(tracer.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo); } + @Test + void updateEnabled() { + tracer.updateTracerConfig(TracerConfig.disabled()); + assertThat(tracer.isEnabled()).isFalse(); + tracer.updateTracerConfig(TracerConfig.enabled()); + assertThat(tracer.isEnabled()).isTrue(); + } + @Test void propagatesInstrumentationScopeInfoToSpan() { ReadableSpan readableSpan = (ReadableSpan) tracer.spanBuilder("spanName").startSpan();