-
Notifications
You must be signed in to change notification settings - Fork 858
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add SdkTracerProvider.setScopeConfigurator() and support #7021
base: main
Are you sure you want to change the base?
Changes from all commits
fd1e9db
de0778a
1658f53
9a3cfc8
79b639f
01a26f6
16a8248
8e4eebf
6ecd99c
f77f866
cb50085
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,10 +30,9 @@ 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. | ||
private boolean tracerEnabled; | ||
// deliberately not volatile because of performance concerns | ||
// - which means its eventually consistent | ||
protected boolean tracerEnabled; | ||
|
||
SdkTracer( | ||
TracerSharedState sharedState, | ||
|
@@ -79,4 +78,13 @@ public SpanBuilder spanBuilder(String spanName) { | |
InstrumentationScopeInfo getInstrumentationScopeInfo() { | ||
return instrumentationScopeInfo; | ||
} | ||
|
||
// Visible for testing | ||
boolean isEnabled() { | ||
return tracerEnabled; | ||
} | ||
|
||
void updateTracerConfig(TracerConfig tracerConfig) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed a comment on this method which implied it may one day be public, since this class is package private and will stay that way. |
||
this.tracerEnabled = tracerConfig.isEnabled(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
import io.opentelemetry.sdk.internal.ComponentRegistry; | ||
import io.opentelemetry.sdk.internal.ScopeConfigurator; | ||
import io.opentelemetry.sdk.resources.Resource; | ||
import io.opentelemetry.sdk.trace.internal.SdkTracerProviderUtil; | ||
import io.opentelemetry.sdk.trace.internal.TracerConfig; | ||
import io.opentelemetry.sdk.trace.samplers.Sampler; | ||
import java.io.Closeable; | ||
|
@@ -30,7 +31,9 @@ public final class SdkTracerProvider implements TracerProvider, Closeable { | |
static final String DEFAULT_TRACER_NAME = ""; | ||
private final TracerSharedState sharedState; | ||
private final ComponentRegistry<SdkTracer> tracerSdkComponentRegistry; | ||
private final ScopeConfigurator<TracerConfig> tracerConfigurator; | ||
// deliberately not volatile because of performance concerns | ||
// - which means its eventually consistent | ||
private ScopeConfigurator<TracerConfig> tracerConfigurator; | ||
|
||
/** | ||
* Returns a new {@link SdkTracerProviderBuilder} for {@link SdkTracerProvider}. | ||
|
@@ -100,6 +103,25 @@ public Sampler getSampler() { | |
return sharedState.getSampler(); | ||
} | ||
|
||
/** | ||
* Updates the tracer configurator, which computes {@link TracerConfig} for each {@link | ||
* InstrumentationScopeInfo}. | ||
* | ||
* <p>This method is experimental so not public. You may reflectively call it using {@link | ||
* SdkTracerProviderUtil#setTracerConfigurator(SdkTracerProvider, ScopeConfigurator)}. | ||
* | ||
* @see TracerConfig#configuratorBuilder() | ||
*/ | ||
void setTracerConfigurator(ScopeConfigurator<TracerConfig> tracerConfigurator) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated naming to mirror |
||
this.tracerConfigurator = tracerConfigurator; | ||
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. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,6 @@ | |
import io.opentelemetry.api.incubator.trace.ExtendedTracer; | ||
import io.opentelemetry.api.trace.Span; | ||
import io.opentelemetry.api.trace.SpanId; | ||
import io.opentelemetry.api.trace.Tracer; | ||
import io.opentelemetry.context.Scope; | ||
import io.opentelemetry.sdk.common.InstrumentationScopeInfo; | ||
import io.opentelemetry.sdk.internal.ScopeConfigurator; | ||
|
@@ -42,9 +41,13 @@ void disableScopes() throws InterruptedException { | |
.addSpanProcessor(SimpleSpanProcessor.create(exporter)) | ||
.build(); | ||
|
||
Tracer tracerA = tracerProvider.get("tracerA"); | ||
Tracer tracerB = tracerProvider.get("tracerB"); | ||
Tracer tracerC = tracerProvider.get("tracerC"); | ||
ExtendedSdkTracer tracerA = (ExtendedSdkTracer) tracerProvider.get("tracerA"); | ||
ExtendedSdkTracer tracerB = (ExtendedSdkTracer) tracerProvider.get("tracerB"); | ||
ExtendedSdkTracer tracerC = (ExtendedSdkTracer) tracerProvider.get("tracerC"); | ||
|
||
assertThat(tracerA.isEnabled()).isTrue(); | ||
assertThat(tracerB.isEnabled()).isFalse(); | ||
assertThat(tracerC.isEnabled()).isTrue(); | ||
|
||
Span parent; | ||
Span child; | ||
|
@@ -158,4 +161,67 @@ private static Stream<Arguments> tracerConfiguratorArgs() { | |
Arguments.of(enableStartsWithD, scopeDog, enabled()), | ||
Arguments.of(enableStartsWithD, scopeDuck, enabled())); | ||
} | ||
|
||
@Test | ||
void setScopeConfigurator() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. New test to ensure changes reach |
||
// 1. Initially, configure all tracers to be enabled except tracerB | ||
InMemorySpanExporter exporter = InMemorySpanExporter.create(); | ||
SdkTracerProvider tracerProvider = | ||
SdkTracerProvider.builder() | ||
.addTracerConfiguratorCondition(nameEquals("tracerB"), disabled()) | ||
.addSpanProcessor(SimpleSpanProcessor.create(exporter)) | ||
.build(); | ||
|
||
ExtendedSdkTracer tracerA = (ExtendedSdkTracer) tracerProvider.get("tracerA"); | ||
ExtendedSdkTracer tracerB = (ExtendedSdkTracer) tracerProvider.get("tracerB"); | ||
ExtendedSdkTracer tracerC = (ExtendedSdkTracer) tracerProvider.get("tracerC"); | ||
|
||
// verify isEnabled() | ||
assertThat(tracerA.isEnabled()).isTrue(); | ||
assertThat(tracerB.isEnabled()).isFalse(); | ||
assertThat(tracerC.isEnabled()).isTrue(); | ||
|
||
// verify spans are emitted as expected | ||
tracerA.spanBuilder("spanA").startSpan().end(); | ||
tracerB.spanBuilder("spanB").startSpan().end(); | ||
tracerC.spanBuilder("spanC").startSpan().end(); | ||
assertThat(exporter.getFinishedSpanItems()) | ||
.satisfiesExactlyInAnyOrder( | ||
span -> assertThat(span).hasName("spanA"), span -> assertThat(span).hasName("spanC")); | ||
exporter.reset(); | ||
|
||
// 2. Update config to disable all tracers | ||
tracerProvider.setTracerConfigurator( | ||
ScopeConfigurator.<TracerConfig>builder().setDefault(TracerConfig.disabled()).build()); | ||
|
||
// verify isEnabled() | ||
assertThat(tracerA.isEnabled()).isFalse(); | ||
assertThat(tracerB.isEnabled()).isFalse(); | ||
assertThat(tracerC.isEnabled()).isFalse(); | ||
|
||
// verify spans are emitted as expected | ||
tracerA.spanBuilder("spanA").startSpan().end(); | ||
tracerB.spanBuilder("spanB").startSpan().end(); | ||
tracerC.spanBuilder("spanC").startSpan().end(); | ||
assertThat(exporter.getFinishedSpanItems()).isEmpty(); | ||
|
||
// 3. Update config to restore original | ||
tracerProvider.setTracerConfigurator( | ||
ScopeConfigurator.<TracerConfig>builder() | ||
.addCondition(nameEquals("tracerB"), disabled()) | ||
.build()); | ||
|
||
// verify isEnabled() | ||
assertThat(tracerA.isEnabled()).isTrue(); | ||
assertThat(tracerB.isEnabled()).isFalse(); | ||
assertThat(tracerC.isEnabled()).isTrue(); | ||
|
||
// verify spans are emitted as expected | ||
tracerA.spanBuilder("spanA").startSpan().end(); | ||
tracerB.spanBuilder("spanB").startSpan().end(); | ||
tracerC.spanBuilder("spanC").startSpan().end(); | ||
assertThat(exporter.getFinishedSpanItems()) | ||
.satisfiesExactly( | ||
span -> assertThat(span).hasName("spanA"), span -> assertThat(span).hasName("spanC")); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed to make sure the updates are visible to
ExtendedTracer#isEnabled()
. UpdatedSdkTracer.tracerEnabled
to be protected, and removed this field, such thatExtendedSdkTracer#isEnabled()
resolves using the value fromSdkTracer.tracerEnabled
.