1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/logger.rb (Logger): added formatter accessor to logger for

dictating the way in which the logger should format the messages it
          displays.  Thanks to Nicholas Seckar (cf. [ruby-talk:153391]) and
          Daniel Berger.

        * lib/logger.rb (Logger): added VERSION constant.

        * lib/logger.rb: removed document for LogDevice. It is an
          implementation detail and is not a public interface.

        * test/logger/test_logger.rb: added tests.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@9151 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nahi 2005-09-13 13:13:41 +00:00
parent 9a7b502846
commit 5d0bf56235
3 changed files with 111 additions and 83 deletions

View file

@ -178,6 +178,7 @@ require 'monitor'
class Logger
VERSION = "1.2.6"
/: (\S+),v (\S+)/ =~ %q$Id$
ProgName = "#{$1}/#{$2}"
@ -202,7 +203,20 @@ class Logger
attr_accessor :progname
# Logging date-time format (string passed to +strftime+).
attr_accessor :datetime_format
def datetime_format=(datetime_format)
@default_formatter.datetime_format = datetime_format
end
def datetime_format
@default_formatter.datetime_format
end
# Logging formatter. formatter#call is invoked with 4 arguments; severity,
# time, progname and msg for each log. Bear in mind that time is a Time and
# msg is an Object that user passed and it could not be a String. It is
# expected to return a logdev#write-able Object. Default formatter is used
# when no formatter is set.
attr_accessor :formatter
alias sev_threshold level
alias sev_threshold= level=
@ -246,16 +260,17 @@ class Logger
#
# === Description
#
# Create an instance. See Logger::LogDevice.new for more information if
# required.
# Create an instance.
#
def initialize(logdev, shift_age = 0, shift_size = 1048576)
@progname = nil
@level = DEBUG
@datetime_format = nil
@default_formatter = Formatter.new
@formatter = nil
@logdev = nil
if logdev
@logdev = LogDevice.new(logdev, :shift_age => shift_age, :shift_size => shift_size)
@logdev = LogDevice.new(logdev, :shift_age => shift_age,
:shift_size => shift_size)
end
end
@ -318,13 +333,7 @@ class Logger
end
end
@logdev.write(
format_message(
format_severity(severity),
format_datetime(Time.now),
msg2str(message),
progname
)
)
format_message(format_severity(severity), Time.now, progname, message))
true
end
alias log add
@ -427,74 +436,60 @@ private
SEV_LABEL[severity] || 'ANY'
end
def format_datetime(datetime)
if @datetime_format.nil?
datetime.strftime("%Y-%m-%dT%H:%M:%S.") << "%06d " % datetime.usec
else
datetime.strftime(@datetime_format)
def format_message(severity, datetime, progname, msg)
(@formatter || @default_formatter).call(severity, datetime, progname, msg)
end
class Formatter
Format = "%s, [%s#%d] %5s -- %s: %s\n"
attr_accessor :datetime_format
def initialize
@datetime_format = nil
end
end
Format = "%s, [%s#%d] %5s -- %s: %s\n"
def format_message(severity, timestamp, msg, progname)
Format % [severity[0..0], timestamp, $$, severity, progname, msg]
end
def call(severity, time, progname, msg)
Format % [severity[0..0], format_datetime(time), $$, severity, progname,
msg2str(msg)]
end
def msg2str(msg)
case msg
when ::String
msg
when ::Exception
"#{ msg.message } (#{ msg.class })\n" << (msg.backtrace || []).join("\n")
else
msg.inspect
private
def format_datetime(time)
if @datetime_format.nil?
time.strftime("%Y-%m-%dT%H:%M:%S.") << "%06d " % time.usec
else
time.strftime(@datetime_format)
end
end
def msg2str(msg)
case msg
when ::String
msg
when ::Exception
"#{ msg.message } (#{ msg.class })\n" <<
(msg.backtrace || []).join("\n")
else
msg.inspect
end
end
end
#
# LogDevice -- Logging device.
#
class LogDevice
attr_reader :dev
attr_reader :filename
#
# == Synopsis
#
# Logger::LogDevice.new(name, :shift_age => 'daily|weekly|monthly')
# Logger::LogDevice.new(name, :shift_age => 10, :shift_size => 1024*1024)
#
# == Args
#
# +name+::
# A String (representing a filename) or an IO object (actually, anything
# that responds to +write+ and +close+). If a filename is given, then
# that file is opened for writing (and appending if it already exists),
# with +sync+ set to +true+.
# +opts+::
# Contains optional arguments for rolling ("shifting") the log file.
# <tt>:shift_age</tt> is either a description (e.g. 'daily'), or an
# integer number of log files to keep. <tt>shift_size</tt> is the maximum
# size of the log file, and is only significant is a number is given for
# <tt>shift_age</tt>.
#
# These arguments are only relevant if a filename is provided for the
# first argument.
#
# == Description
#
# Creates a LogDevice object, which is the target for log messages. Rolling
# of log files is supported (only if a filename is given; you can't roll an
# IO object). The beginning of each file created by this class is tagged
# with a header message.
#
# This class is unlikely to be used directly; it is a backend for Logger.
#
class LogDeviceMutex
include MonitorMixin
end
def initialize(log = nil, opt = {})
@dev = @filename = @shift_age = @shift_size = nil
@mutex = Object.new
@mutex.extend(MonitorMixin)
@mutex = LogDeviceMutex.new
if log.respond_to?(:write) and log.respond_to?(:close)
@dev = log
else
@ -506,12 +501,6 @@ private
end
end
#
# Log a message. If needed, the log file is rolled and the new file is
# prepared. Log device is not locked. Append open does not need to lock
# file but on an OS which supports multi I/O, records could possibly be
# mixed.
#
def write(message)
@mutex.synchronize do
if @shift_age and @dev.respond_to?(:stat)
@ -525,9 +514,6 @@ private
end
end
#
# Close the logging device.
#
def close
@mutex.synchronize do
@dev.close
@ -689,8 +675,8 @@ private
end
#
# Sets the log device for this application. See the classes Logger and
# Logger::LogDevice for an explanation of the arguments.
# Sets the log device for this application. See the class Logger for an
# explanation of the arguments.
#
def set_log(logdev, shift_age = 0, shift_size = 1024000)
@log = Logger.new(logdev, shift_age, shift_size)