class Logger

This class makes some minor monkey-patches to the standard Logger class. These changes allow the logging methods to be called directly on the Logger class itself without having to create a (global) instance. Class methods are defined (via instance_eval) to log messages at the various levels. Sample usages:

Logger.debug("A debug message")  # Message as a string.
Logger.debug{"A debug message"}  # Message in a block.
Logger.debug("method_name") {    # Override calling method name
  "A debug message"
}

The first two forms will automatically add the name of the calling method as part of the logged message. An exception can also be logged instead of a string. The exception will be converted into a backtrace string.

Unlike the Status methods, the Logger methods perform no output.

Constants

LEVELS

Store all the Logger levels as strings in an array.

Attributes

logdev[R]

Permit access to the name of the logging device so that we can filter the log file with the ::show method.

Public Class Methods

close() click to toggle source

Close the log file, if it hasn't already been closed before.

# File buryspam.rb, line 243
def close
  return if @log.nil?
  @log.close
  @log = nil
end
ex2str(ex) click to toggle source

Convert the given exception into a string with backtrace information.

# File buryspam.rb, line 250
def ex2str(ex)
  return "" unless ex.kind_of?(Exception)
  if ex.backtrace.nil? || ex.backtrace.empty?
    return "%s (%s)" % [ex, ex.class]
  end
  first, *rest = ex.backtrace
  unless rest.empty?
    rest = "\n\tfrom " + rest.join("\n\tfrom ")
  end
  "%s: %s (%s)%s" % [first, ex, ex.class, rest]
end
show(level) click to toggle source

Show all log messages with the given severity. level is a string consisting of the letters d,i,w,e,f representing the logging levels of debug, info, warning, error, fatal, respectively.

# File buryspam.rb, line 266
def show(level)
  if @log.nil?
    puts "No log file."
    return
  end
  glob = @log.logdev.filename + "*"
  files = Dir[glob].find_all {|e| File.file?(e)}
  sorted = files.sort_by {|f| File.mtime(f)}
  # Get the first character of all the valid levels
  # (in upper and lower case).
  good = LEVELS.map{ |l|
    first = l.to_s[0,1]
    [first, first.upcase]
  }.flatten.join
  # See if the user specified a bad level.  If so, stop.
  bad = level.delete(good).split(//)
  unless bad.empty?
    # Don't want the number in the string so
    # don't use String#pluralize.
    plural = (bad.size == 1 ? "" : "s")
    raise CommandLine::Error,
       "Invalid log level%s: #{bad.join(",")}" % plural
  end
  regex = level.empty? ? // : /^[#{level}],/
  filter = []
  sorted.each { |f|
    lines = IO.readlines(f)
    show = lines.find_all{|l| regex.match(l) }
    filter.concat(show.map { |l| "<#{f}> #{l}" })
  }
  if filter.empty?
    puts "No log messages at specified level(s)."
  else
    puts filter
  end
end

Protected Class Methods

open() click to toggle source

Open the log file if it hasn't already been opened and set it to its configured level. If there are problems opening the log file, /dev/null will be used instead. There is no need for any method other than the class logging methods to call open, so this method is protected.

# File buryspam.rb, line 309
def open
  return unless @log.nil?
  begin
    @log = Logger.new(Buryspam::Config.log_file,
                      Buryspam::Config.log_file_count,
                      Buryspam::Config.log_file_size)
  rescue
    $stderr.puts("Log file '#{Buryspam::Config.log_file}' invalid: #$!.")
    $stderr.puts("Logging to '/dev/null'")
    @log = Logger.new("/dev/null")
  end
  @log.level = Buryspam::Config.log_level
end