Skip to content

Commit dae2b83

Browse files
authored
Enable subclasses to configure level isolation (#103)
`Logger#with_level` was recently added to enable configuring a `Logger`'s level for the duration of a block. However, the configured level is always tied to the currently running `Fiber`, which is not always ideal in applications that mix `Thread`s and `Fiber`s. For example, Active Support has provided a similar feature (`ActiveSupport::Logger#log_at`) which, depending on configuration, can be isolated to either `Thread`s or `Fiber`s. This commit enables subclasses of `Logger` to customize the level isolation. Ideally, it will enable replacing most of Active Support's `#log_at`, since both methods end up serving the same purpose.
1 parent d1d704a commit dae2b83

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed

lib/logger.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ class Logger
381381

382382
# Logging severity threshold (e.g. <tt>Logger::INFO</tt>).
383383
def level
384-
level_override[Fiber.current] || @level
384+
level_override[level_key] || @level
385385
end
386386

387387
# Sets the log level; returns +severity+.
@@ -406,14 +406,14 @@ def level=(severity)
406406
# logger.debug { "Hello" }
407407
# end
408408
def with_level(severity)
409-
prev, level_override[Fiber.current] = level, Severity.coerce(severity)
409+
prev, level_override[level_key] = level, Severity.coerce(severity)
410410
begin
411411
yield
412412
ensure
413413
if prev
414-
level_override[Fiber.current] = prev
414+
level_override[level_key] = prev
415415
else
416-
level_override.delete(Fiber.current)
416+
level_override.delete(level_key)
417417
end
418418
end
419419
end
@@ -751,6 +751,10 @@ def level_override
751751
@level_override ||= {}
752752
end
753753

754+
def level_key
755+
Fiber.current
756+
end
757+
754758
def format_message(severity, datetime, progname, msg)
755759
(@formatter || @default_formatter).call(severity, datetime, progname, msg)
756760
end

test/logger/test_severity.rb

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def test_level_assignment
2626
end
2727
end
2828

29-
def test_thread_local_level
29+
def test_fiber_local_level
3030
logger = Logger.new(nil)
3131
logger.level = INFO # default level
3232
other = Logger.new(nil)
@@ -40,14 +40,50 @@ def test_thread_local_level
4040
logger.with_level(DEBUG) do # verify reentrancy
4141
assert_equal(logger.level, DEBUG)
4242

43-
Thread.new do
43+
Fiber.new do
4444
assert_equal(logger.level, INFO)
4545
logger.with_level(:WARN) do
4646
assert_equal(other.level, ERROR)
4747
assert_equal(logger.level, WARN)
4848
end
4949
assert_equal(logger.level, INFO)
50-
end.join
50+
end.resume
51+
52+
assert_equal(logger.level, DEBUG)
53+
end
54+
assert_equal(logger.level, WARN)
55+
end
56+
assert_equal(logger.level, INFO)
57+
end
58+
59+
def test_thread_local_level
60+
subclass = Class.new(Logger) do
61+
def level_key
62+
Thread.current
63+
end
64+
end
65+
66+
logger = subclass.new(nil)
67+
logger.level = INFO # default level
68+
other = subclass.new(nil)
69+
other.level = ERROR # default level
70+
71+
assert_equal(other.level, ERROR)
72+
logger.with_level(:WARN) do
73+
assert_equal(other.level, ERROR)
74+
assert_equal(logger.level, WARN)
75+
76+
logger.with_level(DEBUG) do # verify reentrancy
77+
assert_equal(logger.level, DEBUG)
78+
79+
Fiber.new do
80+
assert_equal(logger.level, DEBUG)
81+
logger.with_level(:WARN) do
82+
assert_equal(other.level, ERROR)
83+
assert_equal(logger.level, WARN)
84+
end
85+
assert_equal(logger.level, DEBUG)
86+
end.resume
5187

5288
assert_equal(logger.level, DEBUG)
5389
end

0 commit comments

Comments
 (0)