Module: Koderift::Rails::Instrumentation
- Defined in:
- lib/koderift/rails/instrumentation.rb
Class Method Summary collapse
-
.capture ⇒ Object
Subscribes to Rails notifications during a request to capture partial render times, SQL query times, and breadcrumbs.
- .rails_root_prefix ⇒ Object
Class Method Details
.capture ⇒ Object
Subscribes to Rails notifications during a request to capture partial render times, SQL query times, and breadcrumbs. Returns a hash of captured data to be merged into the log payload.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 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 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/koderift/rails/instrumentation.rb', line 12 def self.capture partials = [] queries = [] search_queries = [] = [] config = Koderift::Rails.configuration partial_sub = ActiveSupport::Notifications.subscribe('render_partial.action_view') do |*args| event = ActiveSupport::Notifications::Event.new(*args) payload = event.payload duration = (payload[:duration] || event.duration).round identifier = payload[:identifier].to_s .sub(rails_root_prefix, '') .sub(%r{\A/app/views/}, '') partials << { partial: identifier, duration_ms: duration } << { type: 'render', message: identifier, duration_ms: duration, timestamp: Time.now.utc.iso8601 } end query_sub = ActiveSupport::Notifications.subscribe('sql.active_record') do |*args| event = ActiveSupport::Notifications::Event.new(*args) payload = event.payload next if payload[:name].to_s.match?(/\A(CACHE|SCHEMA)/) duration = (payload[:duration] || event.duration).round sql = payload[:sql].to_s.squish.truncate(300) queries << { sql: sql, duration_ms: duration } << { type: 'sql', message: sql, duration_ms: duration, timestamp: Time.now.utc.iso8601 } end # Single-model search: fired by Model.search(...) # payload: { name: "Admin10 Search", query: {...} } search_sub = ActiveSupport::Notifications.subscribe('search.searchkick') do |*args| event = ActiveSupport::Notifications::Event.new(*args) payload = event.payload duration = (payload[:duration] || event.duration).round index = payload[:name].to_s.sub(/\s*Search\z/i, '').strip index = 'unknown' if index.blank? search_queries << { index: index, duration_ms: duration } end # Multi search: fired by Searchkick.multi_search([...]) # payload: { name: "Multi Search", body: "..." } # Duration covers the entire batch — record as a single entry. multi_search_sub = ActiveSupport::Notifications.subscribe('multi_search.searchkick') do |*args| event = ActiveSupport::Notifications::Event.new(*args) duration = event.duration.round search_queries << { index: 'multi_search', duration_ms: duration } end external_calls = [] Thread.current[:koderift_external_calls] = external_calls Thread.current[:koderift_external_config] = config begin yield ensure ActiveSupport::Notifications.unsubscribe(partial_sub) ActiveSupport::Notifications.unsubscribe(query_sub) ActiveSupport::Notifications.unsubscribe(search_sub) ActiveSupport::Notifications.unsubscribe(multi_search_sub) Thread.current[:koderift_external_calls] = nil Thread.current[:koderift_external_config] = nil end spans = [] partials.each_with_index do |p, i| spans << { type: 'partial', name: p[:partial], duration_ms: p[:duration_ms], sequence: i } end queries.each_with_index do |q, i| spans << { type: 'sql', name: q[:sql], duration_ms: q[:duration_ms], sequence: i } end search_queries.each_with_index do |s, i| spans << { type: 'search', name: s[:index], duration_ms: s[:duration_ms], sequence: i } end external_calls.each_with_index do |c, i| spans << { type: 'http', name: "#{c[:host]}#{c[:endpoint]}", duration_ms: c[:duration_ms], detail: { method: c[:method], status: c[:status], trace_id: c[:trace_id] }.compact.to_json, sequence: i } end { spans: spans, query_count: queries.size, partial_count: partials.size, search_count: search_queries.size, breadcrumbs: .last(config.) } end |
.rails_root_prefix ⇒ Object
124 125 126 |
# File 'lib/koderift/rails/instrumentation.rb', line 124 def self.rails_root_prefix defined?(::Rails) && ::Rails.respond_to?(:root) && ::Rails.root ? ::Rails.root.to_s : '' end |