Rails: Logging the Entire Stack Trace of an Exception

Rails: Logging the entire stack trace of an exception

If you look at the source for the BufferedLogger class in ActiveSupport, you'll see that the second argument is 'progname'. This is used only when the first argument is nil and you have either given it no block or the block return a non-true value.

In essence, you can't use the second parameter to output additional stuff.

What you want to do is something more akin to:

begin
raise
rescue => e
logger.error e.message
logger.error e.backtrace.join("\n")
end

Depending on how you have your logging setup, it might be better to iterate through each line of the backtrace and print it separately as certain loggers don't output newlines, in which case you'd do something like:

begin
raise
rescue => e
logger.error e.message
e.backtrace.each { |line| logger.error line }
end

How do I log the entire trace back of a Ruby exception using the default Rails logger?

logger.error $!.backtrace

Also, don't forget you can

rescue ErrorType => error_name

to give your error a variable name other than the default $!.

log partial exception stack trace in Ruby

e.backtrace is just array and you can get only last N numbers of backtrace's lines:

# get last 10 lines    
e.backtrace[0, 10].join("\n\t")

How to prevent logging Rails stack trace

According to the docs you should be able to add a backtrace silencer that excludes every line by returning true in the block.

But, at least with Rails 4.2.5.2, this doesn't appear to be working and even if it did work you would still end up with a line in log about the exception.

Accidentally I discovered that if you raise an error inside a silencer block that this will suppress the error message and the entire backtrace which turns out to be exactly what I'm looking for.

Rails.backtrace_cleaner.add_silencer { |_line| raise }

Combining this hack with the concise_logging gem I can now have logs that look like the following:

Sample Image

Get current stack trace in Ruby without raising an exception

You can use Kernel#caller:

# /tmp/caller.rb

def foo
puts caller # Kernel#caller returns an array of strings
end

def bar
foo
end

def baz
bar
end

baz

Output:

caller.rb:8:in `bar'
caller.rb:12:in `baz'
caller.rb:15:in `<main>'

Configure Rails Logger to store full stack trace by default

When you put your app on the highest log level (which is ":debug"), you'd get what want:

Rails guides on log level

How do I get ruby to print a full backtrace instead of a truncated one?

Exception#backtrace has the entire stack in it:

def do_division_by_zero; 5 / 0; end
begin
do_division_by_zero
rescue => exception
puts exception.backtrace
raise # always reraise
end

(Inspired by Peter Cooper's Ruby Inside blog)



Related Topics



Leave a reply



Submit