Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I keep log messages out of STDOUT when running Rake tasks on Heroku?

I have some Rake tasks that produce CSV output which I'd like to redirect to a file and open with other tools, but when I run heroku rake foo > foo.csv I get log messages (SQL queries, etc.) in my output.

I've tried Rails.logger = Logger.new('/dev/null') and Rails.logger = Logger.new(STDERR) at the top of the Rake task and while those function as expected locally, they don't have any noticeable effect when I run the task on Heroku.

I'm not too shocked that Heroku would squash STDOUT and STDERR together but it's a mystery to me why sending to /dev/null would not kill the output.

Any help greatly appreciated.

Rails v3.0.0, Heroku bamboo-ree-1.8.7 stack, rake 0.9.2.

like image 436
camdez Avatar asked Nov 18 '25 09:11

camdez


2 Answers

I was having the same problem, though I didn't run into it until I changed config/environments/production.rb to have this:

  config.logger = Logger.new(STDOUT)

(I did this so that my app would log to the heroku log.)

My fix was this:

config.logger = Logger.new(STDOUT) unless 'rake' == File.basename($0)
like image 126
Matt Burke Avatar answered Nov 20 '25 02:11

Matt Burke


From Heroku | Dev Center | Logging:

When a Rails app is pushed, we will automatically install the rails_log_stdout plugin into the application which will redirect logs to stdout.

I think Heroku includes (in the output sent through your git push command) a notification about this (and one other addition: for serving static/public content, if I remember correctly). You may only see the notifications for certain kinds of pushes though (complete slug rebuilds?). I remember seeing it when I recently pushed a new application to a Bamboo/MRI-1.9.2 stack, but I do not think I got the message every time I pushed changes to just the application’s code (maybe adding a new gem to the Gemfile is enough to trigger it?).


Several Rails subsystems keep their own logger binding (independent bindings whose values are often initialized from Rails.logger; reassigning the latter does not change the former):

  • ActiveRecord::Base.logger
  • ActionController::Base.logger
  • ActionMailer::Base.logger

Heroku’s changes probably set a new value for Rails.logger before ActiveRecord is initialized. When ActiveRecord is eventually loaded, it sets its own logger to be the same as Rails.logger (the Heroku/stdout one). When your task runs, it reassigns Rails.logger, but it is too late for this to have any effect on ActiveRecord::Base.logger (the only most likely to be handling the SQL logs).

You probably need to reassign some of these other logger bindings to squelch the logging going to STDOUT. Some other likely locations are listed in rails_log_stdout’s init.rb in the Rails 2 section.

like image 36
Chris Johnsen Avatar answered Nov 20 '25 04:11

Chris Johnsen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!