Class: RailsOtelContext::ActiveRecordContext::Subscriber

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_otel_context/activerecord_context.rb

Overview

Subscriber for sql.active_record notifications.

Instance Method Summary collapse

Instance Method Details

#finish(_name, _id, _payload) ⇒ Object



114
115
116
117
# File 'lib/rails_otel_context/activerecord_context.rb', line 114

def finish(_name, _id, _payload)
ensure
  Thread.current[THREAD_KEY] = nil
end

#start(_name, _id, payload) ⇒ Object



82
83
84
85
86
87
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
# File 'lib/rails_otel_context/activerecord_context.rb', line 82

def start(_name, _id, payload)
  ar_name = payload[:name]
  return if ar_name == 'SCHEMA' || ar_name&.start_with?('CACHE')

  ctx = if ar_name.nil? || 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

  # 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