views:

267

answers:

3

In my rails application, I have a background process runner, model name Worker, that checks for new tasks to run every 10 seconds. This check generates two SQL queries each time - one to look for new jobs, one to delete old completed ones.

The problem with this - the main log file gets spammed for each of those queries.

Can I direct the SQL queries spawned by the Worker model into a separate log file, or at least silence them? Overwriting Worker.logger does not work - it redirects only the messages that explicitly call logger.debug("something").

A: 

Queries are logged at Adapter level as I demonstrated here. http://stackoverflow.com/questions/1090801/how-do-i-get-the-last-sql-query-performed-by-activerecord-in-ruby-on-rails/1091006#1091006

You can't change the behavior unless tweaking the Adapter behavior with some really really horrible hacks.

Simone Carletti
A: 
class Worker < ActiveRecord::Base
  def run
    old_level, self.class.logger.level = self.class.logger.level, Logger::WARN

    run_outstanding_jobs
    remove_obsolete_jobs
  ensure
    self.class.logger.level = old_level
  end
end

This is a fairly familiar idiom. I've seen it many times, in different situations. Of course, if you didn't know that ActiveRecord::Base.logger can be changed like that, it would have been hard to guess.

One caveat of this solution: this changes the logger level for all of ActiveRecord, ActionController, ActionView, ActionMailer and ActiveResource. This is because there is a single Logger instance shared by all modules.

François Beausoleil
+2  A: 

The simplest and most idiomatic solution

logger.silence do
  do_something
end

See Logger#silence

Adam Byrtek
Ended up doing this. Not what I had hoped for, but it does solve the problem.
Toms Mikoss