Class: RailsOtelContext::ActiveRecordContext::Subscriber
- Inherits:
-
Object
- Object
- RailsOtelContext::ActiveRecordContext::Subscriber
- Defined in:
- lib/rails_otel_context/activerecord_context.rb
Overview
Subscriber for sql.active_record notifications.
Instance Method Summary collapse
- #finish(_name, id, _payload) ⇒ Object
-
#initialize ⇒ Subscriber
constructor
A new instance of Subscriber.
- #start(_name, id, payload) ⇒ Object
Constructor Details
#initialize ⇒ Subscriber
Returns a new instance of Subscriber.
84 85 86 |
# File 'lib/rails_otel_context/activerecord_context.rb', line 84 def initialize @threshold = RailsOtelContext.configuration.slow_query_threshold_ms end |
Instance Method Details
#finish(_name, id, _payload) ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/rails_otel_context/activerecord_context.rb', line 126 def finish(_name, id, _payload) if @threshold && Thread.current[TIMING_ID_KEY].equal?(id) elapsed_ms = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - Thread.current[TIMING_START_KEY]) * 1000 Thread.current[TIMING_ID_KEY] = nil if elapsed_ms >= @threshold span = OpenTelemetry::Trace.current_span span.set_attribute(DB_SLOW_ATTR, true) if span.context.valid? end end ensure Thread.current[THREAD_KEY] = nil end |
#start(_name, id, payload) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/rails_otel_context/activerecord_context.rb', line 88 def start(_name, id, payload) ar_name = payload[:name] return unless ar_name return if ar_name == 'SCHEMA' || ar_name.start_with?('CACHE') ctx = if ar_name == 'SQL' ActiveRecordContext.parse_sql_context(payload[:sql]) else ActiveRecordContext.parse_ar_name(ar_name) end return unless ctx # Include scope name if one was captured by RelationScopeCapture scope = Thread.current[SCOPE_THREAD_KEY] ctx[:scope_name] = scope if scope query_key = ctx[:query_key] counts = (Thread.current[RequestContext::QUERY_COUNT_KEY] ||= {}) count = (counts[query_key] = (counts[query_key] || 0) + 1) ctx[:query_count] = count if count > 1 ctx[:async] = true if payload[:async] Thread.current[THREAD_KEY] = ctx if @threshold Thread.current[TIMING_ID_KEY] = id Thread.current[TIMING_START_KEY] = Process.clock_gettime(Process::CLOCK_MONOTONIC) end # Enrich the current span directly. When OTel instruments via driver-level # prepend (Trilogy, PG, Mysql2), the span is created BEFORE this notification # fires, so CallContextProcessor#on_start sees nil AR context. Applying here # fixes those spans after the fact. return unless defined?(OpenTelemetry::Trace) ActiveRecordContext.apply_to_span(OpenTelemetry::Trace.current_span, ctx) end |