如何在每个操作的基础上禁用Ruby on Rails中的日志记录?

arc*_*hop 37 logging conditional action ruby-on-rails

我有一个Rails应用程序,它有一个经常被调用的动作,在我开发时很不方便,因为它导致了很多额外的日志输出我不关心.如何才能让rails不记录任何内容(控制器,动作,参数,计算时间等)?我也想在RAILS_ENV上对其进行条件化,因此生产中的日志已经完成.

谢谢!

Jos*_*man 16

您可以使Rails记录器对象静音:

def action
  Rails.logger.silence do
    # Things within this block will not be logged...
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 这是一个普遍有用的模式,但ActionController :: Base会记录action方法执行之前和之后的内容,因此这不能解决我的特定问题. (5认同)
  • 这会在 Rails 3 中引发弃用警告。您可以使用“silence do ... end”代替 (2认同)

小智 10

以下适用于至少Rails 3.1.0:

制作可以沉默的自定义记录器:

# 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
Run Code Online (Sandbox Code Playgroud)

告诉Rails使用它:

# application.rb
config.middleware.swap Rails::Rack::Logger, SelectiveLogger, :silenced => ["/remote/every_minute", %r"^/assets/"]
Run Code Online (Sandbox Code Playgroud)

上面的示例显示了静默资产服务请求,这在开发环境中意味着需要更少(有时没有)回滚来查看实际请求.

  • 不幸的是,这似乎与quiet_assets gem(https://github.com/evrone/quiet_assets)冲突。启用这两个选项后,我会收到来自logger.rb`compute_tags`的错误,例如“ NoMethodError:undefined method`collect'for nil:NilClass`”。 (2认同)

mer*_*ove 10

使用lograge宝石.

的Gemfile:

gem 'lograge'
Run Code Online (Sandbox Code Playgroud)

配置/ application.rb中

config.lograge.enabled = true
config.lograge.ignore_actions = ['StatusController#nginx', ...]
Run Code Online (Sandbox Code Playgroud)


arc*_*hop 7

答案结果比我预期的要困难得多,因为rails确实没有提供钩子来做到这一点.相反,你需要包装一些ActionController :: Base的内容.在我的控制器的公共基类中,我这样做

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
Run Code Online (Sandbox Code Playgroud)

然后,在控制器中使用我想要禁止登录的方法:

def silent?(action)
  RAILS_ENV == "development" && ['my_noisy_action'].include?(action)
end
Run Code Online (Sandbox Code Playgroud)


mic*_*red 7

您可以将宝石添加到 Gemfile消音器中。

gem 'silencer', '>= 1.0.1'
Run Code Online (Sandbox Code Playgroud)

在你的 config/initializers/silencer.rb 中:

  require 'silencer/logger'

  Rails.application.configure do
    config.middleware.swap Rails::Rack::Logger, Silencer::Logger, silence: ['/api/notifications']
  end
Run Code Online (Sandbox Code Playgroud)