lib/prosopite.rb in prosopite-0.1.4 vs lib/prosopite.rb in prosopite-0.1.5

- old
+ new

@@ -8,28 +8,38 @@ :rails_logger, :prosopite_logger, :whitelist def scan + @scan ||= false return if scan? + subscribe @query_counter = Hash.new(0) @query_holder = Hash.new { |h, k| h[k] = [] } @query_caller = {} @whitelist ||= [] + @scan = true end def scan? @scan end def finish return unless scan? + @scan = false + + create_notifications + send_notifications if @notifications.present? + end + + def create_notifications @notifications = {} @query_counter.each do |location_key, count| if count > 1 fingerprints = @query_holder[location_key].map do |q| @@ -49,23 +59,24 @@ @notifications[queries] = kaller end end end end + end - @scan = false - Prosopite.send_notifications if @notifications.present? + def fingerprint(query) + if ActiveRecord::Base.connection.adapter_name.downcase.include?('mysql') + mysql_fingerprint(query) + else + PgQuery.fingerprint(query) + end end # Many thanks to https://github.com/genkami/fluent-plugin-query-fingerprint/ - def fingerprint(query) + def mysql_fingerprint(query) query = query.dup - unless ActiveRecord::Base.connection.adapter_name.downcase.include?('mysql') - return PgQuery.fingerprint(query) - end - return "mysqldump" if query =~ %r#\ASELECT /\*!40001 SQL_NO_CACHE \*/ \* FROM `# return "percona-toolkit" if query =~ %r#\*\w+\.\w+:[0-9]/[0-9]\*/# if match = /\A\s*(call\s+\S+)\(/i.match(query) return match.captures.first.downcase! end @@ -106,10 +117,15 @@ query end def send_notifications + @rails_logger ||= false + @stderr_logger ||= false + @prosopite_logger ||= false + @raise ||= false + notifications_str = '' @notifications.each do |queries, kaller| notifications_str << "N+1 queries detected:\n" queries.each { |q| notifications_str << " #{q}\n" } @@ -131,12 +147,12 @@ raise NPlusOneQueriesError.new(notifications_str) if @raise end def subscribe + @subscribed ||= false return if @subscribed - @subscribed = true ActiveSupport::Notifications.subscribe 'sql.active_record' do |_, _, _, _, data| sql = data[:sql] if scan? && sql.include?('SELECT') && data[:cached].nil? @@ -148,8 +164,10 @@ if @query_counter[location_key] > 1 @query_caller[location_key] = caller.dup end end end + + @subscribed = true end end end