Beautiful logging for your Ruby on Rails application

Update April 5, 2012: this method only works with Rails 3.1 and older. For a way that works with Rails 3.2, see my new post.

I like pretty logs. I like logs with timestamped entries. The default Ruby on Rails BufferedLogger is so-so on the former and neglects the latter. This very simple patch fixes that.

This monkey-patch is Rails 2 and 3 compatible. Like all monkey-patches, it simply overrides predefined behavior with your own variant. In this case we add timestamp info as well as color-coded severity info; the latter makes it very easy to spot urgent items such as errors and fatalities. Here are some examples:

Create a file in app/config/initializers called monkey_patches.rb. Into this file paste this

#
# ActiveSupport patches
#
module ActiveSupport

  # Format the buffered logger with timestamp/severity info.
  class BufferedLogger
    NUMBER_TO_NAME_MAP  = {0=>'DEBUG', 1=>'INFO', 2=>'WARN', 3=>'ERROR', 4=>'FATAL', 5=>'UNKNOWN'}
    NUMBER_TO_COLOR_MAP = {0=>'0;37', 1=>'32', 2=>'33', 3=>'31', 4=>'31', 5=>'37'}

    def add(severity, message = nil, progname = nil, &block)
      return if @level > severity
      sevstring = NUMBER_TO_NAME_MAP[severity]
      color     = NUMBER_TO_COLOR_MAP[severity]

      message = (message || (block && block.call) || progname).to_s
      message = "\033[0;37m#{Time.now.to_s(:db)}\033[0m [\033[#{color}m" + sprintf("%-5s","#{sevstring}") + "\033[0m] #{message.strip} (pid:#{$$})\n" unless message[-1] == ?\n
      buffer << message
      auto_flush
      message
    end
  end
end

If you don’t like my color choices, or if you use a white background, just tune the color constants in NUMBER_TO_COLOR_MAP — the values correspond to the standard ANSI terminal color codes. Here are the codes copied from an /etc/DIR_COLORS file for your reference:

# Attribute codes:
# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
# Text color codes:
# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
# Background color codes:
# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white

9 thoughts on “Beautiful logging for your Ruby on Rails application

  1. Nice patch, thanks! I have been rewriting something like this manually for my Rails apps for a while. I hope they add something like this to the standard distribution in the near future; I’m amazed that we’re at version 3 and it still just dumps app-level log messages to the log as raw strings…

    Thanks again!
    Paul

  2. I tried this but it only seems to work for explicit calls to the logger, not for uncaught exceptions. Those are still logged, but without timestamps.

  3. I can’t get this to work in Rails 3.2. Looks like due to changes in ActiveSupport BufferedLogger. Would love a fix, if one is easy, otherwise I may spend some time looking into it.

Leave a reply to Ryan Cancel reply