Class: ActiveSanction::Instrumentation::Notifications
- Inherits:
-
Object
- Object
- ActiveSanction::Instrumentation::Notifications
- Extended by:
- T::Sig
- Defined in:
- lib/active_sanction/instrumentation/notifications.rb
Overview
Republishes every event into ActiveSupport::Notifications, for a host
that already has subscribers, log tags and a dashboard pointed there.
# config/initializers/active_sanction.rb
ActiveSanction.configure do |c|
c.instrumenter = ActiveSanction::Instrumentation::Notifications.new
end
ActiveSupport::Notifications.subscribe("screen.active_sanction") do |event|
Rails.logger.info("screened in #{event.duration.round(1)}ms: #{event.payload[:results]} hits")
end
Names are <event>.active_sanction -- fetch.active_sanction,
index.build.active_sanction, and so on -- which is the namespacing
convention every ActiveSupport subscriber already expects, so
subscribe(/\.active_sanction\z/) picks up all six.
It is an adapter, not a dependency
Nothing in this gem requires ActiveSupport, and this file does not
either -- it names ::ActiveSupport::Notifications and never loads it.
Zero required runtime dependencies is a promise this library keeps for
the API container it is going to run in, and a notification adapter is
not a reason to break it. Building one in a process that has not loaded
ActiveSupport raises ConfigurationError rather than quietly instrumenting
nothing, because a subscriber that is not recording is a dashboard that
is wrong rather than missing.
Events arrive finished
publish rather than instrument: this library has already done the
work and timed it, and re-wrapping a finished event in a block would put
an ActiveSupport subscriber around a stage it cannot influence while
reporting a duration measured somewhere else. Subscribers see a normal
ActiveSupport::Notifications::Event with real start and finish times.
A stage that raised carries the two keys ActiveSupport's own subscribers
look for -- :exception, the [class, message] pair, and
:exception_object -- beside this library's :error, so a Rails host's
existing error reporting sees it without being taught anything.
Constant Summary collapse
- NAMESPACE =
The suffix every published name carries.
T.let("active_sanction", String)
Instance Attribute Summary collapse
- #namespace ⇒ String readonly
-
#notifier ⇒ T.untyped
readonly
Whatever the events are published through --
ActiveSupport::Notificationsitself unless a host named its own notifier.
Instance Method Summary collapse
-
#call(event) ⇒ T.untyped
Publishes one finished event.
- #initialize(namespace: NAMESPACE, notifier: nil) ⇒ void constructor
- #inspect ⇒ String
Constructor Details
#initialize(namespace: NAMESPACE, notifier: nil) ⇒ void
70 71 72 73 74 75 76 77 |
# File 'lib/active_sanction/instrumentation/notifications.rb', line 70 def initialize(namespace: NAMESPACE, notifier: nil) @namespace = T.let(namespace.to_s, String) @notifier = T.let(notifier || default_notifier, T.untyped) return if @notifier.respond_to?(:publish) raise ConfigurationError, "an ActiveSupport::Notifications adapter needs a notifier answering " \ "#publish, got #{@notifier.class}" end |
Instance Attribute Details
#namespace ⇒ String (readonly)
57 58 59 |
# File 'lib/active_sanction/instrumentation/notifications.rb', line 57 def namespace @namespace end |
#notifier ⇒ T.untyped (readonly)
Whatever the events are published through -- ActiveSupport::Notifications
itself unless a host named its own notifier.
62 63 64 |
# File 'lib/active_sanction/instrumentation/notifications.rb', line 62 def notifier @notifier end |
Instance Method Details
#call(event) ⇒ T.untyped
Publishes one finished event. Called by Instrumentation, which has already isolated it: an exception raised in here is reported and dropped rather than reaching the sync that emitted the event.
83 84 85 86 |
# File 'lib/active_sanction/instrumentation/notifications.rb', line 83 def call(event) notifier.publish("#{event.name}.#{namespace}", event.started_at, event.finished_at, event_id, payload_for(event)) end |
#inspect ⇒ String
89 |
# File 'lib/active_sanction/instrumentation/notifications.rb', line 89 def inspect = "#<#{self.class} #{notifier.class} *.#{namespace}>" |