puts vs logger in rails rake tasks

Put this in application.rb, or in a rake task initialize code

if defined?(Rails) && (Rails.env == 'development')
  Rails.logger = Logger.new(STDOUT)
end

This is Rails 3 code. Note that this will override logging to development.log. If you want both STDOUT and development.log you'll need a wrapper function.

If you'd like this behaviour only in the Rails console, place the same block of code in your ~/.irbrc.


You could create a new rake task to get this to work.

desc "switch logger to stdout"
task :to_stdout => [:environment] do
 Rails.logger = Logger.new(STDOUT)
end

This way when you execute your rake task you can add to_stdout first to get stdout log messages or don't include it to have messages sent to the default log file

rake to_stdout some_task

Rake tasks are run by a user, on a command-line. Anything they need to know right away ("processed 5 rows") should be output on the terminal with puts.

Anything that needs to be kept for posterity ("sent warning email to [email protected]") should be sent to the Rails.logger.


Code

For Rails 4 and newer, you can use Logger broadcast.

If you want to get both STDOUT and file logging for rake tasks in development mode, you can add this code into config/environments/development.rb :

  if File.basename($0) == 'rake'
    # http://stackoverflow.com/questions/2246141/puts-vs-logger-in-rails-rake-tasks
    log_file     = Rails.root.join("log", "#{Rails.env}.log")
    Rails.logger = ActiveSupport::Logger.new(log_file)
    Rails.logger.extend(ActiveSupport::Logger.broadcast(ActiveSupport::Logger.new(STDOUT)))
  end

Test

Here's a small Rake task to test the above code :

# lib/tasks/stdout_and_log.rake
namespace :stdout_and_log do
  desc "Test if Rails.logger outputs to STDOUT and log file"
  task :test => :environment do
    puts "HELLO FROM PUTS"
    Rails.logger.info "HELLO FROM LOGGER"
  end
end

Running rake stdout_and_log:test outputs

HELLO FROM PUTS
HELLO FROM LOGGER

while

HELLO FROM LOGGER

has been added to log/development.log.

Running rake stdout_and_log:test RAILS_ENV=production outputs

HELLO FROM PUTS

while

HELLO FROM LOGGER

has been added to log/production.log.