Class: Tracelit::ErrorAlwaysOnSampler
- Inherits:
-
Object
- Object
- Tracelit::ErrorAlwaysOnSampler
- Defined in:
- lib/tracelit/error_always_on_sampler.rb
Overview
ErrorAlwaysOnSampler wraps a ratio-based sampler but upgrades DROP decisions to RECORD_ONLY. This ensures span processors (including ErrorSpanProcessor) fire on_end for ALL spans, even those outside the sampling ratio.
Without this, TraceIdRatioBased(0.0) returns DROP, which causes the SDK to create NonRecordingSpans that bypass the processor pipeline entirely — so ErrorSpanProcessor.on_end is never called.
With RECORD_ONLY:
-
Real spans are created and all processors fire
-
BatchSpanProcessor ignores them (checks trace_flags.sampled? == false)
-
ErrorSpanProcessor sees them and exports any that end in ERROR
Constant Summary collapse
- Decision =
OpenTelemetry::SDK::Trace::Samplers::Decision
- Result =
OpenTelemetry::SDK::Trace::Samplers::Result
Instance Method Summary collapse
- #description ⇒ Object
-
#initialize(rate) ⇒ ErrorAlwaysOnSampler
constructor
A new instance of ErrorAlwaysOnSampler.
- #should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:) ⇒ Boolean
Constructor Details
#initialize(rate) ⇒ ErrorAlwaysOnSampler
Returns a new instance of ErrorAlwaysOnSampler.
21 22 23 |
# File 'lib/tracelit/error_always_on_sampler.rb', line 21 def initialize(rate) @inner = OpenTelemetry::SDK::Trace::Samplers.trace_id_ratio_based(rate) end |
Instance Method Details
#description ⇒ Object
43 44 45 |
# File 'lib/tracelit/error_always_on_sampler.rb', line 43 def description "ErrorAlwaysOnSampler{#{@inner.description}}" end |
#should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:) ⇒ Boolean
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/tracelit/error_always_on_sampler.rb', line 25 def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:) result = @inner.should_sample?( trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes ) if result.recording? result else # Upgrade DROP → RECORD_ONLY so processor pipeline fires Result.new(decision: Decision::RECORD_ONLY, tracestate: result.tracestate) end end |