How can I disable logging in Ruby on Rails on a pe

2019-01-11 05:54发布

问题:

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!

回答1:

You can silence the Rails logger object:

def action
  Rails.logger.silence do
    # Things within this block will not be logged...
  end
end


回答2:

The following works with at least Rails 3.1.0:

Make a custom logger that can be silenced:

# selective_logger.rb
class SelectiveLogger < Rails::Rack::Logger

  def initialize  app, opts = {}
    @app = app
    @opts = opts
    @opts[:silenced] ||= []
  end

  def call  env
    if @opts[:silenced].include?(env['PATH_INFO']) || @opts[:silenced].any? {|silencer| silencer.is_a?( Regexp) && silencer.match( env['PATH_INFO']) }
      Rails.logger.silence do
        @app.call env
      end
    else
      super env
    end                        
  end

end

Tell Rails to use it:

# application.rb
config.middleware.swap Rails::Rack::Logger, SelectiveLogger, :silenced => ["/remote/every_minute", %r"^/assets/"]

The example above shows silencing asset serving requests, which in the development environment means less ( and sometimes no) scrolling back is required to see the actual request.



回答3:

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


回答4:

Use lograge gem.

Gemfile:

gem 'lograge'

config/application.rb

config.lograge.enabled = true
config.lograge.ignore_actions = ['StatusController#nginx', ...]


回答5:

You can add the gem to the Gemfile silencer.

gem 'silencer', '>= 1.0.1'

And in your config/initializers/silencer.rb :

  require 'silencer/logger'

  Rails.application.configure do
    config.middleware.swap Rails::Rack::Logger, Silencer::Logger, silence: ['/api/notifications']
  end


回答6:

The following works with Rails 2.3.14:

Make a custom logger that can be silenced:

#selective_logger.rb  
require "active_support"

class SelectiveLogger < ActiveSupport::BufferedLogger

  attr_accessor :silent

  def initialize path_to_log_file
    super path_to_log_file
  end

  def add severity, message = nil, progname = nil, &block
    super unless @silent
  end
end

Tell Rails to use it:

#environment.rb
  config.logger = SelectiveLogger.new  config.log_path

Intercept the log output at the beginning of each action and (re)configure the logger depending on whether the action should be silent or not:

#application_controller.rb
  # This method is invoked in order to log the lines that begin "Processing..."
  # for each new request.
  def log_processing
    logger.silent = %w"ping time_zone_table".include? params[:action]
    super
  end