Class: Flare::WebMarkerSubscriber

Inherits:
Object
  • Object
show all
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

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

#startObject



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

#stopObject



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