mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Maintain a seperate buffer for each thread
This commit is contained in:
@@ -33,11 +33,10 @@ module ActiveSupport
|
||||
|
||||
attr_accessor :level
|
||||
attr_reader :auto_flushing
|
||||
attr_reader :buffer
|
||||
|
||||
def initialize(log, level = DEBUG)
|
||||
@level = level
|
||||
@buffer = []
|
||||
@buffer = {}
|
||||
@auto_flushing = 1
|
||||
@guard = Mutex.new
|
||||
|
||||
@@ -60,9 +59,7 @@ module ActiveSupport
|
||||
# If a newline is necessary then create a new message ending with a newline.
|
||||
# Ensures that the original message is not mutated.
|
||||
message = "#{message}\n" unless message[-1] == ?\n
|
||||
@guard.synchronize do
|
||||
buffer << message
|
||||
end
|
||||
buffer << message
|
||||
auto_flush
|
||||
message
|
||||
end
|
||||
@@ -96,8 +93,8 @@ module ActiveSupport
|
||||
def flush
|
||||
@guard.synchronize do
|
||||
unless buffer.empty?
|
||||
old_buffer = @buffer
|
||||
@buffer = []
|
||||
old_buffer = buffer
|
||||
clear_buffer
|
||||
@log.write(old_buffer.join)
|
||||
end
|
||||
end
|
||||
@@ -113,5 +110,13 @@ module ActiveSupport
|
||||
def auto_flush
|
||||
flush if buffer.size >= @auto_flushing
|
||||
end
|
||||
|
||||
def buffer
|
||||
@buffer[Thread.current] ||= []
|
||||
end
|
||||
|
||||
def clear_buffer
|
||||
@buffer[Thread.current] = []
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -70,7 +70,7 @@ class BufferedLoggerTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
@logger.flush
|
||||
assert !@output.string.empty?, @logger.buffer.size
|
||||
assert !@output.string.empty?, @logger.send(:buffer).size
|
||||
end
|
||||
|
||||
define_method "test_disabling_auto_flush_with_#{disable.inspect}_should_flush_at_max_buffer_size_as_failsafe" do
|
||||
@@ -83,10 +83,10 @@ class BufferedLoggerTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
@logger.info 'there it is.'
|
||||
assert !@output.string.empty?, @logger.buffer.size
|
||||
assert !@output.string.empty?, @logger.send(:buffer).size
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def test_should_know_if_its_loglevel_is_below_a_given_level
|
||||
ActiveSupport::BufferedLogger::Severity.constants.each do |level|
|
||||
@logger.level = ActiveSupport::BufferedLogger::Severity.const_get(level) - 1
|
||||
@@ -105,7 +105,7 @@ class BufferedLoggerTest < Test::Unit::TestCase
|
||||
@logger.info 'there it is.'
|
||||
assert !@output.string.empty?, @output.string
|
||||
end
|
||||
|
||||
|
||||
def test_should_create_the_log_directory_if_it_doesnt_exist
|
||||
tmp_directory = File.join(File.dirname(__FILE__), "tmp")
|
||||
log_file = File.join(tmp_directory, "development.log")
|
||||
@@ -115,4 +115,25 @@ class BufferedLoggerTest < Test::Unit::TestCase
|
||||
ensure
|
||||
FileUtils.rm_rf(tmp_directory)
|
||||
end
|
||||
|
||||
def test_logger_should_maintain_separate_buffers_for_each_thread
|
||||
@logger.auto_flushing = false
|
||||
|
||||
a = Thread.new do
|
||||
@logger.info("a"); Thread.pass;
|
||||
@logger.info("b"); Thread.pass;
|
||||
@logger.info("c"); @logger.flush
|
||||
end
|
||||
|
||||
b = Thread.new do
|
||||
@logger.info("x"); Thread.pass;
|
||||
@logger.info("y"); Thread.pass;
|
||||
@logger.info("z"); @logger.flush
|
||||
end
|
||||
|
||||
a.join
|
||||
b.join
|
||||
|
||||
assert_equal "a\nb\nc\nx\ny\nz\n", @output.string
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user