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
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
What a timely post, exactly what I was looking for – thanks so much for the share!
Than you, it’s very useful!
Aways missed that kind of details in my logs.
You just made a Brazilian dev happier today!
+1 for the Karateka avatar! 🙂
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.
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.
I just learned this, and it’s irritating. I was unable to find a quick fix, but I do hope you’ll share with me the code if you are able to fix it…
Ditto 😦
Gents, I’ve made a new post on getting beautiful logging under Rails 3.2. See the update above for the link!
Thank you!!