diff --git a/ext/syslog/lib/syslog/logger.rb b/ext/syslog/lib/syslog/logger.rb index 6b0336b..10c6b59 100644 --- a/ext/syslog/lib/syslog/logger.rb +++ b/ext/syslog/lib/syslog/logger.rb @@ -51,46 +51,42 @@ class Syslog::Logger # one level. For example, a fatal message for ruby's Logger is considered # an error for syslog(3). - LOGGER_MAP = { - :unknown => :alert, - :fatal => :err, - :error => :warning, - :warn => :notice, - :info => :info, - :debug => :debug, + LEVEL_MAP = { + ::Logger::UNKNOWN => Syslog::LOG_ALERT, + ::Logger::FATAL => Syslog::LOG_ERR, + ::Logger::ERROR => Syslog::LOG_WARNING, + ::Logger::WARN => Syslog::LOG_NOTICE, + ::Logger::INFO => Syslog::LOG_INFO, + ::Logger::DEBUG => Syslog::LOG_DEBUG, } ## - # Maps Logger log levels to their values so we can silence. + # Returns the internal Syslog object that is initialized when the + # first instance is created. - LOGGER_LEVEL_MAP = {} - - LOGGER_MAP.each_key do |key| - LOGGER_LEVEL_MAP[key] = ::Logger.const_get key.to_s.upcase + def self.syslog + @@syslog end ## - # Maps Logger log level values to syslog log levels. - - LEVEL_LOGGER_MAP = {} + # Specifies the internal Syslog object to be used. - LOGGER_LEVEL_MAP.invert.each do |level, severity| - LEVEL_LOGGER_MAP[level] = LOGGER_MAP[severity] + def self.syslog= syslog + @@syslog = syslog end ## # Builds a methods for level +meth+. def self.make_methods meth + level = ::Logger.const_get(meth.upcase) eval <<-EOM, nil, __FILE__, __LINE__ + 1 - def #{meth}(message = nil) - return true if #{LOGGER_LEVEL_MAP[meth]} < @level - SYSLOG.#{LOGGER_MAP[meth]} clean(message || yield) - return true + def #{meth}(message = nil, &block) + add(#{level}, message, &block) end def #{meth}? - @level <= ::Logger::#{meth.to_s.upcase} + @level <= #{level} end EOM end @@ -131,8 +127,8 @@ class Syslog::Logger # Logs a +message+ at the debug (syslog debug) log level, or logs the # message returned from the block. - LOGGER_MAP.each_key do |level| - make_methods level + Logger::Severity::constants.each do |severity| + make_methods severity.downcase end ## @@ -150,8 +146,7 @@ class Syslog::Logger def initialize program_name = 'ruby' @level = ::Logger::DEBUG - return if defined? SYSLOG - self.class.const_set :SYSLOG, Syslog.open(program_name) + @@syslog ||= Syslog.open(program_name) end ## @@ -159,9 +154,9 @@ class Syslog::Logger def add severity, message = nil, progname = nil, &block severity ||= ::Logger::UNKNOWN - return true if severity < @level - SYSLOG.send LEVEL_LOGGER_MAP[severity], clean(message || block.call) - return true + @level <= severity and + @@syslog.log LEVEL_MAP[severity], '%s', clean(message || block.call) + true end private @@ -170,10 +165,8 @@ class Syslog::Logger # Clean up messages so they're nice and pretty. def clean message - message = message.to_s.dup - message.strip! - message.gsub!(/%/, '%%') # syslog(3) fails on % (printf) - message.gsub!(/\e\[[^m]*m/, '') # remove useless ansi color codes + message = message.to_s.strip + message.gsub!(/\e\[[0-9;]*m/, '') # remove useless ansi color codes return message end diff --git a/test/syslog/test_syslog_logger.rb b/test/syslog/test_syslog_logger.rb index d57e064..5763926 100644 --- a/test/syslog/test_syslog_logger.rb +++ b/test/syslog/test_syslog_logger.rb @@ -4,34 +4,43 @@ require 'syslog/logger' class TestSyslogRootLogger < Test::Unit::TestCase - module MockSyslog; end + module MockSyslog + LEVEL_LABEL_MAP = {} - class << MockSyslog + class << self - @line = nil + @line = nil - Syslog::Logger::LOGGER_MAP.values.uniq.each do |level| - eval <<-EOM - def #{level}(message) - @line = "#{level.to_s.upcase} - \#{message}" - end - EOM - end + %w[ALERT ERR WARNING NOTICE INFO DEBUG].each do |name| + level = Syslog.const_get("LOG_#{name}") + LEVEL_LABEL_MAP[level] = name - attr_reader :line - attr_reader :program_name + eval <<-EOM + def #{name.downcase}(format, *args) + log(#{level}, format, *args) + end + EOM + end - def open(program_name) - @program_name = program_name - end + def log(level, format, *args) + @line = "#{LEVEL_LABEL_MAP[level]} - \#{format % args}" + end - def reset - @line = '' - end + attr_reader :line + attr_reader :program_name + + def open(program_name) + @program_name = program_name + end + + def reset + @line = '' + end + end end - Syslog::Logger.const_set :SYSLOG, MockSyslog + Syslog::Logger.syslog = MockSyslog LEVEL_LABEL_MAP = { Logger::DEBUG => 'DEBUG', @@ -452,15 +461,21 @@ class TestSyslogLogger < TestSyslogRootLogger @logger = Syslog::Logger.new end + SEVERITY_MAP = {}.tap { |map| + level2severity = Syslog::Logger::LEVEL_MAP.invert + + MockSyslog::LEVEL_LABEL_MAP.each { |level, name| + map[name] = TestSyslogRootLogger::LEVEL_LABEL_MAP[level2severity[level]] + } + } + class Log attr_reader :line, :label, :datetime, :pid, :severity, :progname, :msg def initialize(line) @line = line return unless /\A(\w+) - (.*)\Z/ =~ @line severity, @msg = $1, $2 - severity = Syslog::Logger::LOGGER_MAP.invert[severity.downcase.intern] - @severity = severity.to_s.upcase - @severity = 'ANY' if @severity == 'UNKNOWN' + @severity = SEVERITY_MAP[severity] end end