Module: Pinot::Instrumentation
- Defined in:
- lib/pinot/instrumentation.rb
Overview
Low-level instrumentation hook that fires after every query executed via Connection#execute_sql. This is the extension point used by Pinot::ActiveSupportNotifications, Pinot::OpenTelemetry, and any custom observability layer.
Subscribing (multiple listeners supported)
listener = Pinot::Instrumentation.subscribe(->(event) do
MyMetrics.record(event[:table], event[:duration_ms], event[:success])
end)
# Remove later:
Pinot::Instrumentation.unsubscribe(listener)
Legacy single-callback API (still supported)
Pinot::Instrumentation.on_query = ->(event) { ... }
Pinot::Instrumentation.on_query = nil # remove
Around-execution hook (for OTel and similar span-based tools)
The ‘around` hook wraps the entire query execution — the block yields the query, and the hook is responsible for calling Instrumentation.notify when done. Only one around hook can be registered at a time.
Pinot::Instrumentation.around = ->(table:, query:) do
MyTracer.in_span("pinot") { yield }
end
Event Hash keys
:table => String — table name passed to execute_sql
:query => String — SQL string
:duration_ms => Float — wall-clock time in milliseconds
:success => Boolean — false when an exception was raised
:error => Exception or nil — the exception on failure, nil on success
Class Method Summary collapse
- .around ⇒ Object
-
.around=(wrapper) ⇒ Object
Register an around-execution wrapper.
- .instrument(table:, query:) ⇒ Object
-
.notify(event) ⇒ Object
Fire all registered listeners with an event hash.
-
.on_query ⇒ Object
Returns the first registered listener (legacy compat).
-
.on_query=(callback) ⇒ Object
Legacy single-callback setter.
-
.subscribe(listener) ⇒ Object
Add a post-execution listener.
-
.unsubscribe(listener) ⇒ Object
Remove a previously subscribed listener.
Class Method Details
.around ⇒ Object
60 61 62 |
# File 'lib/pinot/instrumentation.rb', line 60 def self.around @around end |
.around=(wrapper) ⇒ Object
Register an around-execution wrapper. Only one wrapper is supported; the new value replaces any previous one. Set to nil to remove.
56 57 58 |
# File 'lib/pinot/instrumentation.rb', line 56 def self.around=(wrapper) @around = wrapper end |
.instrument(table:, query:) ⇒ Object
75 76 77 78 79 80 81 |
# File 'lib/pinot/instrumentation.rb', line 75 def self.instrument(table:, query:) if @around @around.call(table: table, query: query) { yield } else _timed_instrument(table: table, query: query) { yield } end end |
.notify(event) ⇒ Object
Fire all registered listeners with an event hash. Called by the default instrument path and by the OTel around wrapper.
85 86 87 |
# File 'lib/pinot/instrumentation.rb', line 85 def self.notify(event) @listeners.each { |l| l.call(event) } end |
.on_query ⇒ Object
Returns the first registered listener (legacy compat).
71 72 73 |
# File 'lib/pinot/instrumentation.rb', line 71 def self.on_query @listeners.first end |
.on_query=(callback) ⇒ Object
Legacy single-callback setter. Replaces all listeners with the given callback (or clears them when nil).
66 67 68 |
# File 'lib/pinot/instrumentation.rb', line 66 def self.on_query=(callback) @listeners = callback ? [callback] : [] end |
.subscribe(listener) ⇒ Object
Add a post-execution listener. Returns the listener so it can be passed to unsubscribe later.
44 45 46 47 |
# File 'lib/pinot/instrumentation.rb', line 44 def self.subscribe(listener) @listeners << listener listener end |
.unsubscribe(listener) ⇒ Object
Remove a previously subscribed listener.
50 51 52 |
# File 'lib/pinot/instrumentation.rb', line 50 def self.unsubscribe(listener) @listeners.delete(listener) end |