【问题标题】:Rails backtrace silencers do not work, while filters doRails 回溯消音器不起作用,而过滤器起作用
【发布时间】:2015-03-20 14:35:41
【问题描述】:

全新 Rails 4.2 设置。我想抑制长错误回溯。在下面的回溯日志中,第一行对我来说就足够了,接下来的 4 行可以删除

ActionController::RoutingError (No route matches [GET] "/user"):
  actionpack (4.2.1) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  web-console (2.1.2) lib/web_console/middleware.rb:37:in `call'
  actionpack (4.2.1) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.2.1) lib/rails/rack/logger.rb:38:in `call_app'

我给backtrace_silencers.rb添加了一个新的消音器

# config/initializers/backtrace_silencers.rb
Rails.backtrace_cleaner.add_silencer { |line| line =~ /lib/ }

服务器重新启动后 - 没有任何反应,我仍然得到相同的回溯日志。 (与/lib/ 匹配的每一行都应该被删除:http://api.rubyonrails.org/classes/ActiveSupport/BacktraceCleaner.htm

完整性检查:

> line = "actionpack (4.2.1) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'"
=> "actionpack (4.2.1) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'"
> line =~ /lib/
=> 19

但过滤器有效:

# config/initializers/backtrace_silencers.rb
Rails.backtrace_cleaner.add_filter { |line| line.gsub('lib', 'yeah!') }

现在回溯看起来像这样:

ActionController::RoutingError (No route matches [GET] "/user"):
  actionpack (4.2.1) yeah!/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  web-console (2.1.2) yeah!/web_console/middleware.rb:37:in `call'
  actionpack (4.2.1) yeah!/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.2.1) yeah!/rails/rack/logger.rb:38:in `call_app'

不胜感激有关如何使消音器工作的建议。干杯!

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 backtrace


    【解决方案1】:

    这是因为https://github.com/vipulnsward/rails/blob/ecc8f283cfc1b002b5141c527a827e74b770f2f0/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb#L155-L156

    由于application_trace 是空的(这是因为错误不是来自用户代码而是路由错误),我们将退回到framework_trace,它不会过滤它(它只过滤噪音)。

    您可以通过创建自己的 log_formatter 来达到您的目标。在您的development.rb 和/或test.rb 添加

    config.log_formatter = SilentLogger.new
    config.log_formatter.add_silencer { |line| line =~ /lib/ }
    

    并在模型中创建简单的类,只需要方法call。在那里,您可以根据需要修改回溯。

    class SilentLogger
      def initialize
        @silencers = []
      end
    
      def add_silencer(&block)
        @silencers << block
      end
    
      def call(severity, timestamp, progname, msg)
        backtrace = (String === msg) ? "#{msg}\n" : "#{msg.inspect}\n"
    
        return backtrace if @silencers.empty?
    
        @silencers.each do |s|
          backtrace = backtrace.split("\n").delete_if { |line| s.call(line) }
        end
    
        backtrace.join("\n")
      end
    end
    

    【讨论】:

    • 这有效,但只有在从“Elder”中选择的答案中添加代码来修复 MiniTest 中的错误之后。
    【解决方案2】:

    问题在于 Minitest-Reporters gem(向 Minitest 输出添加颜色),它与 Rails 回溯过滤器混淆

    要修复,您需要将以下内容添加到test_helper.rb

    Minitest::Reporters.use!(
      Minitest::Reporters::DefaultReporter.new,
      ENV,
      Minitest.backtrace_filter
    )
    

    此处描述的问题和解决方案详情:https://github.com/kern/minitest-reporters#caveats

    【讨论】:

    • 我将此添加到该文件的顶部,在现有的“require”行之后。就其本身而言,这并没有对我的“backtrace_silencers.rb”文件(清洁器)进行更改。但是,我发现有必要结合“Mikhail Chuprynski”的答案来创建一个 SilentLogger 模型。结合这两种解决方案,我终于可以从控制台输出中清除所有无用的垃圾了。
    【解决方案3】:

    在添加自己的之前删除默认消音器:

    Rails.backtrace_cleaner.remove_silencers!
    Rails.backtrace_cleaner.add_silencer { |line| line =~ /lib/ }
    

    【讨论】:

    • 谢谢,但没有帮助,同样的日志
    【解决方案4】:

    我遇到了类似的问题,是由 test_helper 中的这段代码引起的:

    def MiniTest.filter_backtrace(backtrace, prefix=nil)
      backtrace
    end
    

    添加它是为了在某个阶段诊断错误和overrides this。删除那个删除了回溯。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-16
      • 2014-08-24
      • 2018-01-04
      • 2020-12-23
      • 2016-10-08
      • 2014-11-17
      • 2017-08-30
      相关资源
      最近更新 更多