Class: Flare::WebMarkerSubscriber
- Inherits:
-
Object
- Object
- Flare::WebMarkerSubscriber
- Defined in:
- lib/flare/web_marker_subscriber.rb
Overview
Path 2: ActiveSupport::Notifications subscriber that fires on ‘start_processing.action_controller`, after Rails has routed to a controller#action. At that point the rack server span’s start attributes don’t yet carry code.namespace/code.function – only the ActionPack instrumentation adds them, and Flare::Sampler’s start-time decision (RECORD_ONLY) was already locked in.
The subscriber consults the same sampler’s rule set, finds any whose match_attributes match the now-known controller/action, applies the deterministic trace_id_ratio gate (CAF-1: no rate bypass on Path 2), and on pass calls marker.mark(trace_id, owner_span_id:, rule_id:). FilteringSpanProcessor then forwards every span in the trace to the exporter and unmarks when the owner (this rack span) finishes.
Constant Summary collapse
- NOTIFICATION =
"start_processing.action_controller"
Instance Method Summary collapse
-
#handle(payload, current_span: OpenTelemetry::Trace.current_span) ⇒ Object
Public for tests so they don’t have to drive ActiveSupport::Notifications.
-
#initialize(sampler:, marker:) ⇒ WebMarkerSubscriber
constructor
A new instance of WebMarkerSubscriber.
- #start ⇒ Object
- #stop ⇒ Object
Constructor Details
#initialize(sampler:, marker:) ⇒ WebMarkerSubscriber
Returns a new instance of WebMarkerSubscriber.
22 23 24 25 |
# File 'lib/flare/web_marker_subscriber.rb', line 22 def initialize(sampler:, marker:) @sampler = sampler @marker = marker end |
Instance Method Details
#handle(payload, current_span: OpenTelemetry::Trace.current_span) ⇒ Object
Public for tests so they don’t have to drive ActiveSupport::Notifications. current_span lets tests inject a context; in production it’s the rack server span on the current thread.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/flare/web_marker_subscriber.rb', line 43 def handle(payload, current_span: OpenTelemetry::Trace.current_span) return unless current_span ctx = current_span.context return unless ctx && ctx.valid? attrs = candidate_attributes(payload) return if attrs.empty? @sampler.rules.each do |rule| next unless matches?(rule, attrs) next unless @sampler.trace_id_ratio(ctx.trace_id) < rule.rate current_span.set_attribute(Flare::Sampler::RULE_ID_ATTRIBUTE, rule.id) if current_span.respond_to?(:set_attribute) @marker.mark(ctx.trace_id, owner_span_id: ctx.span_id, rule_id: rule.id) break end end |
#start ⇒ Object
27 28 29 30 31 32 |
# File 'lib/flare/web_marker_subscriber.rb', line 27 def start @subscriber = ActiveSupport::Notifications.subscribe(NOTIFICATION) do |*, payload| handle(payload) end self end |
#stop ⇒ Object
34 35 36 37 38 |
# File 'lib/flare/web_marker_subscriber.rb', line 34 def stop ActiveSupport::Notifications.unsubscribe(@subscriber) if @subscriber @subscriber = nil self end |