Module: ImprovedLogging

Defined in:
lib/improved_logging/improved_logging.rb,
lib/improved_logging/version.rb

Overview

This module, when included into ActiveSupport::BufferedLogger, improves the logging format. See the README file for more info.

This is distributed under a Creative Commons “Attribution-Share Alike” license: for details see: creativecommons.org/licenses/by-sa/3.0/

Constant Summary collapse

VERSION =
'1.0.2'
LENGTH =
::ActiveSupport::BufferedLogger::Severity.constants.map{|c| c.to_s.length}.max
@@verbose =

These are configurable, put something like the following in an initializer:

ImprovedLogging.verbose = false
defined?(::Rails) ? ::Rails.env != "development" : false
@@full_hostname =
get_hostname
@@hostname_maxlen =
10
@@custom =
nil
@@pid =

These are not configurable

$$
@@line_prefix =
format_line_prefix

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.custom=(string) ⇒ Object



60
61
62
63
# File 'lib/improved_logging/improved_logging.rb', line 60

def self.custom=(string)
  @@custom = string
  @@line_prefix = format_line_prefix
end

.format_line_prefixObject



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/improved_logging/improved_logging.rb', line 70

def self.format_line_prefix
  if @@full_hostname.length < @@hostname_maxlen
    hostname = @@full_hostname
  else
    hostname = @@full_hostname[-(@@hostname_maxlen)..-1]
  end
  
  line_prefix = sprintf("%1$*2$s", "#{hostname}.#{@@pid}  ", -(7 + hostname.length))
  line_prefix = "#{@@custom}  #{line_prefix}" if @@custom
  return line_prefix
end

.get_hostnameObject



82
83
84
# File 'lib/improved_logging/improved_logging.rb', line 82

def self.get_hostname
  `hostname -s`.strip
end

.hostname_maxlen=(integer) ⇒ Object



65
66
67
68
# File 'lib/improved_logging/improved_logging.rb', line 65

def self.hostname_maxlen=(integer)
  @@hostname_maxlen = integer
  @@line_prefix = format_line_prefix
end

.included(base) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/improved_logging/improved_logging.rb', line 11

def self.included(base)
  base.class_eval do
    alias_method_chain :add, :extra_info
    alias_method_chain :error, :exception_param
    alias_method_chain :warn, :exception_param
  end
  
  # Get the length to format the output so that the pid column lines up.
  # The severity levels probably won't change but this avoids hard-coding
  # them anyway, just in case.
  # Most of this is done with class_eval so it should only be done once 
  # while the class is being loaded.
  if_stmts = ""
  for c in ::ActiveSupport::BufferedLogger::Severity.constants
    if_stmts += <<-EOT
      if severity == #{c}
        severity_name = sprintf("%1$*2$s", "#{c}", #{LENGTH * -1})
        use_colour = false
        if ::Rails.version.to_i >= 3
          use_colour = true if ::ActiveSupport::LogSubscriber.colorize_logging
        else
          use_colour = true if defined?(::ActiveRecord) && ::ActiveRecord::Base.colorize_logging
        end
        if use_colour
          if severity == INFO
            severity_name = "\033[32m" + severity_name + "\033[0m"
          elsif severity == WARN
            severity_name = "\033[33m" + severity_name + "\033[0m"
          elsif severity == ERROR || severity == FATAL
            severity_name = "\033[31m" + severity_name + "\033[0m"
          end
        end
        return severity_name
      end
    EOT
  end
  base.class_eval <<-EOT, __FILE__, __LINE__
    def self.severity_name(severity)
      #{if_stmts}
      return "UNKNOWN"
    end
  EOT
end

.verbose=(boolean) ⇒ Object



56
57
58
# File 'lib/improved_logging/improved_logging.rb', line 56

def self.verbose=(boolean)
  @@verbose = boolean
end

Instance Method Details

#add_with_extra_info(severity, message = nil, progname = nil, &block) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/improved_logging/improved_logging.rb', line 109

def add_with_extra_info(severity, message = nil, progname = nil, &block)
  update_pid
  time = @@verbose ? "#{Time.new.strftime('%H:%M:%S')}  " : ""
  message = "#{time}#{::ActiveSupport::BufferedLogger.severity_name(severity)}  #{message}"
  
  # Make sure every line has the PID and hostname and custom string 
  # so we can use grep to isolate output from one process or server.
  # gsub works even when the output contains "\n", though there's
  # probably a small performance cost.
  message = message.gsub(/^/, @@line_prefix) if @@verbose
  
  add_without_extra_info(severity, message, progname, &block)
end

#error_with_exception_param(message = '', exception = nil) ⇒ Object

add an optional second parameter to the error & warn methods to allow a stack trace:



126
127
128
129
130
# File 'lib/improved_logging/improved_logging.rb', line 126

def error_with_exception_param(message = '', exception = nil)
  message = yield if block_given?
  message += "\n#{exception.inspect}\n#{exception.backtrace.join("\n")}" if exception
  error_without_exception_param(message)
end

#update_pidObject

the cached pid can be wrong after a fork(), this checks if it has changed and re-caches the line_prefix



102
103
104
105
106
107
# File 'lib/improved_logging/improved_logging.rb', line 102

def update_pid
  if @@pid != $$
    @@pid = $$
    @@line_prefix = ImprovedLogging.format_line_prefix
  end
end

#warn_with_exception_param(message = '', exception = nil) ⇒ Object



132
133
134
135
136
# File 'lib/improved_logging/improved_logging.rb', line 132

def warn_with_exception_param(message = '', exception = nil)
  message = yield if block_given?
  message += "\n#{exception.inspect}\n#{exception.backtrace.join("\n")}" if exception
  warn_without_exception_param(message)
end