[前][次][番号順一覧][スレッド一覧]

ruby-changes:23631

From: drbrain <ko1@a...>
Date: Fri, 18 May 2012 06:14:36 +0900 (JST)
Subject: [ruby-changes:23631] drbrain:r35682 (trunk): * ext/syslog/lib/syslog/logger.rb: Added Syslog::Logger which was

drbrain	2012-05-18 06:14:24 +0900 (Fri, 18 May 2012)

  New Revision: 35682

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=35682

  Log:
    * ext/syslog/lib/syslog/logger.rb:  Added Syslog::Logger which was
      ported from the SyslogLogger gem.  [ruby-trunk - Feature #5096]
    * NEWS:  ditto.
    * test/syslog/test_syslog_logger.rb:  ditto.

  Added directories:
    trunk/ext/syslog/lib/
    trunk/ext/syslog/lib/syslog/
    trunk/test/syslog/
  Added files:
    trunk/ext/syslog/lib/syslog/logger.rb
    trunk/test/syslog/test_syslog_logger.rb
  Modified files:
    trunk/ChangeLog
    trunk/NEWS

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 35681)
+++ ChangeLog	(revision 35682)
@@ -1,3 +1,10 @@
+Fri May 18 06:14:07 2012  Eric Hodel  <drbrain@s...>
+
+	* ext/syslog/lib/syslog/logger.rb:  Added Syslog::Logger which was
+	  ported from the SyslogLogger gem.  [ruby-trunk - Feature #5096]
+	* NEWS:  ditto.
+	* test/syslog/test_syslog_logger.rb:  ditto.
+
 Fri May 18 01:28:21 2012  Aaron Patterson <aaron@t...>
 
 	* ext/psych/parser.c (transcode_string): fix encoding index names.
Index: ext/syslog/lib/syslog/logger.rb
===================================================================
--- ext/syslog/lib/syslog/logger.rb	(revision 0)
+++ ext/syslog/lib/syslog/logger.rb	(revision 35682)
@@ -0,0 +1,174 @@
+require 'syslog'
+require 'logger'
+
+##
+# Syslog::Logger is a Logger work-alike that logs via syslog instead of to a
+# file.  You can use Syslog::Logger to aggregate logs between multiple
+# machines.
+#
+# By default, Syslog::Logger uses the program name 'ruby', but this can be
+# changed via the first argument to Syslog::Logger.new.
+#
+# NOTE! You can only set the Syslog::Logger program name when you initialize
+# Syslog::Logger for the first time.  This is a limitation of the way
+# Syslog::Logger uses syslog (and in some ways, a limitation of the way
+# syslog(3) works).  Attempts to change Syslog::Logger's program name after
+# the first initialization will be ignored.
+#
+# === Example
+#
+# The following will log to syslogd on your local machine:
+#
+#   require 'syslog/logger'
+#
+#   log = Syslog::Logger.new 'my_program'
+#   log.info 'this line will be logged via syslog(3)'
+#
+# You may need to perform some syslog.conf setup first.  For a BSD machine add
+# the following lines to /etc/syslog.conf:
+#
+#  !my_program
+#  *.*                                             /var/log/my_program.log
+#
+# Then touch /var/log/my_program.log and signal syslogd with a HUP
+# (killall -HUP syslogd, on FreeBSD).
+#
+# If you wish to have logs automatically roll over and archive, see the
+# newsyslog.conf(5) and newsyslog(8) man pages.
+
+class Syslog::Logger
+
+  ##
+  # The version of Syslog::Logger you are using.
+
+  VERSION = '2.0'
+
+  ##
+  # Maps Logger warning types to syslog(3) warning types.
+  #
+  # Messages from ruby applications are not considered as critical as messages
+  # from other system daemons using syslog(3), so most messages are reduced by
+  # one level.  For example, a fatal message for ruby's Logger is considered
+  # an error for syslog(3).
+
+  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,
+  }
+
+  ##
+  # Returns the internal Syslog object that is initialized when the
+  # first instance is created.
+
+  def self.syslog
+    @@syslog
+  end
+
+  ##
+  # Specifies the internal Syslog object to be used.
+
+  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, &block)
+        add(#{level}, message, &block)
+      end
+
+      def #{meth}?
+        @level <= #{level}
+      end
+    EOM
+  end
+
+  ##
+  # :method: unknown
+  #
+  # Logs a +message+ at the unknown (syslog alert) log level, or logs the
+  # message returned from the block.
+
+  ##
+  # :method: fatal
+  #
+  # Logs a +message+ at the fatal (syslog err) log level, or logs the message
+  # returned from the block.
+
+  ##
+  # :method: error
+  #
+  # Logs a +message+ at the error (syslog warning) log level, or logs the
+  # message returned from the block.
+
+  ##
+  # :method: warn
+  #
+  # Logs a +message+ at the warn (syslog notice) log level, or logs the
+  # message returned from the block.
+
+  ##
+  # :method: info
+  #
+  # Logs a +message+ at the info (syslog info) log level, or logs the message
+  # returned from the block.
+
+  ##
+  # :method: debug
+  #
+  # Logs a +message+ at the debug (syslog debug) log level, or logs the
+  # message returned from the block.
+
+  Logger::Severity::constants.each do |severity|
+    make_methods severity.downcase
+  end
+
+  ##
+  # Log level for Logger compatibility.
+
+  attr_accessor :level
+
+  ##
+  # Fills in variables for Logger compatibility.  If this is the first
+  # instance of Syslog::Logger, +program_name+ may be set to change the logged
+  # program name.
+  #
+  # Due to the way syslog works, only one program name may be chosen.
+
+  def initialize program_name = 'ruby'
+    @level = ::Logger::DEBUG
+
+    @@syslog ||= Syslog.open(program_name)
+  end
+
+  ##
+  # Almost duplicates Logger#add.  +progname+ is ignored.
+
+  def add severity, message = nil, progname = nil, &block
+    severity ||= ::Logger::UNKNOWN
+    @level <= severity and
+      @@syslog.log LEVEL_MAP[severity], '%s', clean(message || block.call)
+    true
+  end
+
+  private
+
+  ##
+  # Clean up messages so they're nice and pretty.
+
+  def clean message
+    message = message.to_s.strip
+    message.gsub!(/\e\[[0-9;]*m/, '') # remove useless ansi color codes
+    return message
+  end
+
+end
+

Property changes on: ext/syslog/lib/syslog/logger.rb
___________________________________________________________________
Added: svn:eol-style
   + LF

Index: NEWS
===================================================================
--- NEWS	(revision 35681)
+++ NEWS	(revision 35682)
@@ -96,6 +96,9 @@
     * Shellwords#shelljoin() accepts non-string objects in the given
       array, each of which is stringified using to_s.
 
+* syslog
+  * Added Syslog::Logger which provides a Logger API atop Syslog.
+
 * lib/tmpdir.rb
   * incompatible changes:
     * Dir.mktmpdir uses FileUtils.remove_entry instead of
Index: test/syslog/test_syslog_logger.rb
===================================================================
--- test/syslog/test_syslog_logger.rb	(revision 0)
+++ test/syslog/test_syslog_logger.rb	(revision 35682)
@@ -0,0 +1,507 @@
+require 'test/unit'
+require 'tempfile'
+require 'syslog/logger'
+
+# These tests ensure Syslog::Logger works like Logger
+
+class TestSyslogRootLogger < Test::Unit::TestCase
+
+  module MockSyslog
+    LEVEL_LABEL_MAP = {}
+
+    class << self
+
+      @line = nil
+
+      %w[ALERT ERR WARNING NOTICE INFO DEBUG].each do |name|
+        level = Syslog.const_get("LOG_#{name}")
+        LEVEL_LABEL_MAP[level] = name
+
+        eval <<-EOM
+          def #{name.downcase}(format, *args)
+            log(#{level}, format, *args)
+          end
+        EOM
+      end
+
+      def log(level, format, *args)
+        @line = "#{LEVEL_LABEL_MAP[level]} - \#{format % args}"
+      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.syslog = MockSyslog
+
+  LEVEL_LABEL_MAP = {
+    Logger::DEBUG => 'DEBUG',
+    Logger::INFO => 'INFO',
+    Logger::WARN => 'WARN',
+    Logger::ERROR => 'ERROR',
+    Logger::FATAL => 'FATAL',
+    Logger::UNKNOWN => 'ANY',
+  }
+
+  def setup
+    @logger = Logger.new(nil)
+  end
+
+  class Log
+    attr_reader :line, :label, :datetime, :pid, :severity, :progname, :msg
+    def initialize(line)
+      @line = line
+      /\A(\w+), \[([^#]*)#(\d+)\]\s+(\w+) -- (\w*): ([\x0-\xff]*)/ =~ @line
+      @label, @datetime, @pid, @severity, @progname, @msg = $1, $2, $3, $4, $5, $6
+    end
+  end
+
+  def log_add(severity, msg, progname = nil, &block)
+    log(:add, severity, msg, progname, &block)
+  end
+
+  def log(msg_id, *arg, &block)
+    Log.new(log_raw(msg_id, *arg, &block))
+  end
+
+  def log_raw(msg_id, *arg, &block)
+    logdev = Tempfile.new(File.basename(__FILE__) + '.log')
+    @logger.instance_eval { @logdev = Logger::LogDevice.new(logdev) }
+    assert_equal true, @logger.__send__(msg_id, *arg, &block)
+    logdev.open
+    msg = logdev.read
+    logdev.close
+    msg
+  end
+
+  def test_initialize
+    assert_equal Logger::DEBUG, @logger.level
+  end
+
+  def test_add
+    msg = log_add nil,           'unknown level message' # nil == unknown
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+
+    msg = log_add Logger::FATAL, 'fatal level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::FATAL],   msg.severity
+
+    msg = log_add Logger::ERROR, 'error level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::ERROR],   msg.severity
+
+    msg = log_add Logger::WARN,  'warn level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::WARN],    msg.severity
+
+    msg = log_add Logger::INFO,  'info level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::INFO],    msg.severity
+
+    msg = log_add Logger::DEBUG, 'debug level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::DEBUG],   msg.severity
+  end
+
+  def test_add_level_unknown
+    @logger.level = Logger::UNKNOWN
+
+    msg = log_add nil,           'unknown level message' # nil == unknown
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+
+    msg = log_add Logger::FATAL, 'fatal level message'
+    assert_equal '', msg.line
+
+    msg = log_add Logger::ERROR, 'error level message'
+    assert_equal '', msg.line
+
+    msg = log_add Logger::WARN,  'warn level message'
+    assert_equal '', msg.line
+
+    msg = log_add Logger::INFO,  'info level message'
+    assert_equal '', msg.line
+
+    msg = log_add Logger::DEBUG, 'debug level message'
+    assert_equal '', msg.line
+  end
+
+  def test_add_level_fatal
+    @logger.level = Logger::FATAL
+
+    msg = log_add nil,           'unknown level message' # nil == unknown
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+
+    msg = log_add Logger::FATAL, 'fatal level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::FATAL],   msg.severity
+
+    msg = log_add Logger::ERROR, 'error level message'
+    assert_equal '', msg.line
+
+    msg = log_add Logger::WARN,  'warn level message'
+    assert_equal '', msg.line
+
+    msg = log_add Logger::INFO,  'info level message'
+    assert_equal '', msg.line
+
+    msg = log_add Logger::DEBUG, 'debug level message'
+    assert_equal '', msg.line
+  end
+
+  def test_add_level_error
+    @logger.level = Logger::ERROR
+
+    msg = log_add nil,           'unknown level message' # nil == unknown
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+
+    msg = log_add Logger::FATAL, 'fatal level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::FATAL],   msg.severity
+
+    msg = log_add Logger::ERROR, 'error level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::ERROR],   msg.severity
+
+    msg = log_add Logger::WARN,  'warn level message'
+    assert_equal '', msg.line
+
+    msg = log_add Logger::INFO,  'info level message'
+    assert_equal '', msg.line
+
+    msg = log_add Logger::DEBUG, 'debug level message'
+    assert_equal '', msg.line
+  end
+
+  def test_add_level_warn
+    @logger.level = Logger::WARN
+
+    msg = log_add nil,           'unknown level message' # nil == unknown
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+
+    msg = log_add Logger::FATAL, 'fatal level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::FATAL],   msg.severity
+
+    msg = log_add Logger::ERROR, 'error level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::ERROR],   msg.severity
+
+    msg = log_add Logger::WARN,  'warn level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::WARN],   msg.severity
+
+    msg = log_add Logger::INFO,  'info level message'
+    assert_equal '', msg.line
+
+    msg = log_add Logger::DEBUG, 'debug level message'
+    assert_equal '', msg.line
+  end
+
+  def test_add_level_info
+    @logger.level = Logger::INFO
+
+    msg = log_add nil,           'unknown level message' # nil == unknown
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+
+    msg = log_add Logger::FATAL, 'fatal level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::FATAL],   msg.severity
+
+    msg = log_add Logger::ERROR, 'error level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::ERROR],   msg.severity
+
+    msg = log_add Logger::WARN,  'warn level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::WARN],    msg.severity
+
+    msg = log_add Logger::INFO,  'info level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::INFO],    msg.severity
+
+    msg = log_add Logger::DEBUG, 'debug level message'
+    assert_equal '', msg.line
+  end
+
+  def test_add_level_debug
+    @logger.level = Logger::DEBUG
+
+    msg = log_add nil,           'unknown level message' # nil == unknown
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+
+    msg = log_add Logger::FATAL, 'fatal level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::FATAL],   msg.severity
+
+    msg = log_add Logger::ERROR, 'error level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::ERROR],   msg.severity
+
+    msg = log_add Logger::WARN,  'warn level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::WARN],    msg.severity
+
+    msg = log_add Logger::INFO,  'info level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::INFO],    msg.severity
+
+    msg = log_add Logger::DEBUG, 'debug level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::DEBUG],   msg.severity
+  end
+
+  def test_unknown
+    msg = log :unknown, 'unknown level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+
+    @logger.level = Logger::UNKNOWN
+    msg = log :unknown, 'unknown level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+
+    @logger.level = Logger::FATAL
+    msg = log :unknown, 'unknown level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+
+    @logger.level = Logger::ERROR
+    msg = log :unknown, 'unknown level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+
+    @logger.level = Logger::WARN
+    msg = log :unknown, 'unknown level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+
+    @logger.level = Logger::INFO
+    msg = log :unknown, 'unknown level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+
+    @logger.level = Logger::DEBUG
+    msg = log :unknown, 'unknown level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
+  end
+
+  def test_fatal
+    msg = log :fatal, 'fatal level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
+
+    @logger.level = Logger::UNKNOWN
+    msg = log :fatal, 'fatal level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::FATAL
+    msg = log :fatal, 'fatal level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
+
+    @logger.level = Logger::ERROR
+    msg = log :fatal, 'fatal level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
+
+    @logger.level = Logger::WARN
+    msg = log :fatal, 'fatal level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
+
+    @logger.level = Logger::INFO
+    msg = log :fatal, 'fatal level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
+
+    @logger.level = Logger::DEBUG
+    msg = log :fatal, 'fatal level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
+  end
+
+  def test_fatal_eh
+    @logger.level = Logger::FATAL
+    assert_equal true, @logger.fatal?
+
+    @logger.level = Logger::UNKNOWN
+    assert_equal false, @logger.fatal?
+  end
+
+  def test_error
+    msg = log :error, 'error level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
+
+    @logger.level = Logger::UNKNOWN
+    msg = log :error, 'error level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::FATAL
+    msg = log :error, 'error level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::ERROR
+    msg = log :error, 'error level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
+
+    @logger.level = Logger::WARN
+    msg = log :error, 'error level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
+
+    @logger.level = Logger::INFO
+    msg = log :error, 'error level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
+
+    @logger.level = Logger::DEBUG
+    msg = log :error, 'error level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
+  end
+
+  def test_error_eh
+    @logger.level = Logger::ERROR
+    assert_equal true, @logger.error?
+
+    @logger.level = Logger::FATAL
+    assert_equal false, @logger.error?
+  end
+
+  def test_warn
+    msg = log :warn, 'warn level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
+
+    @logger.level = Logger::UNKNOWN
+    msg = log :warn, 'warn level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::FATAL
+    msg = log :warn, 'warn level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::ERROR
+    msg = log :warn, 'warn level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::WARN
+    msg = log :warn, 'warn level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
+
+    @logger.level = Logger::INFO
+    msg = log :warn, 'warn level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
+
+    @logger.level = Logger::DEBUG
+    msg = log :warn, 'warn level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
+  end
+
+  def test_warn_eh
+    @logger.level = Logger::WARN
+    assert_equal true, @logger.warn?
+
+    @logger.level = Logger::ERROR
+    assert_equal false, @logger.warn?
+  end
+
+  def test_info
+    msg = log :info, 'info level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
+
+    @logger.level = Logger::UNKNOWN
+    msg = log :info, 'info level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::FATAL
+    msg = log :info, 'info level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::ERROR
+    msg = log :info, 'info level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::WARN
+    msg = log :info, 'info level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::INFO
+    msg = log :info, 'info level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
+
+    @logger.level = Logger::DEBUG
+    msg = log :info, 'info level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
+  end
+
+  def test_info_eh
+    @logger.level = Logger::INFO
+    assert_equal true, @logger.info?
+
+    @logger.level = Logger::WARN
+    assert_equal false, @logger.info?
+  end
+
+  def test_debug
+    msg = log :debug, 'debug level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::DEBUG], msg.severity
+
+    @logger.level = Logger::UNKNOWN
+    msg = log :debug, 'debug level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::FATAL
+    msg = log :debug, 'debug level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::ERROR
+    msg = log :debug, 'debug level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::WARN
+    msg = log :debug, 'debug level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::INFO
+    msg = log :debug, 'debug level message'
+    assert_equal '', msg.line
+
+    @logger.level = Logger::DEBUG
+    msg = log :debug, 'debug level message'
+    assert_equal LEVEL_LABEL_MAP[Logger::DEBUG], msg.severity
+  end
+
+  def test_debug_eh
+    @logger.level = Logger::DEBUG
+    assert_equal true, @logger.debug?
+
+    @logg (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]