views:

486

answers:

3

I have a Rails application which has an action which is invoked frequently enough to be inconvenient when I am developing, as it results in a lot of extra log output I don't care about. How can I get rails not to log anything (controller, action, parameters, complection time, etc.) for just this one action? I'd like to conditionalize it on RAILS_ENV as well, so logs in production are complete.

Thanks!

A: 

Perhaps what you really need to is just filter your log file before you view it? Run it through sed or awk perhaps?

It is probably a bad idea to hide things from the development log.

srboisvert
+1  A: 

You can silence the Rails logger object:

def action
  Rails.logger.silence do
    # Things within this block will not be logged...
  end
end
Josh
That's a generally useful pattern, but ActionController::Base logs stuff before and after the action method executes, so that doesn't solve my particular problem.
archbishop
+2  A: 

The answer turns out to be a lot harder than I expected, since rails really does provide no hook to do this. Instead, you need to wrap some of the guts of ActionController::Base. In the common base class for my controllers, I do

def silent?(action)
  false
end

# this knows more than I'd like about the internals of process, but
# the other options require knowing even more.  It would have been
# nice to be able to use logger.silence, but there isn't a good
# method to hook that around, due to the way benchmarking logs.

def log_processing_with_silence_logs
  if logger && silent?(action_name) then
    @old_logger_level, logger.level = logger.level, Logger::ERROR
  end

  log_processing_without_silence_logs
end

def process_with_silence_logs(request, response, method = :perform_action, *arguments)
  ret = process_without_silence_logs(request, response, method, *arguments)
  if logger && silent?(action_name) then
    logger.level = @old_logger_level
  end
  ret
end

alias_method_chain :log_processing, :silence_logs
alias_method_chain :process, :silence_logs

then, in the controller with the method I want to suppress logging on:

def silent?(action)
  RAILS_ENV == "development" && ['my_noisy_action'].include?(action)
end
archbishop