[ruby/logger] Add reraise_write_errors keyword argument to Logger and LogDevice

This allows the user to specify exception classes to treat as regular
exceptions instead of being swallowed.  Among other things, it is
useful for having Logger work with Timeout.

Fixes Ruby Bug 9115.

https://github.com/ruby/logger/commit/436a7d680f
This commit is contained in:
Jeremy Evans 2019-08-16 09:12:06 -07:00 committed by git
parent a0469a4788
commit c698180e68
3 changed files with 24 additions and 3 deletions

View File

@ -574,10 +574,14 @@ class Logger
# - +shift_period_suffix+: sets the format for the filename suffix # - +shift_period_suffix+: sets the format for the filename suffix
# for periodic log file rotation; default is <tt>'%Y%m%d'</tt>. # for periodic log file rotation; default is <tt>'%Y%m%d'</tt>.
# See {Periodic Rotation}[rdoc-ref:Logger@Periodic+Rotation]. # See {Periodic Rotation}[rdoc-ref:Logger@Periodic+Rotation].
# - +reraise_write_errors+: An array of exception classes, which will
# be reraised if there is an error when writing to the log device.
# The default is to swallow all exceptions raised.
# #
def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG, def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG,
progname: nil, formatter: nil, datetime_format: nil, progname: nil, formatter: nil, datetime_format: nil,
binmode: false, shift_period_suffix: '%Y%m%d') binmode: false, shift_period_suffix: '%Y%m%d',
reraise_write_errors: [])
self.level = level self.level = level
self.progname = progname self.progname = progname
@default_formatter = Formatter.new @default_formatter = Formatter.new
@ -589,7 +593,8 @@ class Logger
@logdev = LogDevice.new(logdev, shift_age: shift_age, @logdev = LogDevice.new(logdev, shift_age: shift_age,
shift_size: shift_size, shift_size: shift_size,
shift_period_suffix: shift_period_suffix, shift_period_suffix: shift_period_suffix,
binmode: binmode) binmode: binmode,
reraise_write_errors: reraise_write_errors)
end end
end end

View File

@ -11,9 +11,10 @@ class Logger
attr_reader :filename attr_reader :filename
include MonitorMixin include MonitorMixin
def initialize(log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil, binmode: false) def initialize(log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil, binmode: false, reraise_write_errors: [])
@dev = @filename = @shift_age = @shift_size = @shift_period_suffix = nil @dev = @filename = @shift_age = @shift_size = @shift_period_suffix = nil
@binmode = binmode @binmode = binmode
@reraise_write_errors = reraise_write_errors
mon_initialize mon_initialize
set_dev(log) set_dev(log)
if @filename if @filename
@ -34,16 +35,22 @@ class Logger
if @shift_age and @dev.respond_to?(:stat) if @shift_age and @dev.respond_to?(:stat)
begin begin
check_shift_log check_shift_log
rescue *@reraise_write_errors
raise
rescue rescue
warn("log shifting failed. #{$!}") warn("log shifting failed. #{$!}")
end end
end end
begin begin
@dev.write(message) @dev.write(message)
rescue *@reraise_write_errors
raise
rescue rescue
warn("log writing failed. #{$!}") warn("log writing failed. #{$!}")
end end
end end
rescue *@reraise_write_errors
raise
rescue Exception => ignored rescue Exception => ignored
warn("log writing failed. #{ignored}") warn("log writing failed. #{ignored}")
end end

View File

@ -113,6 +113,15 @@ class TestLogger < Test::Unit::TestCase
assert_raise(ArgumentError) { @logger.level = 'something_wrong' } assert_raise(ArgumentError) { @logger.level = 'something_wrong' }
end end
def test_reraise_write_errors
c = Object.new
e = Class.new(StandardError)
c.define_singleton_method(:write){|*| raise e}
c.define_singleton_method(:close){}
logger = Logger.new(c, :reraise_write_errors=>[e])
assert_raise(e) { logger.warn('foo') }
end
def test_progname def test_progname
assert_nil(@logger.progname) assert_nil(@logger.progname)
@logger.progname = "name" @logger.progname = "name"