Silencing the Rails log on a per-action basis

In our current project we are having an action that is polled every ten seconds by the clients. This clutters up the log, so I was looking for a way to completely silence the Rails logger for this action. It turns out that you have to swap the default logger with a custom one, because even when you use the Rails.logger.silence block in your action, you will still find a line in your log that is printed out before the request gets dispatched.

Here’s our custon logging class:

# lib/custom_logger.rb
class CustomLogger < Rails::Rack::Logger
  def initialize(app, opts = {})
    @app = app
    @opts = opts
    @opts[:silenced] ||= []

  def call(env)
    if env['X-SILENCE-LOGGER'] || @opts[:silenced].include?(env['PATH_INFO'])
      Rails.logger.silence do

This way you can either define request paths that should not get logged or send the X-SILENCE-LOGGER header for the request you don’t want to log.

To make use of your own logger, you’ll have to swap the default logger, which is included as a Rack middleware:

# config/application.rb
require File.dirname(__FILE__) + '/../lib/custom_logger.rb'

module MyApp
  class Application < Rails::Application
    # Middlewares
    config.middleware.swap Rails::Rack::Logger, CustomLogger, :silenced => ["/noisy/action.json"]

Updated on February 12th, 2013: Thanks to Andrew Premdas for letting me know that with Rails 3.2.11 one needs to call super in the initialize method.