Rails backtrace silencers do not work, while filters do
Asked Answered
P

4

11

Fresh Rails 4.2 set up. I want to suppress long error backtraces. In the following backtrace log first line would be enough for me, and next 4 could be removed

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'

I've added a new silencer to backtrace_silencers.rb

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

After server restart - nothing happens, i'm still getting same backtrace log. (Each line matching /lib/ was supposed to be removed: http://api.rubyonrails.org/classes/ActiveSupport/BacktraceCleaner.htm)

Sanity check:

> 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

But filters work:

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

Now backtrace looks like this:

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'

Would appreciate an advice how to make silencers work. Cheers!

Propitious answered 20/3, 2015 at 14:35 Comment(0)
P
4

Problem was with Minitest-Reporters gem (adds colors to Minitest output), it messes up with Rails backtrace filters

To fix you need to add the following to test_helper.rb

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

Problem and solution details described here: https://github.com/kern/minitest-reporters#caveats

Propitious answered 3/4, 2015 at 18:14 Comment(1)
I added this to the top of that file, after the existing "require" lines. By itself, this did not make changes to the "backtrace_silencers.rb" file (cleaners) work for me. But, I found it to be necessary in combination with the answer from "Mikhail Chuprynski" to create a SilentLogger model. With both of these solutions combined, I can finally get all the useless-garbage out of my console-output.Knifeedged
E
6

This is because of https://github.com/vipulnsward/rails/blob/ecc8f283cfc1b002b5141c527a827e74b770f2f0/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb#L155-L156

Since application_trace is empty(This is because error is not from user code but route error), we are falling back to framework_trace, which does not filter it (it filters only noise).

You can reach your gaol it with creating your own log_formatter. In your development.rb and/or test.rb add

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

And create simple class in models with only method call required. There you can modify your backtrace as you wish.

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
Esthonia answered 7/4, 2016 at 8:48 Comment(1)
This worked, but only after also adding the code to fix the bug in MiniTest, from the selected answer from "Elder".Knifeedged
P
4

Problem was with Minitest-Reporters gem (adds colors to Minitest output), it messes up with Rails backtrace filters

To fix you need to add the following to test_helper.rb

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

Problem and solution details described here: https://github.com/kern/minitest-reporters#caveats

Propitious answered 3/4, 2015 at 18:14 Comment(1)
I added this to the top of that file, after the existing "require" lines. By itself, this did not make changes to the "backtrace_silencers.rb" file (cleaners) work for me. But, I found it to be necessary in combination with the answer from "Mikhail Chuprynski" to create a SilentLogger model. With both of these solutions combined, I can finally get all the useless-garbage out of my console-output.Knifeedged
M
0

Remove default silencers before add own:

Rails.backtrace_cleaner.remove_silencers!
Rails.backtrace_cleaner.add_silencer { |line| line =~ /lib/ }
Margo answered 20/3, 2015 at 15:0 Comment(1)
Thanks, but it doesn't help, same logPropitious
I
0

I had a similar problem, which was caused by this code in test_helper:

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

It was added to diagnose the error at some stage and overrides this. Removing that removed the backtrace.

Irishman answered 14/3, 2016 at 22:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.