未验证 提交 ace28a54 编写于 作者: R Rafael França 提交者: Rafael Mendonça França

Merge pull request #36753 from cmrd-senya/36752-make-rails-logger-fiber-safe

Make ActiveSupport::Logger Fiber-safe
上级 270fb0b5
* Make ActiveSupport::Logger Fiber-safe. Fixes #36752.
Use `Fiber.current.__id__` in `ActiveSupport::Logger#local_level=` in order
to make log level local to Ruby Fibers in addition to Threads.
Example:
logger = ActiveSupport::Logger.new(STDOUT)
logger.level = 1
p "Main is debug? #{logger.debug?}"
Fiber.new {
logger.local_level = 0
p "Thread is debug? #{logger.debug?}"
}.resume
p "Main is debug? #{logger.debug?}"
Before:
Main is debug? false
Thread is debug? true
Main is debug? true
After:
Main is debug? false
Thread is debug? true
Main is debug? false
*Alexander Varnin*
* Do not delegate missing `marshal_dump` and `_dump` methods via the * Do not delegate missing `marshal_dump` and `_dump` methods via the
`delegate_missing_to` extension. This avoids unintentionally adding instance `delegate_missing_to` extension. This avoids unintentionally adding instance
variables when calling `Marshal.dump(object)`, should the delegation target of variables when calling `Marshal.dump(object)`, should the delegation target of
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
require "active_support/concern" require "active_support/concern"
require "active_support/core_ext/module/attribute_accessors" require "active_support/core_ext/module/attribute_accessors"
require "concurrent" require "concurrent"
require "fiber"
module ActiveSupport module ActiveSupport
module LoggerThreadSafeLevel # :nodoc: module LoggerThreadSafeLevel # :nodoc:
...@@ -28,7 +29,7 @@ def after_initialize ...@@ -28,7 +29,7 @@ def after_initialize
end end
def local_log_id def local_log_id
Thread.current.__id__ Fiber.current.__id__
end end
def local_level def local_level
......
...@@ -258,6 +258,50 @@ def test_logger_level_local_thread_safety ...@@ -258,6 +258,50 @@ def test_logger_level_local_thread_safety
assert_level(Logger::INFO) assert_level(Logger::INFO)
end end
def test_logger_level_main_fiber_safety
@logger.level = Logger::INFO
assert_level(Logger::INFO)
fiber = Fiber.new do
assert_level(Logger::INFO)
end
@logger.silence(Logger::ERROR) do
assert_level(Logger::ERROR)
fiber.resume
end
end
def test_logger_level_local_fiber_safety
@logger.level = Logger::INFO
assert_level(Logger::INFO)
another_fiber = Fiber.new do
@logger.silence(Logger::ERROR) do
assert_level(Logger::ERROR)
@logger.silence(Logger::DEBUG) do
assert_level(Logger::DEBUG)
end
end
assert_level(Logger::INFO)
end
Fiber.new do
@logger.silence(Logger::ERROR) do
assert_level(Logger::ERROR)
@logger.silence(Logger::DEBUG) do
another_fiber.resume
assert_level(Logger::DEBUG)
end
end
assert_level(Logger::INFO)
end.resume
assert_level(Logger::INFO)
end
private private
def level_name(level) def level_name(level)
::Logger::Severity.constants.find do |severity| ::Logger::Severity.constants.find do |severity|
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册