New Upstream Release - ruby-logging
Ready changes
Summary
Merged new upstream version: 2.3.1 (was: 2.2.2).
Resulting package
Built on 2022-12-29T20:35 (took 5m5s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-releases ruby-logging
Lintian Result
Diff
diff --git a/.gitignore b/.gitignore
index 538924b..4b48f00 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,4 @@ tmp/
vendor/
.rbx
.rvmrc
+.tool-versions
diff --git a/.travis.yml b/.travis.yml
index 6329578..574f46a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,6 +9,8 @@ rvm:
- 2.0.0-p648
- 2.1.10
- 2.2.7
- - 2.3.4
- - 2.4.1
- - jruby-9.1.8.0
+ - 2.3.8
+ - 2.4.9
+ - 2.5.7
+ - 2.6.5
+ - jruby-9.2.9.0
diff --git a/History.txt b/History.txt
index 73b007a..5032a70 100644
--- a/History.txt
+++ b/History.txt
@@ -1,3 +1,24 @@
+== 2.3.1 / 2022-05-24
+
+Bug Fixes
+- logging hangs on JRuby when the stdout appender is closed [PR #237]
+- initialize the Logging framework when a Filter is created [PR #238]
+
+== 2.3.0 / 2020-07-04
+
+Enhancements
+- all appender output is now synchronized [PR #219]
+- renamed the `LogEvent#method` to no longer conflict with `Kernel#method` [PR #218]
+- @bhuga (not the Fortnite star) added a `raise_errors` method for debugging [PR #203]
+- thanks to @olleolleolle for keeping on top of Travis and Ruby versions
+
+Bug Fixes
+- conosle appenders can be reopened [PR #220]
+- fixed a race condition in the rolling file appender [PR #216]
+- fixed a race condition when opening log file destinations [PR #208 #217]
+- @MikaelSmith fixed a race condition in Logger creation [PR #201]
+- documentation bug fixes [PR #184 #185 #188 #194 #209]
+
== 2.2.2 / 2017-04-11
Enhancements
diff --git a/Rakefile b/Rakefile
index 6d673b0..bd16f85 100644
--- a/Rakefile
+++ b/Rakefile
@@ -26,9 +26,9 @@ Bones {
use_gmail
depend_on 'little-plugger', '~> 1.1'
- depend_on 'multi_json', '~> 1.10'
+ depend_on 'multi_json', '~> 1.14'
- depend_on 'test-unit', '~> 3.1', :development => true
+ depend_on 'test-unit', '~> 3.3', :development => true
depend_on 'bones-git', '~> 1.3', :development => true
#depend_on 'bones-rcov', :development => true
}
diff --git a/debian/changelog b/debian/changelog
index 89baeed..c9e3f22 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-ruby-logging (2.2.2-2) UNRELEASED; urgency=medium
+ruby-logging (2.3.1-1) UNRELEASED; urgency=medium
[ Hleb Valoshka ]
* Remove myself from uploaders
@@ -22,8 +22,9 @@ ruby-logging (2.2.2-2) UNRELEASED; urgency=medium
* Bump debhelper from old 12 to 13.
* Update Vcs-* headers from URL redirect.
* Use canonical URL in Vcs-Git.
+ * New upstream release.
- -- Utkarsh Gupta <guptautkarsh2102@gmail.com> Tue, 13 Aug 2019 05:55:48 +0530
+ -- Utkarsh Gupta <guptautkarsh2102@gmail.com> Thu, 29 Dec 2022 20:31:03 -0000
ruby-logging (2.2.2-1) unstable; urgency=medium
diff --git a/debian/patches/0002-Disable-assertions-not-working-when-run-by-root.patch b/debian/patches/0002-Disable-assertions-not-working-when-run-by-root.patch
index 25b2685..35fb5e0 100644
--- a/debian/patches/0002-Disable-assertions-not-working-when-run-by-root.patch
+++ b/debian/patches/0002-Disable-assertions-not-working-when-run-by-root.patch
@@ -7,23 +7,25 @@ Subject: Disable assertions not working when run by root
test/appenders/test_file.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
---- a/test/appenders/test_file.rb
-+++ b/test/appenders/test_file.rb
-@@ -30,7 +30,7 @@
- log = File.join(TMP, 'uw_dir', 'file.log')
+Index: ruby-logging.git/test/appenders/test_file.rb
+===================================================================
+--- ruby-logging.git.orig/test/appenders/test_file.rb
++++ ruby-logging.git/test/appenders/test_file.rb
+@@ -30,7 +30,7 @@ module TestAppenders
+ log = File.join(@tmpdir, 'uw_dir', 'file.log')
assert_raise(ArgumentError) do
Logging.appenders.file(log).class.assert_valid_logfile(log)
- end
+ end if Process.euid != 0
- log = File.join(TMP, 'dir')
+ log = File.join(@tmpdir, 'dir')
assert_raise(ArgumentError) do
-@@ -40,7 +40,7 @@
- log = File.join(TMP, 'uw_file')
+@@ -40,7 +40,7 @@ module TestAppenders
+ log = File.join(@tmpdir, 'uw_file')
assert_raise(ArgumentError) do
Logging.appenders.file(log).class.assert_valid_logfile(log)
- end
+ end if Process.euid != 0
- log = File.join(TMP, 'file.log')
+ log = File.join(@tmpdir, 'file.log')
assert Logging.appenders.file(log).class.assert_valid_logfile(log)
diff --git a/debian/patches/0003-remove-relative-path.patch b/debian/patches/0003-remove-relative-path.patch
index c9bc9ba..9722946 100644
--- a/debian/patches/0003-remove-relative-path.patch
+++ b/debian/patches/0003-remove-relative-path.patch
@@ -1,8 +1,10 @@
autopkgtest should take installed lib
---- a/test/setup.rb
-+++ b/test/setup.rb
-@@ -10,7 +10,7 @@
+Index: ruby-logging.git/test/setup.rb
+===================================================================
+--- ruby-logging.git.orig/test/setup.rb
++++ ruby-logging.git/test/setup.rb
+@@ -16,7 +16,7 @@ if Test::Unit::TestCase.respond_to? :tes
Test::Unit::TestCase.test_order = :random
end
diff --git a/examples/appenders.rb b/examples/appenders.rb
index 2bbf80e..12f7bf8 100644
--- a/examples/appenders.rb
+++ b/examples/appenders.rb
@@ -1,7 +1,7 @@
# :stopdoc:
#
# Appenders are used to output log events to some logging destination. The
-# same log event can be sent to multiple desitnations by associating
+# same log event can be sent to multiple destinations by associating
# multiple appenders with the logger.
#
# The following is a list of all the available appenders and a brief
diff --git a/examples/mdc.rb b/examples/mdc.rb
index b58ef1d..2f3dd87 100644
--- a/examples/mdc.rb
+++ b/examples/mdc.rb
@@ -29,9 +29,9 @@
Logging.mdc['first'] = 'John'
Logging.mdc['last'] = 'Doe'
- # in this first thread we will log some quotes by Allan Rickman
+ # in this first thread we will log some quotes by Alan Rickman
t1 = Thread.new {
- Logging.mdc['first'] = 'Allan'
+ Logging.mdc['first'] = 'Alan'
Logging.mdc['last'] = 'Rickman'
[ %q{I've never been able to plan my life. I just lurch from indecision to indecision.},
diff --git a/lib/logging.rb b/lib/logging.rb
index 78bcce1..eb4668a 100644
--- a/lib/logging.rb
+++ b/lib/logging.rb
@@ -258,6 +258,7 @@ module Logging
module_eval "MAX_LEVEL_LENGTH = #{longest.length}", __FILE__, __LINE__
self.cause_depth = nil unless defined? @cause_depth
+ self.raise_errors = false unless defined? @raise_errors
initialize_plugins
levels.keys
@@ -268,8 +269,8 @@ module Logging
#
# Defines the default _obj_format_ method to use when converting objects
# into string representations for logging. _obj_format_ can be one of
- # <tt>:string</tt>, <tt>:inspect</tt>, or <tt>:yaml</tt>. These
- # formatting commands map to the following object methods
+ # <tt>:string</tt>, <tt>:inspect</tt>, <tt>:json</tt> or <tt>:yaml</tt>.
+ # These formatting commands map to the following object methods
#
# * :string => to_s
# * :inspect => inspect
@@ -277,7 +278,7 @@ module Logging
# * :json => MultiJson.encode(obj)
#
# An +ArgumentError+ is raised if anything other than +:string+,
- # +:inspect+, +:yaml+ is passed to this method.
+ # +:inspect+, +:json+ or +:yaml+ is passed to this method.
#
def format_as( f )
f = f.intern if f.instance_of? String
@@ -490,6 +491,21 @@ module Logging
io
end
+ # Raise an exception when an error is encountered while logging, be it with
+ # a backing store, formatter, or anything else. You probably wouldn't want
+ # to enable this outside of test.
+ #
+ # Not that only one error will ever be raised per logging backend, as
+ # backends that raise errors on write will be set to :off.
+ def raise_errors=(boolean)
+ @raise_errors = boolean
+ end
+
+ # Whether or not we should raise errors when writing logs.
+ def raise_errors?
+ @raise_errors
+ end
+
# :stopdoc:
# Convert the given level into a canonical form - a lowercase string.
def levelify( level )
@@ -518,7 +534,7 @@ module Logging
# exception will be raised again.
def log_internal_error( err )
log_internal(-2) { err }
- raise err if Thread.abort_on_exception
+ raise err if ::Logging.raise_errors?
end
# Close all appenders
@@ -569,8 +585,7 @@ module Logging
require libpath('logging/diagnostic_context')
require libpath('logging/rails_compat')
-end # module Logging
-
+end
# This finalizer will close all the appenders that exist in the system.
# This is needed for closing IO streams and connections to the syslog server
diff --git a/lib/logging/appender.rb b/lib/logging/appender.rb
index 8724065..8d7abd1 100644
--- a/lib/logging/appender.rb
+++ b/lib/logging/appender.rb
@@ -9,11 +9,6 @@ module Logging
# Each subclass should provide a +write+ method that will write log
# messages to the logging destination.
#
-# A private +sync+ method is provided for use by subclasses. It is used to
-# synchronize writes to the logging destination, and can be used by
-# subclasses to synchronize the closing or flushing of the logging
-# destination.
-#
class Appender
attr_reader :name, :layout, :level, :filters
@@ -263,13 +258,9 @@ class Appender
"<%s name=\"%s\">" % [self.class.name.sub(%r/^Logging::/, ''), self.name]
end
- # Returns the current Encoding for the appender or nil if an encoding has
- # not been set.
- #
- def encoding
- return @encoding if defined? @encoding
- @encoding = Object.const_defined?(:Encoding) ? Encoding.default_external : nil
- end
+ # Returns the current Encoding for the appender. The default external econding
+ # will be used if none is explicitly set.
+ attr_reader :encoding
# Set the appender encoding to the given value. The value can either be an
# Encoding instance or a String or Symbol referring to a valid encoding.
@@ -282,9 +273,9 @@ class Appender
# Raises ArgumentError if the value is not a valid encoding.
def encoding=( value )
if value.nil?
- @encoding = nil
+ @encoding = Encoding.default_external
else
- @encoding = Object.const_defined?(:Encoding) ? Encoding.find(value.to_s) : nil
+ @encoding = Encoding.find(value.to_s)
end
end
@@ -328,17 +319,6 @@ private
nil
end
- # call-seq:
- # sync { block }
- #
- # Obtains an exclusive lock, runs the block, and releases the lock when
- # the block completes. This method is re-entrant so that a single thread
- # can call +sync+ multiple times without hanging the thread.
- #
- def sync( &block )
- @mutex.synchronize(&block)
- end
-
end # class Appender
end # module Logging
diff --git a/lib/logging/appenders/buffering.rb b/lib/logging/appenders/buffering.rb
index afbeedf..6a6de49 100644
--- a/lib/logging/appenders/buffering.rb
+++ b/lib/logging/appenders/buffering.rb
@@ -79,7 +79,7 @@ module Logging::Appenders
return self if @buffer.empty?
ary = nil
- sync {
+ @mutex.synchronize {
ary = @buffer.dup
@buffer.clear
}
@@ -100,7 +100,7 @@ module Logging::Appenders
# Clear the underlying buffer of all log events. These events will not be
# appended to the logging destination; they will be lost.
def clear!
- sync { @buffer.clear }
+ @mutex.synchronize { @buffer.clear }
end
# Configure the levels that will trigger an immediate flush of the
@@ -285,7 +285,7 @@ module Logging::Appenders
canonical_write(str)
else
str = str.force_encoding(encoding) if encoding && str.encoding != encoding
- sync {
+ @mutex.synchronize {
@buffer << str
}
flush_now = @buffer.length >= @auto_flushing || immediate?(event)
diff --git a/lib/logging/appenders/console.rb b/lib/logging/appenders/console.rb
index 0b08f70..fe4871c 100644
--- a/lib/logging/appenders/console.rb
+++ b/lib/logging/appenders/console.rb
@@ -22,17 +22,39 @@ module Logging::Appenders
#
def initialize( *args )
name = self.class.name.split("::").last.downcase
- io = Object.const_get(name.upcase)
opts = args.last.is_a?(Hash) ? args.pop : {}
name = args.shift unless args.empty?
- opts[:encoding] = io.external_encoding if io.respond_to? :external_encoding
+ io = open_fd
+ opts[:encoding] = io.external_encoding
super(name, io, opts)
- rescue NameError
- raise RuntimeError, "Please do not use the `Logging::Appenders::Console` class directly - " +
- "use `Logging::Appenders::Stdout` and `Logging::Appenders::Stderr` instead"
+ end
+
+ # Reopen the connection to the underlying logging destination. If the
+ # connection is currently closed then it will be opened. If the connection
+ # is currently open then it will be closed and immediately reopened.
+ def reopen
+ @mutex.synchronize {
+ flush if defined? @io && @io
+ @io = open_fd
+ }
+ super
+ self
+ end
+
+ private
+
+ def open_fd
+ case self.class.name
+ when "Logging::Appenders::Stdout"; STDOUT
+ when "Logging::Appenders::Stderr"; STDERR
+ else
+ raise RuntimeError, "Please do not use the `Logging::Appenders::Console` class directly - " +
+ "use `Logging::Appenders::Stdout` and `Logging::Appenders::Stderr` instead" +
+ " [class #{self.class.name}]"
+ end
end
end
@@ -43,7 +65,6 @@ module Logging::Appenders
Stderr = Class.new(Console)
# Accessor / Factory for the Stdout appender.
- #
def self.stdout( *args )
if args.empty?
return self['stdout'] || ::Logging::Appenders::Stdout.new
@@ -52,7 +73,6 @@ module Logging::Appenders
end
# Accessor / Factory for the Stderr appender.
- #
def self.stderr( *args )
if args.empty?
return self['stderr'] || ::Logging::Appenders::Stderr.new
diff --git a/lib/logging/appenders/file.rb b/lib/logging/appenders/file.rb
index 8b3fea6..d2ac2a2 100644
--- a/lib/logging/appenders/file.rb
+++ b/lib/logging/appenders/file.rb
@@ -2,14 +2,12 @@
module Logging::Appenders
# Accessor / Factory for the File appender.
- #
def self.file( *args )
fail ArgumentError, '::Logging::Appenders::File needs a name as first argument.' if args.empty?
::Logging::Appenders::File.new(*args)
end
# This class provides an Appender that can write to a File.
- #
class File < ::Logging::Appenders::IO
# call-seq:
@@ -21,15 +19,14 @@ module Logging::Appenders
# writable.
#
# An +ArgumentError+ is raised if any of these assertions fail.
- #
def self.assert_valid_logfile( fn )
if ::File.exist?(fn)
- if not ::File.file?(fn)
+ if !::File.file?(fn)
raise ArgumentError, "#{fn} is not a regular file"
- elsif not ::File.writable?(fn)
+ elsif !::File.writable?(fn)
raise ArgumentError, "#{fn} is not writeable"
end
- elsif not ::File.writable?(::File.dirname(fn))
+ elsif !::File.writable?(::File.dirname(fn))
raise ArgumentError, "#{::File.dirname(fn)} is not writable"
end
true
@@ -45,41 +42,65 @@ module Logging::Appenders
# created. If the :truncate option is set to +true+ then the file will
# be truncated before writing begins; otherwise, log messages will be
# appended to the file.
- #
def initialize( name, opts = {} )
- @fn = opts.fetch(:filename, name)
- raise ArgumentError, 'no filename was given' if @fn.nil?
+ @filename = opts.fetch(:filename, name)
+ raise ArgumentError, 'no filename was given' if @filename.nil?
- @fn = ::File.expand_path(@fn)
- self.class.assert_valid_logfile(@fn)
- @mode = opts.fetch(:truncate, false) ? 'w' : 'a'
+ @filename = ::File.expand_path(@filename).freeze
+ self.class.assert_valid_logfile(@filename)
self.encoding = opts.fetch(:encoding, self.encoding)
- @mode = "#{@mode}:#{self.encoding}" if self.encoding
- super(name, ::File.new(@fn, @mode), opts)
+ io = open_file
+ super(name, io, opts)
+
+ truncate if opts.fetch(:truncate, false)
end
# Returns the path to the logfile.
- #
- def filename() @fn.dup end
+ attr_reader :filename
# Reopen the connection to the underlying logging destination. If the
# connection is currently closed then it will be opened. If the connection
# is currently open then it will be closed and immediately opened.
- #
def reopen
@mutex.synchronize {
- if defined? @io and @io
+ if defined? @io && @io
flush
@io.close rescue nil
end
- @io = ::File.new(@fn, @mode)
+ @io = open_file
}
super
self
end
- end # FileAppender
-end # Logging::Appenders
+ protected
+
+ def truncate
+ @mutex.synchronize {
+ begin
+ @io.flock(::File::LOCK_EX)
+ @io.truncate(0)
+ ensure
+ @io.flock(::File::LOCK_UN)
+ end
+ }
+ end
+
+ def open_file
+ mode = ::File::WRONLY | ::File::APPEND
+ ::File.open(filename, mode: mode, external_encoding: encoding)
+ rescue Errno::ENOENT
+ create_file
+ end
+
+ def create_file
+ mode = ::File::WRONLY | ::File::APPEND | ::File::CREAT | ::File::EXCL
+ ::File.open(filename, mode: mode, external_encoding: encoding)
+ rescue Errno::EEXIST
+ open_file
+ end
+ end
+end
diff --git a/lib/logging/appenders/io.rb b/lib/logging/appenders/io.rb
index 4c6fcee..4b12011 100644
--- a/lib/logging/appenders/io.rb
+++ b/lib/logging/appenders/io.rb
@@ -2,7 +2,6 @@
module Logging::Appenders
# Accessor / Factory for the IO appender.
- #
def self.io( *args )
return ::Logging::Appenders::IO if args.empty?
::Logging::Appenders::IO.new(*args)
@@ -10,14 +9,12 @@ module Logging::Appenders
# This class provides an Appender that can write to any IO stream
# configured for writing.
- #
class IO < ::Logging::Appender
include Buffering
# The method that will be used to close the IO stream. Defaults to :close
# but can be :close_read, :close_write or nil. When nil, the IO stream
# will not be closed when the appender's close method is called.
- #
attr_accessor :close_method
# call-seq:
@@ -26,7 +23,6 @@ module Logging::Appenders
#
# Creates a new IO Appender using the given name that will use the _io_
# stream as the logging destination.
- #
def initialize( name, io, opts = {} )
unless io.respond_to? :write
raise TypeError, "expecting an IO object but got '#{io.class.name}'"
@@ -47,13 +43,12 @@ module Logging::Appenders
# destination if the _footer_ flag is set to +true+. Log events will
# no longer be written to the logging destination after the appender
# is closed.
- #
def close( *args )
return self if @io.nil?
super
io, @io = @io, nil
- unless [STDIN, STDERR, STDOUT].include?(io)
+ if ![STDIN, STDERR, STDOUT].include?(io)
io.send(@close_method) if @close_method && io.respond_to?(@close_method)
end
rescue IOError
@@ -61,16 +56,25 @@ module Logging::Appenders
return self
end
+ # Reopen the connection to the underlying logging destination. If the
+ # connection is currently closed then it will be opened. If the connection
+ # is currently open then it will be closed and immediately opened. If
+ # supported, the IO will have its sync mode set to `true` so that all writes
+ # are immediately flushed to the underlying operating system.
+ def reopen
+ super
+ @io.sync = true if @io.respond_to? :sync=
+ self
+ end
private
# This method is called by the buffering code when messages need to be
# written to the logging destination.
- #
def canonical_write( str )
return self if @io.nil?
str = str.force_encoding(encoding) if encoding && str.encoding != encoding
- @io.write str
+ @mutex.synchronize { @io.write str }
self
rescue StandardError => err
handle_internal_error(err)
@@ -82,6 +86,5 @@ module Logging::Appenders
::Logging.log_internal {"appender #{name.inspect} has been disabled"}
::Logging.log_internal_error(err)
end
-
- end # IO
-end # Logging::Appenders
+ end
+end
diff --git a/lib/logging/appenders/rolling_file.rb b/lib/logging/appenders/rolling_file.rb
index 61f3e64..f795600 100644
--- a/lib/logging/appenders/rolling_file.rb
+++ b/lib/logging/appenders/rolling_file.rb
@@ -84,24 +84,32 @@ module Logging::Appenders
# 'date'.
#
def initialize( name, opts = {} )
- @roller = Roller.new name, opts
+ @roller = Roller.new(
+ opts.fetch(:filename, name),
+ age: opts.fetch(:age, nil),
+ size: opts.fetch(:size, nil),
+ roll_by: opts.fetch(:roll_by, nil),
+ keep: opts.fetch(:keep, nil)
+ )
# grab our options
@size = opts.fetch(:size, nil)
@size = Integer(@size) unless @size.nil?
- @age_fn = filename + '.age'
+ @age_fn = self.filename + '.age'
@age_fn_mtime = nil
@age = opts.fetch(:age, nil)
# create our `sufficiently_aged?` method
build_singleton_methods
- FileUtils.touch(@age_fn) if @age && !test(?f, @age_fn)
+ FileUtils.touch(@age_fn) if @age && !::File.file?(@age_fn)
# we are opening the file in read/write mode so that a shared lock can
# be used on the file descriptor => http://pubs.opengroup.org/onlinepubs/009695399/functions/fcntl.html
- @mode = encoding ? "a+:#{encoding}" : 'a+'
- super(name, ::File.new(filename, @mode), opts)
+ self.encoding = opts.fetch(:encoding, self.encoding)
+
+ io = open_file
+ super(name, io, opts)
# if the truncate flag was set to true, then roll
roll_now = opts.fetch(:truncate, false)
@@ -121,11 +129,11 @@ module Logging::Appenders
# is currently open then it will be closed and immediately opened.
def reopen
@mutex.synchronize {
- if defined?(@io) && @io
+ if defined? @io && @io
flush
@io.close rescue nil
end
- @io = ::File.new(filename, @mode)
+ @io = open_file
}
super
self
@@ -134,6 +142,20 @@ module Logging::Appenders
private
+ def open_file
+ mode = ::File::RDWR | ::File::APPEND
+ ::File.open(filename, mode: mode, external_encoding: encoding)
+ rescue Errno::ENOENT
+ create_file
+ end
+
+ def create_file
+ mode = ::File::RDWR | ::File::APPEND | ::File::CREAT | ::File::EXCL
+ ::File.open(filename, mode: mode, external_encoding: encoding)
+ rescue Errno::EEXIST
+ open_file
+ end
+
# Returns the file name to use as the temporary copy location. We are
# using copy-and-truncate semantics for rolling files so that the IO
# file descriptor remains valid during rolling.
@@ -157,14 +179,18 @@ module Logging::Appenders
return self if @io.nil?
str = str.force_encoding(encoding) if encoding && str.encoding != encoding
- @io.flock_sh { @io.write str }
+ @mutex.synchronize {
+ @io.flock_sh { @io.write str }
+ }
if roll_required?
- @io.flock? {
- @age_fn_mtime = nil
- copy_truncate if roll_required?
+ @mutex.synchronize {
+ @io.flock? {
+ @age_fn_mtime = nil
+ copy_truncate if roll_required?
+ }
+ @roller.roll_files
}
- @roller.roll_files
end
self
rescue StandardError => err
@@ -193,7 +219,7 @@ module Logging::Appenders
def copy_truncate
return unless ::File.exist?(filename)
FileUtils.concat filename, copy_file
- @io.truncate 0
+ @io.truncate(0)
# touch the age file if needed
if @age
@@ -255,22 +281,22 @@ module Logging::Appenders
# Create a new roller. See the RollingFile#initialize documentation for
# the list of options.
#
- # name - The appender name as a String
- # opts - The options Hash
+ # filename - the name of the file to roll
+ # age - the age of the file at which it should be rolled
+ # size - the size of the file in bytes at which it should be rolled
+ # roll_by - roll either by 'number' or 'date'
+ # keep - the number of log files to keep when rolling
#
- def initialize( name, opts )
+ def initialize( filename, age: nil, size: nil, roll_by: nil, keep: nil )
# raise an error if a filename was not given
- @fn = opts.fetch(:filename, name)
+ @fn = filename
raise ArgumentError, 'no filename was given' if @fn.nil?
if (m = RGXP.match @fn)
@roll_by = ("#{m[2]}%d" == m[1]) ? :number : :date
else
- age = opts.fetch(:age, nil)
- size = opts.fetch(:size, nil)
-
@roll_by =
- case opts.fetch(:roll_by, nil)
+ case roll_by
when 'number'; :number
when 'date'; :date
else
@@ -293,8 +319,7 @@ module Logging::Appenders
::Logging::Appenders::File.assert_valid_logfile(filename)
@roll = false
- @keep = opts.fetch(:keep, nil)
- @keep = Integer(keep) unless keep.nil?
+ @keep = keep.nil? ? nil : Integer(keep)
end
attr_reader :keep, :roll_by
@@ -347,7 +372,6 @@ module Logging::Appenders
files.delete copy_file
self.send "roll_by_#{roll_by}", files
-
nil
ensure
self.roll = false
diff --git a/lib/logging/appenders/string_io.rb b/lib/logging/appenders/string_io.rb
index 4e9faec..7651740 100644
--- a/lib/logging/appenders/string_io.rb
+++ b/lib/logging/appenders/string_io.rb
@@ -62,7 +62,7 @@ module Logging::Appenders
%w[read readline readlines].each do|m|
class_eval <<-CODE, __FILE__, __LINE__+1
def #{m}( *args )
- sync {
+ @mutex.synchronize {
begin
@sio.seek @pos
rv = @sio.#{m}(*args)
diff --git a/lib/logging/appenders/syslog.rb b/lib/logging/appenders/syslog.rb
index 9850ee6..818e0b4 100644
--- a/lib/logging/appenders/syslog.rb
+++ b/lib/logging/appenders/syslog.rb
@@ -188,7 +188,7 @@ module Logging::Appenders
end
return if message.empty?
- @syslog.log(pri, '%s', message)
+ @mutex.synchronize { @syslog.log(pri, '%s', message) }
self
end
@@ -205,11 +205,10 @@ module Logging::Appenders
level = level.to_s.upcase
self.class.const_get level
else
- raise ArgumentError, "unkonwn level '#{level}'"
+ raise ArgumentError, "unknown level '#{level}'"
end
end
end # Syslog
end # Logging::Appenders
end # HAVE_SYSLOG
-
diff --git a/lib/logging/filter.rb b/lib/logging/filter.rb
index f23eee5..33f935f 100644
--- a/lib/logging/filter.rb
+++ b/lib/logging/filter.rb
@@ -8,10 +8,17 @@ module Logging
# Otherwise the `allow` method should return `nil`.
class Filter
- # Returns the event if it should be allowed into the log. Returns `nil` if
- # the event should _not_ be allowed into the log. Subclasses should override
- # this method and provide their own filtering semantics.
- def allow( event )
+ # Creates a new level filter that will pass all log events. Create a
+ # subclass and override the `allow` method to filter log events.
+ def initialize
+ ::Logging.init unless ::Logging.initialized?
+ end
+
+ # Returns the event if it should be forwarded to the logging appender.
+ # Returns `nil` if the event should _not_ be forwarded to the logging
+ # appender. Subclasses should override this method and provide their own
+ # filtering semantics.
+ def allow(event)
event
end
end
diff --git a/lib/logging/filters.rb b/lib/logging/filters.rb
index e3e6f3c..3152b87 100644
--- a/lib/logging/filters.rb
+++ b/lib/logging/filters.rb
@@ -1,4 +1,4 @@
module Logging
module Filters ; end
require libpath('logging/filters/level')
-end
\ No newline at end of file
+end
diff --git a/lib/logging/filters/level.rb b/lib/logging/filters/level.rb
index f5dc4f1..09138f6 100644
--- a/lib/logging/filters/level.rb
+++ b/lib/logging/filters/level.rb
@@ -4,8 +4,7 @@ module Logging
module Filters
# The `Level` filter class provides a simple level-based filtering mechanism
- # that filters messages to only include those from an enumerated list of
- # levels to log.
+ # that allows events whose log level matches a preconfigured list of values.
class Level < ::Logging::Filter
# Creates a new level filter that will only allow the given _levels_ to
@@ -15,15 +14,19 @@ module Logging
# Examples
# Logging::Filters::Level.new(:debug, :info)
#
- def initialize( *levels )
- levels = levels.map { |level| ::Logging::level_num(level) }
- @levels = Set.new levels
+ def initialize(*levels)
+ super()
+ levels = levels.flatten.map {|level| ::Logging::level_num(level)}
+ @levels = Set.new(levels)
end
- def allow( event )
+ # Returns the event if it should be forwarded to the logging appender.
+ # Otherwise, `nil` is returned. The log event is allowed if the
+ # `event.level` matches one of the levels provided to the filter when it
+ # was constructred.
+ def allow(event)
@levels.include?(event.level) ? event : nil
end
-
end
end
end
diff --git a/lib/logging/layouts/parseable.rb b/lib/logging/layouts/parseable.rb
index f6df0f8..5046606 100644
--- a/lib/logging/layouts/parseable.rb
+++ b/lib/logging/layouts/parseable.rb
@@ -103,7 +103,7 @@ module Logging::Layouts
'message' => 'format_obj(event.data)'.freeze,
'file' => 'event.file'.freeze,
'line' => 'event.line'.freeze,
- 'method' => 'event.method'.freeze,
+ 'method' => 'event.method_name'.freeze,
'hostname' => "'#{Socket.gethostname}'".freeze,
'pid' => 'Process.pid'.freeze,
'millis' => 'Integer((event.time-@created_at)*1000)'.freeze,
diff --git a/lib/logging/layouts/pattern.rb b/lib/logging/layouts/pattern.rb
index 301e432..45bb39e 100644
--- a/lib/logging/layouts/pattern.rb
+++ b/lib/logging/layouts/pattern.rb
@@ -307,7 +307,7 @@ module Logging::Layouts
'l' => '::Logging::LNAMES[event.level]'.freeze,
'L' => 'event.line'.freeze,
'm' => 'format_obj(event.data)'.freeze,
- 'M' => 'event.method'.freeze,
+ 'M' => 'event.method_name'.freeze,
'h' => "'#{Socket.gethostname}'".freeze,
'p' => 'Process.pid'.freeze,
'r' => 'Integer((event.time-@created_at)*1000).to_s'.freeze,
diff --git a/lib/logging/log_event.rb b/lib/logging/log_event.rb
index b66fe63..35ce66f 100644
--- a/lib/logging/log_event.rb
+++ b/lib/logging/log_event.rb
@@ -12,10 +12,11 @@ module Logging
# * $3 == method name (might be nil)
CALLER_RGXP = %r/([-\.\/\(\)\w]+):(\d+)(?::in `([^']+)')?/o
#CALLER_INDEX = 2
- CALLER_INDEX = ((defined? JRUBY_VERSION and JRUBY_VERSION > '1.6') or (defined? RUBY_ENGINE and RUBY_ENGINE[%r/^rbx/i])) ? 1 : 2
+ CALLER_INDEX = ((defined?(JRUBY_VERSION) && JRUBY_VERSION > '1.6' && JRUBY_VERSION < '9.0') ||
+ (defined?(RUBY_ENGINE) && RUBY_ENGINE[%r/^rbx/i])) ? 1 : 2
# :startdoc:
- attr_accessor :logger, :level, :data, :time, :file, :line, :method
+ attr_accessor :logger, :level, :data, :time, :file, :line, :method_name
# call-seq:
# LogEvent.new( logger, level, [data], caller_tracing )
@@ -36,15 +37,15 @@ module Logging
return if stack.nil?
match = CALLER_RGXP.match(stack)
- self.file = match[1]
- self.line = Integer(match[2])
- self.method = match[3] unless match[3].nil?
+ self.file = match[1]
+ self.line = Integer(match[2])
+ self.method_name = match[3] unless match[3].nil?
if (bp = ::Logging.basepath) && !bp.empty? && file.index(bp) == 0
self.file = file.slice(bp.length + 1, file.length - bp.length)
end
else
- self.file = self.line = self.method = ''
+ self.file = self.line = self.method_name = ''
end
end
end
diff --git a/lib/logging/logger.rb b/lib/logging/logger.rb
index a6a2e85..9fcec72 100644
--- a/lib/logging/logger.rb
+++ b/lib/logging/logger.rb
@@ -24,8 +24,6 @@ module Logging
#
class Logger
- @mutex = Mutex.new # :nodoc:
-
# Returns the root logger.
def self.root
::Logging::Repository.instance[:root]
@@ -48,7 +46,10 @@ module Logging
logger = repo[name]
return logger unless logger.nil?
- @mutex.synchronize do
+ # Share the same mutex that's used by 'define_log_methods' because
+ # it iterates over the hash of loggers, and adding a new key to a hash
+ # while iterating over it produces an error.
+ ::Logging::Logger.mutex.synchronize do
logger = repo[name]
return logger unless logger.nil? # thread-safe double checking
@@ -118,6 +119,14 @@ module Logging
code.join("\n")
end
+ @mutex = ReentrantMutex.new
+
+ # Returns a global ReentrantMutex for use when creating Logger instances
+ # and/or updating log levels.
+ def self.mutex
+ @mutex
+ end
+
attr_reader :name, :parent, :additive, :caller_tracing
# call-seq:
@@ -411,7 +420,7 @@ module Logging
def define_log_methods( force = false, code = nil )
return if has_own_level? and !force
- ::Logging::Logger._reentrant_mutex.synchronize do
+ ::Logging::Logger.mutex.synchronize do
::Logging::Logger.define_log_methods(self)
::Logging::Repository.instance.children(name).each do |child|
child.define_log_methods
@@ -423,12 +432,6 @@ module Logging
# :stopdoc:
public
- @reentrant_mutex = ReentrantMutex.new
-
- def self._reentrant_mutex
- @reentrant_mutex
- end
-
# call-seq:
# _meta_eval( code )
#
@@ -511,6 +514,5 @@ module Logging
end
# :startdoc:
- end # Logger
-end # Logging
-
+ end
+end
diff --git a/lib/logging/proxy.rb b/lib/logging/proxy.rb
index 798e3b3..a9f6719 100644
--- a/lib/logging/proxy.rb
+++ b/lib/logging/proxy.rb
@@ -47,7 +47,7 @@ module Logging
# All hail the magic of method missing. Here is where we are going to log
# the method call and then forward to the proxied object. The return value
- # from the proxied objet method call is passed back.
+ # from the proxied object method call is passed back.
#
def method_missing( name, *args, &block )
@logger << "#@leader#{name}(#{args.inspect[1..-2]})\n"
diff --git a/lib/logging/version.rb b/lib/logging/version.rb
index cd0c0e9..8a3964c 100644
--- a/lib/logging/version.rb
+++ b/lib/logging/version.rb
@@ -1,5 +1,5 @@
module Logging
- VERSION = "2.2.2".freeze
+ VERSION = "2.3.1".freeze
# Returns the version string for the library.
def self.version
diff --git a/logging.gemspec b/logging.gemspec
index a5ee2c8..e1e7c5d 100644
--- a/logging.gemspec
+++ b/logging.gemspec
@@ -1,45 +1,44 @@
# -*- encoding: utf-8 -*-
-# stub: logging 2.1.0.48 ruby lib
+# stub: logging 2.3.0 ruby lib
Gem::Specification.new do |s|
s.name = "logging".freeze
- s.version = "2.1.0.48"
+ s.version = "2.3.0"
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze]
s.authors = ["Tim Pease".freeze]
- s.date = "2017-01-08"
+ s.date = "2020-07-04"
s.description = "**Logging** is a flexible logging library for use in Ruby programs based on the\ndesign of Java's log4j library. It features a hierarchical logging system,\ncustom level names, multiple output destinations per log event, custom\nformatting, and more.".freeze
s.email = "tim.pease@gmail.com".freeze
s.extra_rdoc_files = ["History.txt".freeze]
- s.files = [".gitignore".freeze, ".travis.yml".freeze, "History.txt".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "examples/appenders.rb".freeze, "examples/classes.rb".freeze, "examples/colorization.rb".freeze, "examples/custom_log_levels.rb".freeze, "examples/fork.rb".freeze, "examples/formatting.rb".freeze, "examples/hierarchies.rb".freeze, "examples/layouts.rb".freeze, "examples/lazy.rb".freeze, "examples/loggers.rb".freeze, "examples/mdc.rb".freeze, "examples/names.rb".freeze, "examples/rails4.rb".freeze, "examples/reusing_layouts.rb".freeze, "examples/rspec_integration.rb".freeze, "examples/simple.rb".freeze, "lib/logging.rb".freeze, "lib/logging/appender.rb".freeze, "lib/logging/appenders.rb".freeze, "lib/logging/appenders/buffering.rb".freeze, "lib/logging/appenders/console.rb".freeze, "lib/logging/appenders/file.rb".freeze, "lib/logging/appenders/io.rb".freeze, "lib/logging/appenders/rolling_file.rb".freeze, "lib/logging/appenders/string_io.rb".freeze, "lib/logging/appenders/syslog.rb".freeze, "lib/logging/color_scheme.rb".freeze, "lib/logging/diagnostic_context.rb".freeze, "lib/logging/filter.rb".freeze, "lib/logging/filters.rb".freeze, "lib/logging/filters/level.rb".freeze, "lib/logging/layout.rb".freeze, "lib/logging/layouts.rb".freeze, "lib/logging/layouts/basic.rb".freeze, "lib/logging/layouts/parseable.rb".freeze, "lib/logging/layouts/pattern.rb".freeze, "lib/logging/log_event.rb".freeze, "lib/logging/logger.rb".freeze, "lib/logging/proxy.rb".freeze, "lib/logging/rails_compat.rb".freeze, "lib/logging/repository.rb".freeze, "lib/logging/root_logger.rb".freeze, "lib/logging/utils.rb".freeze, "lib/logging/version.rb".freeze, "lib/rspec/logging_helper.rb".freeze, "lib/spec/logging_helper.rb".freeze, "logging.gemspec".freeze, "script/bootstrap".freeze, "script/console".freeze, "test/appenders/test_async_flushing.rb".freeze, "test/appenders/test_buffered_io.rb".freeze, "test/appenders/test_console.rb".freeze, "test/appenders/test_file.rb".freeze, "test/appenders/test_io.rb".freeze, "test/appenders/test_rolling_file.rb".freeze, "test/appenders/test_string_io.rb".freeze, "test/appenders/test_syslog.rb".freeze, "test/benchmark.rb".freeze, "test/layouts/test_basic.rb".freeze, "test/layouts/test_color_pattern.rb".freeze, "test/layouts/test_json.rb".freeze, "test/layouts/test_pattern.rb".freeze, "test/layouts/test_yaml.rb".freeze, "test/performance.rb".freeze, "test/setup.rb".freeze, "test/test_appender.rb".freeze, "test/test_color_scheme.rb".freeze, "test/test_filter.rb".freeze, "test/test_layout.rb".freeze, "test/test_log_event.rb".freeze, "test/test_logger.rb".freeze, "test/test_logging.rb".freeze, "test/test_mapped_diagnostic_context.rb".freeze, "test/test_nested_diagnostic_context.rb".freeze, "test/test_proxy.rb".freeze, "test/test_repository.rb".freeze, "test/test_root_logger.rb".freeze, "test/test_utils.rb".freeze]
+ s.files = [".gitignore".freeze, ".travis.yml".freeze, "History.txt".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "examples/appenders.rb".freeze, "examples/classes.rb".freeze, "examples/colorization.rb".freeze, "examples/custom_log_levels.rb".freeze, "examples/fork.rb".freeze, "examples/formatting.rb".freeze, "examples/hierarchies.rb".freeze, "examples/layouts.rb".freeze, "examples/lazy.rb".freeze, "examples/loggers.rb".freeze, "examples/mdc.rb".freeze, "examples/names.rb".freeze, "examples/rails4.rb".freeze, "examples/reusing_layouts.rb".freeze, "examples/rspec_integration.rb".freeze, "examples/simple.rb".freeze, "lib/logging.rb".freeze, "lib/logging/appender.rb".freeze, "lib/logging/appenders.rb".freeze, "lib/logging/appenders/buffering.rb".freeze, "lib/logging/appenders/console.rb".freeze, "lib/logging/appenders/file.rb".freeze, "lib/logging/appenders/io.rb".freeze, "lib/logging/appenders/rolling_file.rb".freeze, "lib/logging/appenders/string_io.rb".freeze, "lib/logging/appenders/syslog.rb".freeze, "lib/logging/color_scheme.rb".freeze, "lib/logging/diagnostic_context.rb".freeze, "lib/logging/filter.rb".freeze, "lib/logging/filters.rb".freeze, "lib/logging/filters/level.rb".freeze, "lib/logging/layout.rb".freeze, "lib/logging/layouts.rb".freeze, "lib/logging/layouts/basic.rb".freeze, "lib/logging/layouts/parseable.rb".freeze, "lib/logging/layouts/pattern.rb".freeze, "lib/logging/log_event.rb".freeze, "lib/logging/logger.rb".freeze, "lib/logging/proxy.rb".freeze, "lib/logging/rails_compat.rb".freeze, "lib/logging/repository.rb".freeze, "lib/logging/root_logger.rb".freeze, "lib/logging/utils.rb".freeze, "lib/logging/version.rb".freeze, "lib/rspec/logging_helper.rb".freeze, "lib/spec/logging_helper.rb".freeze, "logging.gemspec".freeze, "script/bootstrap".freeze, "script/console".freeze, "test/appenders/test_async_flushing.rb".freeze, "test/appenders/test_buffered_io.rb".freeze, "test/appenders/test_console.rb".freeze, "test/appenders/test_file.rb".freeze, "test/appenders/test_io.rb".freeze, "test/appenders/test_rolling_file.rb".freeze, "test/appenders/test_string_io.rb".freeze, "test/appenders/test_syslog.rb".freeze, "test/benchmark.rb".freeze, "test/layouts/test_basic.rb".freeze, "test/layouts/test_color_pattern.rb".freeze, "test/layouts/test_json.rb".freeze, "test/layouts/test_nested_exceptions.rb".freeze, "test/layouts/test_pattern.rb".freeze, "test/layouts/test_yaml.rb".freeze, "test/performance.rb".freeze, "test/setup.rb".freeze, "test/test_appender.rb".freeze, "test/test_color_scheme.rb".freeze, "test/test_filter.rb".freeze, "test/test_layout.rb".freeze, "test/test_log_event.rb".freeze, "test/test_logger.rb".freeze, "test/test_logging.rb".freeze, "test/test_mapped_diagnostic_context.rb".freeze, "test/test_nested_diagnostic_context.rb".freeze, "test/test_proxy.rb".freeze, "test/test_repository.rb".freeze, "test/test_root_logger.rb".freeze, "test/test_utils.rb".freeze]
s.homepage = "http://rubygems.org/gems/logging".freeze
s.rdoc_options = ["--main".freeze, "README.md".freeze]
- s.rubyforge_project = "logging".freeze
- s.rubygems_version = "2.5.2".freeze
+ s.rubygems_version = "3.0.1".freeze
s.summary = "A flexible and extendable logging library for Ruby".freeze
- s.test_files = ["test/appenders/test_async_flushing.rb".freeze, "test/appenders/test_buffered_io.rb".freeze, "test/appenders/test_console.rb".freeze, "test/appenders/test_file.rb".freeze, "test/appenders/test_io.rb".freeze, "test/appenders/test_rolling_file.rb".freeze, "test/appenders/test_string_io.rb".freeze, "test/appenders/test_syslog.rb".freeze, "test/layouts/test_basic.rb".freeze, "test/layouts/test_color_pattern.rb".freeze, "test/layouts/test_json.rb".freeze, "test/layouts/test_pattern.rb".freeze, "test/layouts/test_yaml.rb".freeze, "test/test_appender.rb".freeze, "test/test_color_scheme.rb".freeze, "test/test_filter.rb".freeze, "test/test_layout.rb".freeze, "test/test_log_event.rb".freeze, "test/test_logger.rb".freeze, "test/test_logging.rb".freeze, "test/test_mapped_diagnostic_context.rb".freeze, "test/test_nested_diagnostic_context.rb".freeze, "test/test_proxy.rb".freeze, "test/test_repository.rb".freeze, "test/test_root_logger.rb".freeze, "test/test_utils.rb".freeze]
+ s.test_files = ["test/appenders/test_async_flushing.rb".freeze, "test/appenders/test_buffered_io.rb".freeze, "test/appenders/test_console.rb".freeze, "test/appenders/test_file.rb".freeze, "test/appenders/test_io.rb".freeze, "test/appenders/test_rolling_file.rb".freeze, "test/appenders/test_string_io.rb".freeze, "test/appenders/test_syslog.rb".freeze, "test/layouts/test_basic.rb".freeze, "test/layouts/test_color_pattern.rb".freeze, "test/layouts/test_json.rb".freeze, "test/layouts/test_nested_exceptions.rb".freeze, "test/layouts/test_pattern.rb".freeze, "test/layouts/test_yaml.rb".freeze, "test/test_appender.rb".freeze, "test/test_color_scheme.rb".freeze, "test/test_filter.rb".freeze, "test/test_layout.rb".freeze, "test/test_log_event.rb".freeze, "test/test_logger.rb".freeze, "test/test_logging.rb".freeze, "test/test_mapped_diagnostic_context.rb".freeze, "test/test_nested_diagnostic_context.rb".freeze, "test/test_proxy.rb".freeze, "test/test_repository.rb".freeze, "test/test_root_logger.rb".freeze, "test/test_utils.rb".freeze]
if s.respond_to? :specification_version then
s.specification_version = 4
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q<little-plugger>.freeze, ["~> 1.1"])
- s.add_runtime_dependency(%q<multi_json>.freeze, ["~> 1.10"])
- s.add_development_dependency(%q<test-unit>.freeze, ["~> 3.1"])
+ s.add_runtime_dependency(%q<multi_json>.freeze, ["~> 1.14"])
+ s.add_development_dependency(%q<test-unit>.freeze, ["~> 3.3"])
s.add_development_dependency(%q<bones-git>.freeze, ["~> 1.3"])
s.add_development_dependency(%q<bones>.freeze, [">= 3.8.4"])
else
s.add_dependency(%q<little-plugger>.freeze, ["~> 1.1"])
- s.add_dependency(%q<multi_json>.freeze, ["~> 1.10"])
- s.add_dependency(%q<test-unit>.freeze, ["~> 3.1"])
+ s.add_dependency(%q<multi_json>.freeze, ["~> 1.14"])
+ s.add_dependency(%q<test-unit>.freeze, ["~> 3.3"])
s.add_dependency(%q<bones-git>.freeze, ["~> 1.3"])
s.add_dependency(%q<bones>.freeze, [">= 3.8.4"])
end
else
s.add_dependency(%q<little-plugger>.freeze, ["~> 1.1"])
- s.add_dependency(%q<multi_json>.freeze, ["~> 1.10"])
- s.add_dependency(%q<test-unit>.freeze, ["~> 3.1"])
+ s.add_dependency(%q<multi_json>.freeze, ["~> 1.14"])
+ s.add_dependency(%q<test-unit>.freeze, ["~> 3.3"])
s.add_dependency(%q<bones-git>.freeze, ["~> 1.3"])
s.add_dependency(%q<bones>.freeze, [">= 3.8.4"])
end
diff --git a/test/appenders/test_buffered_io.rb b/test/appenders/test_buffered_io.rb
index 62642b4..3a62c25 100644
--- a/test/appenders/test_buffered_io.rb
+++ b/test/appenders/test_buffered_io.rb
@@ -194,24 +194,22 @@ module TestAppenders
assert_nil(readline)
end
- if Object.const_defined?(:Encoding)
- def test_force_encoding
- a = 'ümlaut'
- b = 'hello ümlaut'.force_encoding('BINARY')
-
- event_a = Logging::LogEvent.new('TestLogger', @levels['info'], a, false)
- event_b = Logging::LogEvent.new('TestLogger', @levels['info'], b, false)
-
- @appender.append event_a
- @appender.append event_b
- assert_nil(readline)
-
- @appender.append event_a
- assert_equal " INFO TestLogger : #{a}\n", readline
- assert_equal " INFO TestLogger : #{b.force_encoding('UTF-8')}\n", readline
- assert_equal " INFO TestLogger : #{a}\n", readline
- assert_nil(readline)
- end
+ def test_force_encoding
+ a = 'ümlaut'
+ b = 'hello ümlaut'.force_encoding('BINARY')
+
+ event_a = Logging::LogEvent.new('TestLogger', @levels['info'], a, false)
+ event_b = Logging::LogEvent.new('TestLogger', @levels['info'], b, false)
+
+ @appender.append event_a
+ @appender.append event_b
+ assert_nil(readline)
+
+ @appender.append event_a
+ assert_equal " INFO TestLogger : #{a}\n", readline
+ assert_equal " INFO TestLogger : #{b.force_encoding('UTF-8')}\n", readline
+ assert_equal " INFO TestLogger : #{a}\n", readline
+ assert_nil(readline)
end
private
diff --git a/test/appenders/test_console.rb b/test/appenders/test_console.rb
index 7bac4f2..175a6d6 100644
--- a/test/appenders/test_console.rb
+++ b/test/appenders/test_console.rb
@@ -20,11 +20,10 @@ module TestAppenders
appender = Logging.appenders.stdout
assert_equal 'stdout', appender.name
- assert_same STDOUT, appender.instance_variable_get(:@io)
- appender.close
- assert_equal true, appender.closed?
- assert_equal false, STDOUT.closed?
+ io = appender.instance_variable_get(:@io)
+ assert_same STDOUT, io
+ assert_equal STDOUT.fileno, io.fileno
appender = Logging.appenders.stdout('foo')
assert_equal 'foo', appender.name
@@ -38,7 +37,26 @@ module TestAppenders
assert_equal 3, appender.level
end
- end # class TestStdout
+ def test_reopen
+ Logging::Repository.instance
+
+ appender = Logging.appenders.stdout
+ io = appender.instance_variable_get(:@io)
+
+ appender.close
+ assert appender.closed?
+ refute io.closed?
+ refute STDOUT.closed?
+
+ appender.reopen
+ refute appender.closed?
+
+ new_io = appender.instance_variable_get(:@io)
+ assert_same io, new_io
+ refute new_io.closed?
+ refute io.closed?
+ end
+ end
class TestStderr < Test::Unit::TestCase
include LoggingTestCase
@@ -48,11 +66,10 @@ module TestAppenders
appender = Logging.appenders.stderr
assert_equal 'stderr', appender.name
- assert_same STDERR, appender.instance_variable_get(:@io)
- appender.close
- assert_equal true, appender.closed?
- assert_equal false, STDERR.closed?
+ io = appender.instance_variable_get(:@io)
+ assert_same STDERR, io
+ assert_equal STDERR.fileno, io.fileno
appender = Logging.appenders.stderr('foo')
assert_equal 'foo', appender.name
@@ -66,8 +83,26 @@ module TestAppenders
assert_equal 3, appender.level
end
- end # class TestStderr
+ def test_reopen
+ Logging::Repository.instance
-end # module TestAppenders
-end # module TestLogging
+ appender = Logging.appenders.stderr
+ io = appender.instance_variable_get(:@io)
+
+ appender.close
+ assert appender.closed?
+ refute io.closed?
+ refute STDERR.closed?
+
+ appender.reopen
+ refute appender.closed?
+
+ new_io = appender.instance_variable_get(:@io)
+ assert_same io, new_io
+ refute new_io.closed?
+ refute io.closed?
+ end
+ end
+end
+end
diff --git a/test/appenders/test_file.rb b/test/appenders/test_file.rb
index b084057..3d7e12a 100644
--- a/test/appenders/test_file.rb
+++ b/test/appenders/test_file.rb
@@ -14,10 +14,10 @@ module TestAppenders
super
Logging.init
- FileUtils.mkdir [File.join(TMP, 'dir'), File.join(TMP, 'uw_dir')]
- FileUtils.chmod 0555, File.join(TMP, 'uw_dir')
- FileUtils.touch File.join(TMP, 'uw_file')
- FileUtils.chmod 0444, File.join(TMP, 'uw_file')
+ FileUtils.mkdir [File.join(@tmpdir, 'dir'), File.join(@tmpdir, 'uw_dir')]
+ FileUtils.chmod 0555, File.join(@tmpdir, 'uw_dir')
+ FileUtils.touch File.join(@tmpdir, 'uw_file')
+ FileUtils.chmod 0444, File.join(@tmpdir, 'uw_file')
end
def test_factory_method_validates_input
@@ -27,27 +27,27 @@ module TestAppenders
end
def test_class_assert_valid_logfile
- log = File.join(TMP, 'uw_dir', 'file.log')
+ log = File.join(@tmpdir, 'uw_dir', 'file.log')
assert_raise(ArgumentError) do
Logging.appenders.file(log).class.assert_valid_logfile(log)
end
- log = File.join(TMP, 'dir')
+ log = File.join(@tmpdir, 'dir')
assert_raise(ArgumentError) do
Logging.appenders.file(log).class.assert_valid_logfile(log)
end
- log = File.join(TMP, 'uw_file')
+ log = File.join(@tmpdir, 'uw_file')
assert_raise(ArgumentError) do
Logging.appenders.file(log).class.assert_valid_logfile(log)
end
- log = File.join(TMP, 'file.log')
+ log = File.join(@tmpdir, 'file.log')
assert Logging.appenders.file(log).class.assert_valid_logfile(log)
end
def test_initialize
- log = File.join(TMP, 'file.log')
+ log = File.join(@tmpdir, 'file.log')
appender = Logging.appenders.file(NAME, :filename => log)
assert_equal 'logfile', appender.name
assert_equal ::File.expand_path(log), appender.filename
@@ -87,7 +87,7 @@ module TestAppenders
end
def test_changing_directories
- log = File.join(TMP, 'file.log')
+ log = File.join(@tmpdir, 'file.log')
appender = Logging.appenders.file(NAME, :filename => log)
assert_equal 'logfile', appender.name
@@ -95,29 +95,45 @@ module TestAppenders
begin
pwd = Dir.pwd
- Dir.chdir TMP
+ Dir.chdir @tmpdir
assert_nothing_raised { appender.reopen }
ensure
Dir.chdir pwd
end
end
- if Object.const_defined? :Encoding
+ def test_encoding
+ log = File.join(@tmpdir, 'file-encoding.log')
+ appender = Logging.appenders.file(NAME, :filename => log, :encoding => 'ASCII')
- def test_encoding
- log = File.join(TMP, 'file-encoding.log')
- appender = Logging.appenders.file(NAME, :filename => log, :encoding => 'ASCII')
+ appender << "A normal line of text\n"
+ appender << "ümlaut\n"
+ appender.close
- appender << "A normal line of text\n"
- appender << "ümlaut\n"
- appender.close
+ lines = File.readlines(log, :encoding => 'UTF-8')
+ assert_equal "A normal line of text\n", lines[0]
+ assert_equal "ümlaut\n", lines[1]
- lines = File.readlines(log, :encoding => 'UTF-8')
- assert_equal "A normal line of text\n", lines[0]
- assert_equal "ümlaut\n", lines[1]
+ cleanup
+ end
+
+ def test_reopening_should_not_truncate_the_file
+ log = File.join(@tmpdir, 'truncate.log')
+ appender = Logging.appenders.file(NAME, filename: log, truncate: true)
+
+ appender << "This will be the first line\n"
+ appender << "This will be the second line\n"
+ appender << "This will be the third line\n"
+ appender.reopen
- cleanup
+ File.open(log, 'r') do |file|
+ assert_equal "This will be the first line\n", file.readline
+ assert_equal "This will be the second line\n", file.readline
+ assert_equal "This will be the third line\n", file.readline
+ assert_raise(EOFError) {file.readline}
end
+
+ cleanup
end
private
@@ -127,7 +143,6 @@ module TestAppenders
Logging.appenders[NAME] = nil
end
end
-
end # TestFile
end # TestAppenders
diff --git a/test/appenders/test_rolling_file.rb b/test/appenders/test_rolling_file.rb
index f9f5043..6d0d90e 100644
--- a/test/appenders/test_rolling_file.rb
+++ b/test/appenders/test_rolling_file.rb
@@ -13,9 +13,9 @@ module TestAppenders
super
Logging.init
- @fn = File.expand_path('test.log', TMP)
- @fn_fmt = File.expand_path('test.%d.log', TMP)
- @glob = File.expand_path('*.log', TMP)
+ @fn = File.expand_path('test.log', @tmpdir)
+ @fn_fmt = File.expand_path('test.%d.log', @tmpdir)
+ @glob = File.expand_path('*.log', @tmpdir)
end
def test_factory_method_validates_input
@@ -93,8 +93,8 @@ module TestAppenders
end
def test_age
- d_glob = File.join(TMP, 'test.*.log')
- dt_glob = File.join(TMP, 'test.*-*.log')
+ d_glob = File.join(@tmpdir, 'test.*.log')
+ dt_glob = File.join(@tmpdir, 'test.*-*.log')
age_fn = @fn + '.age'
assert_equal [], Dir.glob(@glob)
@@ -205,7 +205,7 @@ module TestAppenders
begin
pwd = Dir.pwd
- Dir.chdir TMP
+ Dir.chdir @tmpdir
ap << 'X' * 100; ap.flush
assert_equal 1, Dir.glob(@glob).length
@@ -249,9 +249,9 @@ module TestAppenders
end
def test_custom_numberd_filename
- fn = File.expand_path('test.log{{.%d}}', TMP)
- filename = File.expand_path('test.log', TMP)
- glob = File.expand_path('test.log.*', TMP)
+ fn = File.expand_path('test.log{{.%d}}', @tmpdir)
+ filename = File.expand_path('test.log', @tmpdir)
+ glob = File.expand_path('test.log.*', @tmpdir)
assert_equal [], Dir.glob(glob)
ap = Logging.appenders.rolling_file(NAME, :filename => fn, :size => 100, :keep => 2)
@@ -285,10 +285,10 @@ module TestAppenders
end
def test_custom_timestamp_filename
- fn = File.expand_path('test{{.%S:%M}}.log', TMP)
- filename = File.expand_path('test.log', TMP)
+ fn = File.expand_path('test{{.%S:%M}}.log', @tmpdir)
+ filename = File.expand_path('test.log', @tmpdir)
age_file = filename + '.age'
- glob = File.expand_path('test.*.log', TMP)
+ glob = File.expand_path('test.*.log', @tmpdir)
assert_equal [], Dir.glob(glob)
ap = Logging.appenders.rolling_file(NAME, :filename => fn, :age => 1, :keep => 2)
diff --git a/test/layouts/test_json.rb b/test/layouts/test_json.rb
index 9e4c548..d750108 100644
--- a/test/layouts/test_json.rb
+++ b/test/layouts/test_json.rb
@@ -78,7 +78,7 @@ module TestLayouts
'log message', false)
event.file = 'test_file.rb'
event.line = 123
- event.method = 'method_name'
+ event.method_name = 'method_name'
@layout.items = %w[logger]
assert_equal %Q[{"logger":"TestLogger"}\n], @layout.format(event)
diff --git a/test/layouts/test_nested_exceptions.rb b/test/layouts/test_nested_exceptions.rb
index ef66f96..e784d95 100644
--- a/test/layouts/test_nested_exceptions.rb
+++ b/test/layouts/test_nested_exceptions.rb
@@ -19,7 +19,7 @@ module TestLogging
end
layout = Logging.layouts.basic({})
- log = layout.format_obj(e)
+ log = layout.format_obj(err)
assert_not_nil log.index('<StandardError> root exception')
if err.respond_to?(:cause)
@@ -45,7 +45,7 @@ module TestLogging
end
layout = Logging.layouts.basic(cause_depth: 1)
- log = layout.format_obj(e)
+ log = layout.format_obj(err)
assert_not_nil log.index('<StandardError> root exception')
if err.respond_to?(:cause)
@@ -68,12 +68,12 @@ module TestLogging
end
layout = Logging.layouts.parseable.new
- log = layout.format_obj(e)
+ log = layout.format_obj(err)
assert_equal 'StandardError', log[:class]
assert_equal 'root exception', log[:message]
assert log[:backtrace].size > 0
- if e.respond_to?(:cause)
+ if err.respond_to?(:cause)
assert_not_nil log[:cause]
log = log[:cause]
@@ -101,13 +101,13 @@ module TestLogging
end
layout = Logging.layouts.parseable.new(cause_depth: 1)
- log = layout.format_obj(e)
+ log = layout.format_obj(err)
assert_equal 'StandardError', log[:class]
assert_equal 'root exception', log[:message]
assert log[:backtrace].size > 0
- if e.respond_to?(:cause)
+ if err.respond_to?(:cause)
assert_not_nil log[:cause]
log = log[:cause]
diff --git a/test/layouts/test_pattern.rb b/test/layouts/test_pattern.rb
index 78fe9e2..1e22cfd 100644
--- a/test/layouts/test_pattern.rb
+++ b/test/layouts/test_pattern.rb
@@ -105,7 +105,7 @@ module TestLayouts
'log message', false)
event.file = 'test_file.rb'
event.line = '123'
- event.method = 'method_name'
+ event.method_name = 'method_name'
@layout.pattern = '%c'
assert_equal 'TestLogger', @layout.format(event)
diff --git a/test/layouts/test_yaml.rb b/test/layouts/test_yaml.rb
index 8df420d..7471893 100644
--- a/test/layouts/test_yaml.rb
+++ b/test/layouts/test_yaml.rb
@@ -68,7 +68,7 @@ module TestLayouts
'log message', false)
event.file = 'test_file.rb'
event.line = 123
- event.method = 'method_name'
+ event.method_name = 'method_name'
@layout.items = %w[logger]
assert_match %r/\A--- ?\nlogger: TestLogger\n/, @layout.format(event)
diff --git a/test/setup.rb b/test/setup.rb
index ef293d9..b8b8ca4 100644
--- a/test/setup.rb
+++ b/test/setup.rb
@@ -5,6 +5,12 @@ LOGGING_TEST_SETUP = true
require "rubygems"
require "test/unit"
+require "tmpdir"
+
+LOGGING_TEST_TMPDIR = Dir.mktmpdir("logging")
+Test::Unit.at_exit do
+ FileUtils.remove_entry(LOGGING_TEST_TMPDIR)
+end
if Test::Unit::TestCase.respond_to? :test_order=
Test::Unit::TestCase.test_order = :random
@@ -15,18 +21,16 @@ require File.expand_path("../../lib/logging", __FILE__)
module TestLogging
module LoggingTestCase
- TMP = 'tmp'
-
def setup
super
Logging.reset
- FileUtils.rm_rf TMP
- FileUtils.mkdir TMP
+ @tmpdir = LOGGING_TEST_TMPDIR
+ FileUtils.rm_rf(Dir.glob(File.join(@tmpdir, "*")))
end
def teardown
super
- FileUtils.rm_rf TMP
+ FileUtils.rm_rf(Dir.glob(File.join(@tmpdir, "*")))
end
end
end
diff --git a/test/test_log_event.rb b/test/test_log_event.rb
index eb6523e..53c6dcb 100644
--- a/test/test_log_event.rb
+++ b/test/test_log_event.rb
@@ -68,12 +68,12 @@ module TestLogging
assert_equal 'MyLogger', @event.logger
end
- def test_method
+ def test_method_name
assert_equal '', @event.file
@logger.caller_tracing = true
@logger.debug 'debug message'
- assert_equal 'test_method', @appender.event.method
+ assert_equal 'test_method_name', @appender.event.method_name
end
end # class TestLogEvent
diff --git a/test/test_logging.rb b/test/test_logging.rb
index f8548ba..e0ca6c3 100644
--- a/test/test_logging.rb
+++ b/test/test_logging.rb
@@ -11,8 +11,8 @@ module TestLogging
@levels = ::Logging::LEVELS
@lnames = ::Logging::LNAMES
- @fn = File.join(TMP, 'test.log')
- @glob = File.join(TMP, '*.log')
+ @fn = File.join(@tmpdir, 'test.log')
+ @glob = File.join(@tmpdir, '*.log')
end
def test_backtrace
@@ -253,6 +253,31 @@ module TestLogging
assert_match %r/\d+\.\d+\.\d+/, ::Logging.version
end
- end # class TestLogging
-end # module TestLogging
+ class Failer
+ class WriteError < StandardError ; end
+ def self.write(*args)
+ raise WriteError.new("Oh noooooo")
+ end
+ end
+ def test_error_handling
+ logger = ::Logging.logger Failer, 2, 100
+ logger.appenders.first.level = :debug
+
+ # No errors are raised by default
+ logger.fatal 'this is a debug message'
+ # Always reset the level; we disable appenders that raise by setting them
+ # to :off
+ logger.appenders.first.level = :debug
+
+ begin
+ Logging.raise_errors = true
+ assert_raises Failer::WriteError do
+ logger.fatal 'this fails because the file descriptor is closed'
+ end
+ ensure
+ Logging.raise_errors = false
+ end
+ end
+ end
+end
Debdiff
[The following lists of changes regard files as different if they have different names, permissions or owners.]
Files in second set of .debs but not in first
-rw-r--r-- root/root /usr/share/rubygems-integration/all/specifications/logging-2.3.0.gemspec
Files in first set of .debs but not in second
-rw-r--r-- root/root /usr/share/rubygems-integration/all/specifications/logging-2.1.0.48.gemspec
No differences were encountered in the control files