require 'active_record/log_subscriber' class SlowQueryLog < ActiveSupport::LogSubscriber if Rails.configuration.respond_to?(:slow_query_log_threshold_in_ms) if @@threshold = Rails.configuration.slow_query_log_threshold_in_ms @@threshold = @@threshold.to_i == 0 ? nil : @@threshold.to_i end else @@threshold = nil end def sql(event) return unless duration_ms = event.duration return if ! @@threshold || @@threshold > duration_ms payload = event.payload; name = payload[:name] return if name.eql? 'EXPLAIN'; return if name.eql? 'SCHEMA' if ( binds = payload[:binds] ) && ! binds.empty? binds = " #{binds.map { |col,v| render_bind(col, v) }.inspect}" end log "#{name} (#{event.duration.round(1)}ms) #{payload[:sql]}#{binds}" end def log(msg) logger = ActiveRecord::Base.logger logger && logger.warn("[slow-query] #{msg}") end private def render_bind(column, value) # from ActiveRecord::LogSubscriber return [nil, value] unless column if column.binary? value = value[:value] if value.is_a?(Hash) value = value ? "<#{value.bytesize} bytes of binary data>" : "" end [column.name, value] end end SlowQueryLog.attach_to :active_record