class MU::Logger

This class should be used for all output from MU. By default it logs to stdout with human-friendly ANSI coloring, and to syslog.

Constants

COLORMAP

stash a hash map for color outputs

LOUD

Show DEBUG log entries and extra call stack and threading info

NORMAL

Show INFO log entries

minimum log verbosity at which we'll print various types of messages

QUIET

Only show NOTICE, WARN, and ERROR log entries

SILENT

Show nothing at all

SYSLOG_MAP

Syslog equivalents of our log levels

Attributes

color[RW]
handle[RW]
html[RW]
quiet[RW]
summary[R]
verbosity[RW]

Public Class Methods

new(verbosity=MU::Logger::NORMAL, html=false, handle=STDOUT, color=true) click to toggle source

@param verbosity [Integer]: See {MU::Logger.QUIET}, {MU::Logger.NORMAL}, {MU::Logger.LOUD} @param html [Boolean]: Enable web-friendly log output.

# File modules/mu/logger.rb, line 74
def initialize(verbosity=MU::Logger::NORMAL, html=false, handle=STDOUT, color=true)
  @verbosity = verbosity
  @html = html
  @handle = handle
  @color = color
  @summary = []
end

Public Instance Methods

log(msg, level=INFO, details: nil, html: nil, verbosity: nil, handle: nil, color: nil, deploy: MU.mommacat ) click to toggle source

@param msg [String]: A short message to log @param level [Integer]: The level at which to log (DEBUG, INFO, NOTICE, WARN, ERR) @param details [String,Hash,Array]: Extra information for verbose logging modes. @param html [Boolean]: Toggle web-friendly output. @param verbosity [Integer]: Explicit verbosity settings for this message

# File modules/mu/logger.rb, line 93
    def log(msg,
            level=INFO,
            details: nil,
            html: nil,
            verbosity: nil,
            handle: nil,
            color: nil,
            deploy: MU.mommacat
    )
      verbosity ||= @verbosity
      html ||= @html
      handle ||= @handle
      color ||= @color

      if verbosity == MU::Logger::SILENT or (verbosity < MU::Logger::LOUD and level == DEBUG) or (verbosity < MU::Logger::NORMAL and level == INFO)
        return
      end

      if level == SUMMARY
        @summary << msg
        return
      end

      caller_name = extract_caller_name(caller[1])

      time = Time.now.strftime("%b %d %H:%M:%S").to_s

      Syslog.open("Mu/"+caller_name, Syslog::LOG_PID, Syslog::LOG_DAEMON | Syslog::LOG_LOCAL3) if !Syslog.opened?

      details = format_details(details, html)

      msg = msg.first if msg.is_a?(Array)
      msg = "" if msg == nil
      msg = msg.to_s if !msg.is_a?(String) and msg.respond_to?(:to_s)

      @@log_semaphere.synchronize {
        handles = [handle]
        extra_logfile = if deploy and deploy.deploy_dir and Dir.exist?(deploy.deploy_dir)
          File.open(deploy.deploy_dir+"/log", "a")
        end
        handles << extra_logfile if extra_logfile
        msgs = []

        if !PRINT_MSG_IF[level][:msg] or level >= PRINT_MSG_IF[level][:msg]
          if html
            html_out "#{time} - #{caller_name} - #{msg}", COLORMAP[level][:html]
          else
            str = "#{time} - #{caller_name} - #{msg}"
            str = str.send(COLORMAP[level][:ansi]).on_black if color
            msgs << str
          end
          Syslog.log(SYSLOG_MAP[level], msg.gsub(/%/, ''))
        end

        if details and (!PRINT_MSG_IF[level][:details] or level >= PRINT_MSG_IF[level][:details])
          if html
            html_out "&nbsp;#{details}"
          else
            details = details.white.on_black if color
            msgs << details
          end
          Syslog.log(SYSLOG_MAP[level], details.gsub(/%/, ''))
        end

#          else
#            if html
#              html_out "#{time} - #{caller_name} - #{msg}"
#              html_out "&nbsp;#{details}" if details
#            elsif color
#              msgs << "#{time} - #{caller_name} - #{msg}".white.on_black
#              msgs << "#{details}".white.on_black if details
#            else
#              msgs << "#{time} - #{caller_name} - #{msg}"
#              msgs << "#{details}" if details
#            end
#            Syslog.log(Syslog::LOG_NOTICE, msg.gsub(/%/, ''))
#            Syslog.log(Syslog::LOG_NOTICE, details.gsub(/%/, '')) if details

        write(handles, msgs)

        extra_logfile.close if extra_logfile
      }

    end

Private Instance Methods

extract_caller_name(caller_name) click to toggle source

By which we mean, “get the filename (with the .rb stripped off) which originated the call to this method. Which, for our purposes, is the MU subclass that called us. Useful information. And it looks like Perl.

# File modules/mu/logger.rb, line 202
def extract_caller_name(caller_name)
  return nil if !caller_name or !caller_name.is_a?(String)
  mod_root = Regexp.quote("#{ENV['MU_LIBDIR']}/modules/mu/")
  bin_root = Regexp.quote("#{ENV['MU_INSTALLDIR']}/bin/")

  caller_name.sub!(/:.*/, "")
  caller_name.sub!(/^\.\//, "")
  caller_name.sub!(/^#{mod_root}/, "")
  caller_name.sub!(/^#{bin_root}/, "")
  caller_name.sub!(/\.r[ub]$/, "")
  caller_name.sub!(/#{Regexp.quote(MU.myRoot)}\//, "")
  caller_name.sub!(/^modules\//, "")
  caller_name
end
format_details(details, html = false) click to toggle source
# File modules/mu/logger.rb, line 180
def format_details(details, html = false)
  return if details.nil?

  if details.is_a?(Hash) and details.has_key?(:details)
    details = details[:details]
  end
  details = PP.pp(details, '') if !details.is_a?(String)

  details = "<pre>"+details+"</pre>" if html
  # We get passed literal quoted newlines sometimes, fix 'em. Get Windows'
  # ugly line feeds too.

  details = details.dup # in case it's frozen or something
  details.gsub!(/\\n/, "\n")
  details.gsub!(/(\\r|\r)/, "")

  details
end
html_out(msg, color_name="black") click to toggle source

Output a log message as HTML.

@param msg [String]: The log message to print @param color_name [String]: A color name. Must be a valid CSS color.

# File modules/mu/logger.rb, line 221
def html_out(msg, color_name="black")
  rgb = Color::RGB::by_name color_name
  @handle.puts "<span style='color:#{rgb.css_rgb};'>#{msg}</span>"
end
write(handles = [], msgs = []) click to toggle source

wrapper for writing a log entry to multiple filehandles @param handles [Array<IO>] @param msgs [Array<String>]

# File modules/mu/logger.rb, line 229
def write(handles = [], msgs = [])
  return if handles.nil? or msgs.nil?
  handles.each { |h|
    msgs.each { |m|
      h.puts m
    }
  }
end