open-telemetry / open-telemetry/opentelemetry-java
No tracer provider in the OpenTelemetrySdk builder makes the application do a lot of work for spans that will be dropped
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 2.5k
- Forks
- 1k
- Avg merge
- 3d 17h
- Merged PRs (30d)
- 58
Description
Describe the bug
When the tracer provider is not set in the OpenTelemetrySdk builder, spans claim they are recorded, but there is no exporter defined for them.
Therefore, despite appropriately guarding the attribute creation code with if (!span.isRecording()), an application can waste resources generating spans with attributes that will never be exported anyway.
Steps to reproduce
This reduced test case shows the problem:
@Test
public void shouldNotEmitSpansWhenTracingDisabledButLoggingEnabled2() {
// Given
OpenTelemetry openTelemetry = OpenTelemetrySdk.builder().setTracerProvider(null).build();
// Same as OpenTelemetry openTelemetry = OpenTelemetrySdk.builder().build();
// When
Span span = openTelemetry.getTracer("test").spanBuilder("test-span").startSpan();
// Then
assertThat(span.isRecording()).isFalse(); // Fails!
}
Of course our setup code is a bit more complicated: we have a real logger provider, but no tracer provider, and we ended up passing null for the tracer provider.
What did you expect to see?
In the test above, the assertion assertThat(span.isRecording()).isFalse(); should pass. As a result, all the application span code would be a noop.
What did you see instead?
In the test above, the assertion assertThat(span.isRecording()).isFalse(); does not pass. As a result, all the application span code does a lot of useless work.
Workaround
First attempt:
Do the following instead:
SdkTracerProvider noopTracer = SdkTracerProvider.builder().setSampler(alwaysOff()).build();
OpenTelemetry openTelemetry = OpenTelemetrySdk.builder().setTracerProvider(noopTracer).build();
But even that is not optimal, it will run through a lot of code on this line:
openTelemetry.getTracer("test").spanBuilder("test-span").startSpan();
I was hoping I could find a way to setSdkTracer#tracerEnabled to false, but I could not.
I wanted to override SdkTracerProviderBuilder#tracerConfiguratorBuilder, but there is no public API to do so either.
Second attempt:
In the end, the best workaround I found is the following:
SdkTracerProvider noopTracer = SdkTracerProvider.builder().build();
noopTracer.close();
OpenTelemetry openTelemetry = OpenTelemetrySdk.builder().setTracerProvider(noopTracer).build();
This ensures we take one of the fast paths in io.opentelemetry.sdk.trace.SdkTracer#spanBuilder, which returns a NoopSpanBuilder, and then the call to io.opentelemetry.api.trace.SpanBuilder.startSpan does as little as possible, and the returned io.opentelemetry.api.trace.PropagatedSpan isRecording() method returns false.
Which what we want.
Conclusion:
To cut a long story short, the default is surprising, and making it to behave as noop required a surprising amount of work, and it is a bit "heavy". i.e. doing the "right thing" in this case is not exactly trivial.
What version and what artifacts are you using?
io.opentelemetry:opentelemetry-sdk-trace:1.62.0
Environment
Compiler: Amazon Correto 17.0.19
OS: Ubuntu 24.04.4 LTS
Additional context
n/a
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the reduced test for OpenTelemetrySdk.builder().build() and inspect SdkTracer#spanBuilder, including the NoopSpanBuilder fast path described in the report. Trace how a missing tracer provider affects Span.isRecording(), then add a regression test that verifies spans are no-ops and application span work is avoided when tracing is not configured.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- observability
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100