16

How can I configure the rails logger to output its log strings in another format? I would like to get something that is more informative like:

[Log Level] [Time] [Message]

Debug : 01-20-2008 13:11:03.00 : Method Called

This would really help me when I want to tail my development.log for messages that only come from a certain log level, like debug.

Bill
  • 1,563
  • 1
  • 15
  • 28
  • why not use Log4r? http://stackoverflow.com/questions/5664136/how-to-configure-log4r-with-rails-3-0-x – Siwei Jan 08 '12 at 23:50

4 Answers4

24

Did some digging and found this post in the RubyOnRails Talk google group.

So I modified it a little bit and put it at the end of my environment.rb:

module ActiveSupport
  class BufferedLogger
    def add(severity, message = nil, progname = nil, &block)
      return if @level > severity
      message = (message || (block && block.call) || progname).to_s

      level = {
        0 => "DEBUG",
        1 => "INFO",
        2 => "WARN",
        3 => "ERROR",
        4 => "FATAL"
      }[severity] || "U"

      message = "[%s: %s #%d] %s" % [level,
                                     Time.now.strftime("%m%d %H:%M:%S"),
                                     $$,
                                     message]

      message = "#{message}\n" unless message[-1] == ?\n
      buffer << message
      auto_flush
      message
    end
  end
end

This results in a format string like this:

[DEBUG: 0121 10:35:26 #57078] Rendered layouts/_header (0.00089)

Bill
  • 1,563
  • 1
  • 15
  • 28
  • Just to add: a cleaner way to add this patch to your application is to put the code in an initializer. Just create a file monkey_patching_logger_to_write_date_time.rb and add it in the config/initializers directory, restart your app. – Pascal Van Hecke Mar 28 '12 at 09:04
  • 1
    I had this in my initializer - worked for 3.1, but does not for 3.2 - presumably logging has changed now. – Chris Kimpton Apr 04 '12 at 19:03
  • 11
    In 3.2 Rails switched to using ActiveSupport::TaggedLogger. You can set config.log_tags in your environment.rb that specifies what prefixes to use (e.g., config.log_tags = [ :uuid, :remote_ip, Time.now ]). I haven't figured out how to include log level yet though. – gmcnaughton Apr 12 '12 at 16:02
  • throws *** Exception NameError in Class (undefined local variable or method `buffer' for #) (process 13047, thread #) for rails 3.2.3 – okliv Apr 14 '12 at 12:49
  • For high-performance environments I'd recommend adding %L for milliseconds to the strftime call. – Sim Jun 28 '13 at 04:58
  • Will this work with Rails4? I'm surprised its not easier to customize the default logging. – Tom Rossi Sep 14 '13 at 15:26
2

For rails 4 apps, I've put together a simple gem that not only adds support for basic tagging like time stamp and log level, but even adds color to the log messages themselves.

https://github.com/phallguy/shog

Paul Alexander
  • 31,970
  • 14
  • 96
  • 151
2
# config/initializers/rack_logger.rb
module Rails
  module Rack
    class Logger < ActiveSupport::LogSubscriber
      # Add UserAgent
      def started_request_message(request)
         'Started %s "%s" for %s at %s by %s' % [
          request.request_method,
          request.filtered_path,
          request.ip,
          Time.now.to_default_s,
          request.env['HTTP_USER_AGENT'] ]
      end
    end
  end
end

source link

rocLv
  • 548
  • 6
  • 15
1

The problem with tags is that they clutter your logs to the point where they are unreadable.

I'd recommend something like timber. It automatically augments your logs with context (level, time, session id, etc) without sacrificing readability.

Binary Logic
  • 1,529
  • 2
  • 17
  • 19