Ideally we should be logging an exception in Rails like this.
Above code would produce one line log message as shown below.
In order to get backtrace and other information about the exception we need to handle logging like this.
Above code would produce following log message.
Now let’s look at why Rails logger does not produce detailed logging and what can be done about it.
A closer look at Formatters
When we use
Rails.logger.info(exception) then the output is formatted
ActiveSupport::Logger::SimpleFormatter. It is a custom formatter defined by Rails that looks like this.
As we can see it inherits from
Logger::Formatter defined by Ruby Logger .
It then overrides
call method which is originally defined as
When exception object is passed to
msg.inspect is called and that’s why we see the exception message without any backtrace.
The problem is that Rails’s SimpleFormatter’s call method is a bit dumb compared to Ruby logger’s call method.
Ruby logger’s method has a special check for exception messages. If the message it is going to print is of class
Exception then it prints backtrace also.In comparison
SimpleFormatter just prints
msg.inspect for objects of
This problem can be solved by using
From Rails Configuring Guides we have
config.loggeraccepts a logger conforming to the interface of Log4r or the default Ruby Logger class. Defaults to an instance of
ActiveSupport::Logger, with auto flushing off in production mode.
So now we can configure Rails logger to not to be
SimpleFomatter and go back to ruby’s logger.
config.logger = ::Logger.new(STDOUT) in
config/application.rb and then try following code.
Now above code produces following log message.
Sending log to STDOUT is also a good practice
As per http://12factor.net/logs, an application should not concern itself much with the kind of logging framework being used. The application should write log to STDOUT and logging frameworks should operate on log streams.