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

* lib/logger.rb: imported upstream version (logger/1.2.7)

* do not raise an exception even if log writing failed.
          * do not raise ShiftingError if an aged file already exists.
            (no ShiftingError will be raised from 1.2.7, just warn() instead)
        * test/logger/test_logger.rb: ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@20345 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nahi 2008-11-24 14:55:19 +00:00
parent c1221d04f0
commit 652b6f196a
4 changed files with 220 additions and 38 deletions

View file

@ -1,3 +1,11 @@
Mon Nov 24 23:53:44 2008 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
* lib/logger.rb: imported upstream version (logger/1.2.7)
* do not raise an exception even if log writing failed.
* do not raise ShiftingError if an aged file already exists.
(no ShiftingError will be raised from 1.2.7, just warn() instead)
* test/logger/test_logger.rb: ditto.
Mon Nov 24 23:47:22 2008 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
* time.c: RDoc typo fixed.

7
NEWS
View file

@ -84,6 +84,13 @@ with all sufficient information, see the ChangeLog file.
http://www.ruby-lang.org/en/news/2008/08/23/dos-vulnerability-in-rexml/
* logger
* imported upstream version (logger/1.2.7)
* do not raise an exception even if log writing failed.
* do not raise ShiftingError if an aged file already exists.
(no ShiftingError will be raised from 1.2.7, just warn() instead)
== Changes since the 1.8.6 release
=== Configuration changes

View file

@ -1,8 +1,12 @@
# logger.rb - simple logging utility
# Copyright (C) 2000-2003, 2005 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>.
# Copyright (C) 2000-2003, 2005, 2008 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
require 'monitor'
# = logger.rb
#
# Simple logging utility.
#
# Author:: NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>
@ -11,6 +15,11 @@ require 'monitor'
# You can redistribute it and/or modify it under the same terms of Ruby's
# license; either the dual license version in 2003, or any later version.
# Revision:: $Id$
#
# See Logger for documentation.
#
#
# == Description
#
@ -149,8 +158,8 @@ require 'monitor'
#
# == Format
#
# Log messages are rendered in the output stream in a certain format. The
# default format and a sample are shown below:
# Log messages are rendered in the output stream in a certain format by
# default. The default format and a sample are shown below:
#
# Log format:
# SeverityID, [Date Time mSec #pid] SeverityLabel -- ProgName: message
@ -163,18 +172,22 @@ require 'monitor'
# logger.datetime_format = "%Y-%m-%d %H:%M:%S"
# # e.g. "2004-01-03 00:54:26"
#
# There is currently no supported way to change the overall format, but you may
# have some luck hacking the Format constant.
# You may change the overall format with Logger#formatter= method.
#
# logger.formatter = proc { |severity, datetime, progname, msg|
# "#{datetime}: #{msg}\n"
# }
# # e.g. "Thu Sep 22 08:51:08 GMT+9:00 2005: hello world"
#
class Logger
VERSION = "1.2.6"
id, name, rev = %w$Id$
ProgName = "#{name.chomp(",v")}/#{rev}"
VERSION = "1.2.7"
/: (\S+) (\S+)/ =~ %q$Id$
ProgName = "#{$1}/#{$2}"
class Error < RuntimeError; end
class ShiftingError < Error; end
class ShiftingError < Error; end # not used after 1.2.7. just for compat.
# Logging severity.
module Severity
@ -494,20 +507,27 @@ private
def write(message)
@mutex.synchronize do
if @shift_age and @dev.respond_to?(:stat)
begin
check_shift_log
rescue
raise Logger::ShiftingError.new("Shifting failed. #{$!}")
begin
if @shift_age and @dev.respond_to?(:stat)
begin
check_shift_log
rescue
warn("log shifting failed. #{$!}")
end
end
begin
@dev.write(message)
rescue
warn("log writing failed. #{$!}")
end
rescue Exception => ignored
end
@dev.write(message)
end
end
def close
@mutex.synchronize do
@dev.close
@dev.close rescue nil
end
end
@ -530,8 +550,8 @@ private
def add_log_header(file)
file.write(
"# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName]
)
"# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName]
)
end
SiD = 24 * 60 * 60
@ -544,8 +564,9 @@ private
end
else
now = Time.now
if @dev.stat.mtime <= previous_period_end(now)
shift_log_period(now)
period_end = previous_period_end(now)
if @dev.stat.mtime <= period_end
shift_log_period(period_end)
end
end
end
@ -556,19 +577,26 @@ private
File.rename("#{@filename}.#{i}", "#{@filename}.#{i+1}")
end
end
@dev.close
@dev.close rescue nil
File.rename("#{@filename}", "#{@filename}.0")
@dev = create_logfile(@filename)
return true
end
def shift_log_period(now)
postfix = previous_period_end(now).strftime("%Y%m%d") # YYYYMMDD
def shift_log_period(period_end)
postfix = period_end.strftime("%Y%m%d") # YYYYMMDD
age_file = "#{@filename}.#{postfix}"
if FileTest.exist?(age_file)
raise RuntimeError.new("'#{ age_file }' already exists.")
# try to avoid filename crash caused by Timestamp change.
idx = 0
# .99 can be overriden; avoid too much file search with 'loop do'
while idx < 100
idx += 1
age_file = "#{@filename}.#{postfix}.#{idx}"
break unless FileTest.exist?(age_file)
end
end
@dev.close
@dev.close rescue nil
File.rename("#{@filename}", age_file)
@dev = create_logfile(@filename)
return true
@ -625,8 +653,8 @@ private
class Application
include Logger::Severity
# Name of the application given at initialize.
attr_reader :appname
attr_reader :logdev
#
# == Synopsis
@ -665,9 +693,23 @@ private
status
end
# Logger for this application. See the class Logger for an explanation.
def logger
@log
end
#
# Sets the log device for this application. See the class Logger for an
# explanation of the arguments.
# Sets the logger for this application. See the class Logger for an explanation.
#
def logger=(logger)
@log = logger
@log.progname = @appname
@log.level = @level
end
#
# Sets the log device for this application. See <tt>Logger.new</tt> for an explanation
# of the arguments.
#
def set_log(logdev, shift_age = 0, shift_size = 1024000)
@log = Logger.new(logdev, shift_age, shift_size)
@ -697,6 +739,7 @@ private
private
def run
# TODO: should be an NotImplementedError
raise RuntimeError.new('Method run must be defined in the derived class.')
end
end

View file

@ -21,10 +21,13 @@ class TestLogger < Test::Unit::TestCase
def setup
@logger = Logger.new(nil)
@filename = __FILE__ + ".#{$$}"
end
def test_const_progname
assert %r!\Alogger\.rb/\S+\z! === Logger::ProgName
def teardown
unless $DEBUG
File.unlink(@filename) if File.exist?(@filename)
end
end
class Log
@ -262,8 +265,31 @@ class TestLogger < Test::Unit::TestCase
end
class TestLogDevice < Test::Unit::TestCase
def d(log)
Logger::LogDevice.new(log)
class LogExcnRaiser
def write(*arg)
raise 'disk is full'
end
def close
end
def stat
Object.new
end
end
def setup
@filename = __FILE__ + ".#{$$}"
end
def teardown
unless $DEBUG
File.unlink(@filename) if File.exist?(@filename)
end
end
def d(log, opt = {})
Logger::LogDevice.new(log, opt)
end
def test_initialize
@ -274,16 +300,21 @@ class TestLogDevice < Test::Unit::TestCase
d(nil)
end
#
filename = __FILE__ + ".#{$$}"
logdev = d(@filename)
begin
logdev = d(filename)
assert(File.exist?(filename))
assert(File.exist?(@filename))
assert(logdev.dev.sync)
assert_equal(filename, logdev.filename)
assert_equal(@filename, logdev.filename)
logdev.write('hello')
ensure
logdev.close
File.unlink(filename)
end
# create logfile whitch is already exist.
logdev = d(@filename)
logdev.write('world')
logfile = File.read(@filename)
assert_equal(2, logfile.split(/\n/).size)
assert_match(/^helloworld$/, logfile)
end
def test_write
@ -295,6 +326,15 @@ class TestLogDevice < Test::Unit::TestCase
msg = r.read
r.close
assert_equal("msg2\n\n", msg)
#
logdev = d(LogExcnRaiser.new)
begin
assert_nothing_raised do
logdev.write('hello')
end
ensure
logdev.close
end
end
def test_close
@ -377,4 +417,88 @@ class TestLogDevice < Test::Unit::TestCase
File.unlink(logfile1)
File.unlink(logfile2)
end
def test_shifting_age_variants
logger = Logger.new(@filename, 'daily')
logger.info('daily')
logger.close
logger = Logger.new(@filename, 'weekly')
logger.info('weekly')
logger.close
logger = Logger.new(@filename, 'monthly')
logger.info('monthly')
logger.close
end
def test_shifting_age
# shift_age other than 'daily', 'weekly', and 'monthly' means 'everytime'
yyyymmdd = Time.now.strftime("%Y%m%d")
filename1 = @filename + ".#{yyyymmdd}"
filename2 = @filename + ".#{yyyymmdd}.1"
filename3 = @filename + ".#{yyyymmdd}.2"
begin
logger = Logger.new(@filename, 'now')
assert(File.exist?(@filename))
assert(!File.exist?(filename1))
assert(!File.exist?(filename2))
assert(!File.exist?(filename3))
logger.info("0" * 15)
assert(File.exist?(@filename))
assert(File.exist?(filename1))
assert(!File.exist?(filename2))
assert(!File.exist?(filename3))
logger.warn("0" * 15)
assert(File.exist?(@filename))
assert(File.exist?(filename1))
assert(File.exist?(filename2))
assert(!File.exist?(filename3))
logger.error("0" * 15)
assert(File.exist?(@filename))
assert(File.exist?(filename1))
assert(File.exist?(filename2))
assert(File.exist?(filename3))
ensure
[filename1, filename2, filename3].each do |filename|
File.unlink(filename) if File.exist?(filename)
end
end
end
end
class TestLoggerApplication < Test::Unit::TestCase
def setup
@app = Logger::Application.new('appname')
@filename = __FILE__ + ".#{$$}"
end
def teardown
unless $DEBUG
File.unlink(@filename) if File.exist?(@filename)
end
end
def test_initialize
app = Logger::Application.new('appname')
assert_equal('appname', app.appname)
end
def test_start
@app.set_log(@filename)
@app.level = Logger::UNKNOWN
@app.start # logs FATAL log
assert_equal(1, File.read(@filename).split(/\n/).size)
end
def test_logger
@app.level = Logger::WARN
@app.set_log(@filename)
assert_equal(Logger::WARN, @app.logger.level)
@app.logger = logger = Logger.new(STDOUT)
assert_equal(logger, @app.logger)
assert_equal(Logger::WARN, @app.logger.level)
@app.log = @filename
assert(logger != @app.logger)
assert_equal(Logger::WARN, @app.logger.level)
end
end