lib/syslogger.rb in syslogger-1.6.4 vs lib/syslogger.rb in syslogger-1.6.5

- old
+ new

@@ -2,25 +2,23 @@ require 'logger' require 'thread' class Syslogger - VERSION = "1.6.4" - MUTEX = Mutex.new attr_reader :level, :ident, :options, :facility, :max_octets attr_accessor :formatter MAPPING = { - Logger::DEBUG => Syslog::LOG_DEBUG, - Logger::INFO => Syslog::LOG_INFO, - Logger::WARN => Syslog::LOG_WARNING, - Logger::ERROR => Syslog::LOG_ERR, - Logger::FATAL => Syslog::LOG_CRIT, + Logger::DEBUG => Syslog::LOG_DEBUG, + Logger::INFO => Syslog::LOG_INFO, + Logger::WARN => Syslog::LOG_WARNING, + Logger::ERROR => Syslog::LOG_ERR, + Logger::FATAL => Syslog::LOG_CRIT, Logger::UNKNOWN => Syslog::LOG_ALERT - } + }.freeze # # Initializes default options for the logger # <tt>ident</tt>:: the name of your program [default=$0]. # <tt>options</tt>:: syslog options [default=<tt>Syslog::LOG_PID | Syslog::LOG_CONS</tt>]. @@ -43,15 +41,15 @@ # logger.warn "warning message" # logger.debug "debug message" # logger.info "my_subapp" { "Some lazily computed message" } # def initialize(ident = $0, options = Syslog::LOG_PID | Syslog::LOG_CONS, facility = nil) - @ident = ident - @options = options || (Syslog::LOG_PID | Syslog::LOG_CONS) - @facility = facility - @level = Logger::INFO - @formatter = proc do |severity, datetime, progname, msg| + @ident = ident + @options = options || (Syslog::LOG_PID | Syslog::LOG_CONS) + @facility = facility + @level = Logger::INFO + @formatter = proc do |_, _, _, msg| msg end end %w{debug info warn error fatal unknown}.each do |logger_method| @@ -78,10 +76,14 @@ # Logs a message at the Logger::INFO level. def <<(msg) add(Logger::INFO, msg) end + def puts(msg) + add(Logger::INFO, msg) + end + # Low level method to add a message. # +severity+:: the level of the message. One of Logger::DEBUG, Logger::INFO, Logger::WARN, Logger::ERROR, Logger::FATAL, Logger::UNKNOWN # +message+:: the message string. # If nil, the method will call the block and use the result as the message string. # If both are nil or no block is given, it will use the progname as per the behaviour of both the standard Ruby logger, and the Rails BufferedLogger. @@ -91,48 +93,25 @@ message, progname = progname, nil end progname ||= @ident mask = Syslog::LOG_UPTO(MAPPING[@level]) communication = message || block && block.call - formatted_communication = clean(formatter.call([severity], Time.now, progname, communication)) - - MUTEX.synchronize do - Syslog.open(progname, @options, @facility) do |s| - s.mask = mask - if self.max_octets - buffer = "#{tags_text}" - formatted_communication.bytes do |byte| - buffer.concat(byte) - # if the last byte we added is potentially part of an escape, we'll go ahead and add another byte - if buffer.bytesize >= self.max_octets && !['%'.ord,'\\'.ord].include?(byte) - s.log(MAPPING[severity],buffer) - buffer = "" - end - end - s.log(MAPPING[severity],buffer) unless buffer.empty? - else - s.log(MAPPING[severity],"#{tags_text}#{formatted_communication}") - end - end - end + formatted_communication = clean(formatter.call(severity, Time.now, progname, communication)) + + # Call Syslog + syslog_add(progname, severity, mask, formatted_communication) end # Set the max octets of the messages written to the log def max_octets=(max_octets) @max_octets = max_octets end # Sets the minimum level for messages to be written in the log. # +level+:: one of <tt>Logger::DEBUG</tt>, <tt>Logger::INFO</tt>, <tt>Logger::WARN</tt>, <tt>Logger::ERROR</tt>, <tt>Logger::FATAL</tt>, <tt>Logger::UNKNOWN</tt> def level=(level) - level = Logger.const_get(level.to_s.upcase) if level.is_a?(Symbol) - - unless level.is_a?(Fixnum) - raise ArgumentError.new("Invalid logger level `#{level.inspect}`") - end - - @level = level + @level = sanitize_level(level) end # Sets the ident string passed along to Syslog def ident=(ident) @ident = ident @@ -145,12 +124,12 @@ ensure pop_tags(new_tags.size) end def push_tags(*tags) - tags.flatten.reject{ |i| i.respond_to?(:empty?) ? i.empty? : !i }.tap do |new_tags| - current_tags.concat new_tags + tags.flatten.reject { |i| i.respond_to?(:empty?) ? i.empty? : !i }.tap do |new_tags| + current_tags.concat(new_tags).uniq! end end def pop_tags(size = 1) current_tags.pop size @@ -158,12 +137,30 @@ def clear_tags! current_tags.clear end + def current_tags + Thread.current[:syslogger_tagged_logging_tags] ||= [] + end + protected + def sanitize_level(new_level) + begin + new_level = Logger.const_get(new_level.to_s.upcase) + rescue => _ + raise ArgumentError.new("Invalid logger level `#{new_level.inspect}`") + end if new_level.is_a?(Symbol) + + unless new_level.is_a?(Integer) + raise ArgumentError.new("Invalid logger level `#{new_level.inspect}`") + end + + new_level + end + # Borrowed from SyslogLogger. def clean(message) message = message.to_s.dup message.strip! # remove whitespace message.gsub!(/\n/, '\\n') # escape newlines @@ -175,13 +172,31 @@ private def tags_text tags = current_tags if tags.any? - clean(tags.collect { |tag| "[#{tag}] " }.join) << " " + clean(tags.collect { |tag| "[#{tag}] " }.join) << ' ' end end - def current_tags - Thread.current[:syslogger_tagged_logging_tags] ||= [] + def syslog_add(progname, severity, mask, formatted_communication) + MUTEX.synchronize do + Syslog.open(progname, @options, @facility) do |s| + s.mask = mask + if self.max_octets + buffer = "#{tags_text}" + formatted_communication.bytes do |byte| + buffer.concat(byte) + # if the last byte we added is potentially part of an escape, we'll go ahead and add another byte + if buffer.bytesize >= self.max_octets && !['%'.ord,'\\'.ord].include?(byte) + s.log(MAPPING[severity], buffer) + buffer = '' + end + end + s.log(MAPPING[severity], buffer) unless buffer.empty? + else + s.log(MAPPING[severity], "#{tags_text}#{formatted_communication}") + end + end + end end end