aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Perham <mike@perham.net>2023-02-09 17:08:33 -0800
committergit <svn-admin@ruby-lang.org>2023-02-10 01:08:49 +0000
commit194520f80e1cdb71faa055d731450855a1ddb8d1 (patch)
treee1b2a55db6d588213f5e26f2ed7cfed1dc597553
parentb61edc5f5daf8fb664c9bcd7e51850176055d749 (diff)
downloadruby-194520f80e1cdb71faa055d731450855a1ddb8d1.tar.gz
[ruby/logger] Add Logger#with_level{...} for block-scoped log level.
(https://github.com/ruby/logger/pull/85) * Update lib/logger/severity.rb https://github.com/ruby/logger/commit/7aabb0b4aa
-rw-r--r--lib/logger.rb39
-rw-r--r--lib/logger/severity.rb19
-rw-r--r--test/logger/test_severity.rb32
3 files changed, 72 insertions, 18 deletions
diff --git a/lib/logger.rb b/lib/logger.rb
index 7e4dacc911..acc65ac8bb 100644
--- a/lib/logger.rb
+++ b/lib/logger.rb
@@ -10,6 +10,7 @@
#
# A simple system for logging messages. See Logger for more documentation.
+require 'fiber'
require 'monitor'
require 'rbconfig'
@@ -380,7 +381,9 @@ class Logger
include Severity
# Logging severity threshold (e.g. <tt>Logger::INFO</tt>).
- attr_reader :level
+ def level
+ @level_override[Fiber.current] || @level
+ end
# Sets the log level; returns +severity+.
# See {Log Level}[rdoc-ref:Logger@Log+Level].
@@ -395,24 +398,23 @@ class Logger
# Logger#sev_threshold= is an alias for Logger#level=.
#
def level=(severity)
- if severity.is_a?(Integer)
- @level = severity
- else
- case severity.to_s.downcase
- when 'debug'
- @level = DEBUG
- when 'info'
- @level = INFO
- when 'warn'
- @level = WARN
- when 'error'
- @level = ERROR
- when 'fatal'
- @level = FATAL
- when 'unknown'
- @level = UNKNOWN
+ @level = Severity.coerce(severity)
+ end
+
+ # Adjust the log level during the block execution for the current Fiber only
+ #
+ # logger.with_level(:debug) do
+ # logger.debug { "Hello" }
+ # end
+ def with_level(severity)
+ prev, @level_override[Fiber.current] = level, Severity.coerce(severity)
+ begin
+ yield
+ ensure
+ if prev
+ @level_override[Fiber.current] = prev
else
- raise ArgumentError, "invalid log level: #{severity}"
+ @level_override.delete(Fiber.current)
end
end
end
@@ -583,6 +585,7 @@ class Logger
self.datetime_format = datetime_format
self.formatter = formatter
@logdev = nil
+ @level_override = {}
if logdev && logdev != File::NULL
@logdev = LogDevice.new(logdev, shift_age: shift_age,
shift_size: shift_size,
diff --git a/lib/logger/severity.rb b/lib/logger/severity.rb
index b38afb7d22..e96fb0d320 100644
--- a/lib/logger/severity.rb
+++ b/lib/logger/severity.rb
@@ -15,5 +15,24 @@ class Logger
FATAL = 4
# An unknown message that should always be logged.
UNKNOWN = 5
+
+ LEVELS = {
+ "debug" => DEBUG,
+ "info" => INFO,
+ "warn" => WARN,
+ "error" => ERROR,
+ "fatal" => FATAL,
+ "unknown" => UNKNOWN,
+ }
+ private_constant :LEVELS
+
+ def self.coerce(severity)
+ if severity.is_a?(Integer)
+ severity
+ else
+ key = severity.to_s.downcase
+ LEVELS[key] || raise(ArgumentError, "invalid log level: #{severity}")
+ end
+ end
end
end
diff --git a/test/logger/test_severity.rb b/test/logger/test_severity.rb
index dad63472a6..e1069c8262 100644
--- a/test/logger/test_severity.rb
+++ b/test/logger/test_severity.rb
@@ -3,6 +3,8 @@
require 'logger'
class TestLoggerSeverity < Test::Unit::TestCase
+ include Logger::Severity
+
def test_enum
logger_levels = Logger.constants
levels = ["WARN", "UNKNOWN", "INFO", "FATAL", "DEBUG", "ERROR"]
@@ -23,4 +25,34 @@ class TestLoggerSeverity < Test::Unit::TestCase
assert(logger.level) == Logger::Severity.const_get(level)
end
end
+
+ def test_thread_local_level
+ logger = Logger.new(nil)
+ logger.level = INFO # default level
+ other = Logger.new(nil)
+ other.level = ERROR # default level
+
+ assert_equal(other.level, ERROR)
+ logger.with_level(:WARN) do
+ assert_equal(other.level, ERROR)
+ assert_equal(logger.level, WARN)
+
+ logger.with_level(DEBUG) do # verify reentrancy
+ assert_equal(logger.level, DEBUG)
+
+ Thread.new do
+ assert_equal(logger.level, INFO)
+ logger.with_level(:WARN) do
+ assert_equal(other.level, ERROR)
+ assert_equal(logger.level, WARN)
+ end
+ assert_equal(logger.level, INFO)
+ end.join
+
+ assert_equal(logger.level, DEBUG)
+ end
+ assert_equal(logger.level, WARN)
+ end
+ assert_equal(logger.level, INFO)
+ end
end