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 $!
.
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
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
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:
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>'
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
How to Filter an Array of Hashes to Get Only the Keys in Another Array
Openssl, Rvm, Brew, Conflicting Error
How to Delete Specific Characters from a String in Ruby
Augmenting a Model from an External Gem
Confusing Behaviour of Const_Get in Ruby
How to Attach a Message to Rspec Check
How to Validate Ssl Certificate Chain in Ruby with Net/Http
Ruby: How to Pass All Parameters and Blocks Received by One Method to Another
How to Export a Ruby Array from My Heroku Console into CSV
Is Autoload Thread-Safe in Ruby 1.9
Why Should I Use Rspec or Shoulda with Rails
Ruby: How to Make a Public Static Method
Using Typeahead from Twitter Bootstrap in a Form (Formtastic)
Ruby on Rails, Including a Module with Arguments
No Database Connection in Rails Console