class Navo::Logger

Manages the display of output and writing of log files.

The goal is to make the tool easier to read when running from the command line, but preserving all useful information in log files as well so in-depth debugging can be performed.

Each test suite creates its own {Output} instance to write to so individual log lines go to their own files, but they all share a common destination that is synchronized when writing to stdout/stderr for the application as a whole.

Constants

UI_COLORS

Attributes

level[R]
logger[R]
mutex[R]

Public Class Methods

level=(level) click to toggle source
# File lib/navo/logger.rb, line 38
def level=(level)
  level = level ? ::Logger.const_get(level.upcase) : ::Logger::INFO
  @level = level
  @logger.level = level
end
new(suite: nil) click to toggle source
# File lib/navo/logger.rb, line 45
def initialize(suite: nil)
  @suite = suite

  if suite
    log_file = File.open(suite.log_file, File::CREAT | File::WRONLY | File::APPEND)
    @logger = ::Logger.new(log_file)
    @logger.level = self.class.level
  end

  @color_hash = {}
end
output=(out) click to toggle source
# File lib/navo/logger.rb, line 33
def output=(out)
  @logger = ::Logger.new(out)
  @mutex = Mutex.new
end

Public Instance Methods

console(message, severity: :info, flush: true) click to toggle source
# File lib/navo/logger.rb, line 57
def console(message, severity: :info, flush: true)
  # In order to improve the output displayed, we don't want to print a line
  # for every chunk of log received--only logs which have newlines.
  # Thus we buffer the output and flush it once we have the full amount.
  @buffer_severity ||= severity
  @buffer_level ||= ::Logger.const_get(severity.upcase)
  @buffer ||= ''
  @buffer += message

  flush_buffer if flush
end
flush_buffer() click to toggle source
# File lib/navo/logger.rb, line 81
def flush_buffer
  if @buffer
    # This is shared amongst potentially many threads, so serialize access
    if @buffer_level >= self.class.level
      self.class.mutex.synchronize do
        self.class.logger << pretty_message(@buffer_severity, @buffer)
      end
    end

    @buffer = nil
    @buffer_severity = nil
    @buffer_level = nil
  end
end
log(severity, message, flush: true) click to toggle source
# File lib/navo/logger.rb, line 69
def log(severity, message, flush: true)
  level = ::Logger.const_get(severity.upcase)
  @logger.add(level, message) if @logger
  console(message, severity: severity, flush: flush)
end

Private Instance Methods

color_for_string(string) click to toggle source

Returns a deterministic color code for the given string.

# File lib/navo/logger.rb, line 112
def color_for_string(string)
  @color_hash[string] ||= (Digest::MD5.hexdigest(string)[0..8].to_i(16) % 6) + 31
end
indent_output(prefix, colored_prefix, message) click to toggle source
# File lib/navo/logger.rb, line 116
def indent_output(prefix, colored_prefix, message)
  return message unless prefix
  message.gsub(/\n(?!$)/, "\n#{colored_prefix}")
end
pretty_message(severity, message) click to toggle source
# File lib/navo/logger.rb, line 98
def pretty_message(severity, message)
  color_code = UI_COLORS[severity]

  prefix = "[#{@suite.name}] " if @suite
  colored_prefix = "\e[#{color_for_string(@suite.name)}m#{prefix}\e[0m" if prefix
  message = message.to_s
  message = "\e[#{color_code}m#{message}\e[0m" if color_code

  message = indent_output(prefix, colored_prefix, "#{colored_prefix}#{message}")
  message += "\n" unless message.end_with?("\n")
  message
end