310

Is there a way to disable SQL query logging when I'm executing commands in the console? Ideally, it would be great if I can just disable it and re-enable it with a command in the console.

I'm trying to debug something and using "puts" to print out some relevant data. However, the sql query output is making it hard to read.


Edit: I found another solution, since setting the logger to nil sometimes raised an error, if something other than my code tried to call logger.warn

Instead of setting the logger to nil you can set the level of the logger to 1.

ActiveRecord::Base.logger.level = 1 # or Logger::INFO
gylaz
  • 13,221
  • 8
  • 52
  • 58
  • `since setting the logger to nil sometimes raised an error` yap.. I got this one when trying to run `rake db:migrate` http://stackoverflow.com/questions/1719212/undefined-method-info-for-nilnilclass-when-running-active-record-migration – abbood Jun 02 '13 at 11:25
  • 3
    Confirming that this works in Rails 4.1.0 in an initializer. – Amal Chaudhuri Jun 04 '14 at 11:41

10 Answers10

372

To turn it off:

old_logger = ActiveRecord::Base.logger
ActiveRecord::Base.logger = nil

To turn it back on:

ActiveRecord::Base.logger = old_logger
Ryan Bigg
  • 106,965
  • 23
  • 235
  • 261
  • 1
    Is there anywhere I can put this so I disable the SQL output permanently? I tried adding it to envs/dev.rb but not luck. – samvermette Dec 04 '11 at 04:40
  • @samvermette, you don't set it. Just call it from the console before doing your work. – neofetter Jun 11 '12 at 20:53
  • 7
    you can put this code in `.irbrc`, which is basically `.bashrc` for the Rails console. in fact you can do just about anything in `.irbrc` if you want, e.g., syntax coloring, history, edit code in vi and then execute it in the Rails console, etc. check my gem `utility_belt` if you're on Ruby 1.8 or the Ruby 1.9 port called `flyrb` – Giles Bowkett Sep 05 '12 at 03:57
  • 2
    @giles bowkett: Actually, ```.irbrc```is like ```.bashrc``` but actually for your _ruby_ interactive commandline. It's not a rails thing. I imagine you'd probably get errors if you tried to reference rails classes when you were running irb outside of a rails environment. – eremzeit Dec 19 '12 at 12:56
  • 9
    @samvermette you can it in a config file. For example: `config/initializers/activerecord_logger.rb` – Uri Feb 16 '13 at 17:46
  • Just fyi for anyone: after setting `Base.logger`, I also had to run `ActiveRecord::Base.connection_pool.clear_reloadable_connections!` – Kache May 29 '13 at 22:06
  • 22
    `ActiveRecord::Base.logger.level = 1` is a much better answer as it won't raise exceptions if you use .info and others. – Mick F Feb 04 '14 at 16:26
  • I can't +1 this enough. I've came back to this answer so many time I wouldn't be able to count. For some reason I can't seem to remember the syntax correctly :) ... but the sure thing is that it's really helpful to have this answer, so thanks a lot @ryanbigg! – marcgg Jul 31 '14 at 09:18
  • @ryan-- hey is it possible to turn of logging for a specific model ? – pranav prashant Mar 12 '15 at 16:09
  • If you accidentaly ran this code (to turn it off) twice, thus also setting `old_logger` to `nil`, then you may create a new console logger with `ActiveRecord::Base.logger = Logger.new(STDOUT)` when you want to turn it back on again. – Magne Apr 27 '17 at 10:06
  • dirty henry's approach is superior because if you have existing logger.debug statements they will all throw exceptions if you use the accepted answer – jpw Mar 12 '20 at 07:50
96

This might not be a suitable solution for the console, but Rails has a method for this problem: Logger#silence

ActiveRecord::Base.logger.silence do
  # the stuff you want to be silenced
end
Christoph Petschnig
  • 4,047
  • 1
  • 37
  • 46
82

Here's a variation I consider somewhat cleaner, that still allows potential other logging from AR. In config/environments/development.rb :

config.after_initialize do
  ActiveRecord::Base.logger = Rails.logger.clone
  ActiveRecord::Base.logger.level = Logger::INFO
end
jrochkind
  • 22,799
  • 12
  • 59
  • 74
  • Odd, not for me, in Rails 3.0 or 3.1. Why would your Rails.logger be nil in an after_initialize block, did you do something else to customize your Rails init stack, or did you forget the config.after_initialize ? – jrochkind Dec 05 '11 at 05:39
  • 1
    Works great in my Rails 3.1 app. Seemsl ike the nicest solution. +1 – Martijn Mar 22 '12 at 10:41
  • Doesn't work for me ... sets the level OK in the after_initialize block, but the level is back to 0 by the time the console is open. Strange. (I'm using Pry as a console replacement, is that why?) – Mike Blyth Aug 03 '12 at 14:41
27

For Rails 4 you can put the following in an environment file:

# /config/environments/development.rb

config.active_record.logger = nil
Micah
  • 1,676
  • 16
  • 23
  • That would only take effect in production, where logging is mostly surpressed anyway.... – Rob Aug 18 '17 at 17:42
  • in rails 5 this doesn't work. If you're work in linux environment, the following will work: config.active_record.logger = Logger.new('/dev/null') not sure if the same goes with newer version like 6 and 7 – nadavgam Jun 24 '22 at 18:55
16

In case someone wants to actually knock out SQL statement logging (without changing logging level, and while keeping the logging from their AR models):

The line that writes to the log (in Rails 3.2.16, anyway) is the call to debug in lib/active_record/log_subscriber.rb:50.

That debug method is defined by ActiveSupport::LogSubscriber.

So we can knock out the logging by overwriting it like so:

module ActiveSupport
  class LogSubscriber
    def debug(*args, &block)
    end
  end
end
Dorian
  • 22,759
  • 8
  • 120
  • 116
fakeleft
  • 2,830
  • 2
  • 30
  • 32
  • 2
    Good one. This works on SQL logging without affecting `Rails.logger.debug` statements. – Teemu Leisti Mar 03 '15 at 10:27
  • Total noob here. Where exactly should we put this? – devius May 04 '16 at 14:50
  • I keep it in lib/monkeypatch.rb and have rails pull it in with the following line in config/application.rb: `Dir.glob( "./lib/*.{rb}" ).each{ | file | require file }`. Keep in mind that monkeypatching is frowned upon by some. Probably shouldn't check this into your production code. – fakeleft May 06 '16 at 12:57
  • I used this as a starting point for my Rails / ActiveRecord 6 solution, which I've added as an answer here. This version didn't quite work because it actually suppressed a lot of other logs I wanted to see. – Chris R Aug 24 '21 at 16:11
11

I used this: config.log_level = :info edit-in config/environments/performance.rb

Working great for me, rejecting SQL output, and show only rendering and important info.

Nate Ben
  • 626
  • 9
  • 14
  • I'm on rails 4.1.0 and it's worked fine for me. thanks – Zakaria Nov 18 '17 at 06:01
  • Thanks for mentioning this, if put `config.log_level = :fatal` it basically disables output to production log file almost completely, this is what I need since there is a custom request logger in play – Lev Lukomsky Oct 06 '20 at 09:58
4

In Rails 3.2 I'm doing something like this in config/environment/development.rb:

module MyApp
  class Application < Rails::Application
    console do
      ActiveRecord::Base.logger = Logger.new( Rails.root.join("log", "development.log") )
    end
  end
end
Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
Telmo Costa
  • 3,724
  • 1
  • 14
  • 6
4

Just as an FYI, in Rails 2 you can do

ActiveRecord::Base.silence { <code you don't want to log goes here> }

Obviously the curly braces could be replaced with a do end block if you wanted.

Max Williams
  • 32,435
  • 31
  • 130
  • 197
3

I use activerecord 6.0.3.3 and I had to include ActiveSupport::LoggerSilence

include ActiveSupport::LoggerSilence

ActiveSupport::LoggerSilence.silence do
    ## everything you want to silence
end

This however did not work with anything related to creating or deleting SQL tables like ActiveRecord::Migration.drop_table. For this to be silenced I added:

ActiveRecord::Schema.verbose = false
nwnoll
  • 106
  • 1
  • 6
2

I had to solve this for ActiveRecord 6, and I based my answer on fakeleft's response, but it wasn't quite right, since it was suppressing other logging such as the logging of nested views. What I did was created config/initializers/activerecord_logger.rb:

# Suppress SQL statement logging if necessary
# This is a dirty, dirty trick, but it works:
if ENV["ACTIVERECORD_HIDE_SQL"].present?
  module ActiveRecord
    class LogSubscriber
      def sql(event)
      end
    end
  end
end

The log subscriber in AR 6 has a sql event that we want to hide, so this is very narrowly targeted to skip that event.

Chris R
  • 17,546
  • 23
  • 105
  • 172