Default sampler behavior changes in OpenTelemetry Java SDK v1.20.0-v1.24.0 affecting trace completeness
0 reputation · 31 May 2023, 21:59 UTC
0 reputation · 31 May 2023, 21:59 UTC
The OpenTelemetry Java SDK underwent a significant change in default sampler behavior between versions 1.20.0 and 1.24.0. Applications deployed in production environments without explicitly configuring a sampler may experience unexpected changes in trace completeness and sampling rates.
This behavior shift represents a breaking change for applications that previously relied on undocumented default sampling behavior. The change affects how traces are sampled and exported, potentially impacting observability and debugging capabilities in production systems.
Key concerns include: applications with implicit sampler dependencies may lose trace data; migration requires explicit sampler configuration; version-specific behavior differences complicate upgrade paths; default settings may not align with production observability requirements.
Which default sampler should be explicitly configured to maintain consistent trace completeness across SDK versions v1.20.0 through v1.24.0, and what configuration approach ensures production-ready sampling behavior without relying on undocumented defaults?
32275 reputation · 01 Jun 2023, 06:06 UTC
To keep trace completeness consistent across SDK versions 1.20.0 to 1.24.0, you must explicitly set the sampler when initializing the SDK. The default changed to ParentBased(AlwaysOnSampler), which can drop root spans if the parent is not sampled. By overriding this default you avoid the breaking change.
Samplers.alwaysOn() – The AlwaysOnSampler exports every span, guaranteeing full trace data at the cost of higher data volume.ParentBasedSampler.builder(Samplers.alwaysOn()).build() – A parent‑based sampler that still ensures root spans are never dropped, preserving parent‑child relationships while sampling all traces.import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.samplers.Samplers;
import io.opentelemetry.sdk.trace.samplers.ParentBasedSampler;
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
.setSampler(Samplers.alwaysOn()) // or ParentBasedSampler.builder(Samplers.alwaysOn()).build()
.addSpanProcessor(SimpleSpanProcessor.create(exporter))
.build();
OpenTelemetrySdk.builder()
.setTracerProvider(tracerProvider)
.buildAndRegisterGlobal();
log4j.level=DEBUG for io.opentelemetry.sdk) and confirm that the sampler decision is logged for each span.TraceIdRatioBased) and adjust the sampling rate.Do you need to limit the number of exported spans in production to control data volume, or is full trace export acceptable? This will influence whether to keep AlwaysOnSampler or switch to a rate‑based sampler.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.