diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index d8fe2ce1f92c697309a29e206ada19c1ce801b41..33e96c0e9544b9f3f95df8891e7ec54dcc55612b 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* BufferedLogger#auto_flushing = N flushes the log every N messages. Buffers with an array instead of string. [Jeremy Kemper] + * Fixed Date#xmlschema for dates outside the range of what can be created with Time #9744 [gbuesing] diff --git a/activesupport/lib/active_support/buffered_logger.rb b/activesupport/lib/active_support/buffered_logger.rb index 9b840091a52a3bd01d5899c31d9cb8c95b9ba000..fad47b0e9b7d5256e7a31ea5fd93d10918d1d025 100644 --- a/activesupport/lib/active_support/buffered_logger.rb +++ b/activesupport/lib/active_support/buffered_logger.rb @@ -29,13 +29,14 @@ def silence(temporary_level = ERROR) end end - attr_accessor :level, :auto_flushing + attr_accessor :level + attr_reader :auto_flushing attr_reader :buffer def initialize(log, level = DEBUG) @level = level - @buffer = "" - @auto_flushing = true + @buffer = [] + @auto_flushing = 1 if log.respond_to?(:write) @log = log @@ -56,7 +57,7 @@ def add(severity, message = nil, progname = nil, &block) # Ensures that the original message is not mutated. message = "#{message}\n" unless message[-1] == ?\n @buffer << message - flush if auto_flushing + auto_flush if auto_flushing message end @@ -72,9 +73,25 @@ def #{severity.downcase}? EOT end + # Set the auto-flush period. Set to true to flush after every log message, + # to an integer to flush every N messages, or to false, nil, or zero to + # never auto-flush. If you turn auto-flushing off, be sure to regularly + # flush the log yourself -- it will eat up memory until you do. + def auto_flushing=(period) + case period + when true + @auto_flushing = 1 + when 0 + @auto_flushing = false + when false, nil, Integer + @auto_flushing = period + else + raise ArgumentError, "Unrecognized auto_flushing period: #{period.inspect}" + end + end + def flush - return if @buffer.size == 0 - @log.write(@buffer.slice!(0..-1)) + @log.write(@buffer.slice!(0..-1)) unless @buffer.empty? end def close @@ -82,5 +99,10 @@ def close @log.close if @log.respond_to?(:close) @log = nil end + + protected + def auto_flush + flush if @buffer.size >= @auto_flushing + end end -end \ No newline at end of file +end diff --git a/activesupport/test/buffered_logger_test.rb b/activesupport/test/buffered_logger_test.rb index 9a78ee36948cedb192d819e76f77946919509f53..cabdb590452c1dffcb9c2ce8cc11e3b60256dc3a 100644 --- a/activesupport/test/buffered_logger_test.rb +++ b/activesupport/test/buffered_logger_test.rb @@ -8,7 +8,7 @@ def setup @output = StringIO.new @logger = ActiveSupport::BufferedLogger.new(@output) end - + def test_should_log_debugging_message_when_debugging @logger.level = Logger::DEBUG @logger.add(Logger::DEBUG, @message) @@ -26,35 +26,62 @@ def test_should_add_message_passed_as_block_when_using_add @logger.add(Logger::INFO) {@message} assert @output.string.include?(@message) end - + def test_should_add_message_passed_as_block_when_using_shortcut @logger.level = Logger::INFO @logger.info {@message} assert @output.string.include?(@message) end - + def test_should_convert_message_to_string @logger.level = Logger::INFO @logger.info @integer_message assert @output.string.include?(@integer_message.to_s) end - + def test_should_convert_message_to_string_when_passed_in_block @logger.level = Logger::INFO @logger.info {@integer_message} assert @output.string.include?(@integer_message.to_s) end - + def test_should_not_evaluate_block_if_message_wont_be_logged @logger.level = Logger::INFO evaluated = false @logger.add(Logger::DEBUG) {evaluated = true} - assert evaluated == false + assert evaluated == false end - + def test_should_not_mutate_message message_copy = @message.dup @logger.info @message assert_equal message_copy, @message end + + + [false, nil, 0].each do |disable| + define_method "test_disabling_auto_flush_with_#{disable.inspect}_should_buffer_until_explicit_flush" do + @logger.auto_flushing = disable + + 4.times do + @logger.info 'wait for it..' + assert @output.string.empty?, @output.string + end + + @logger.flush + assert !@output.string.empty?, @logger.buffer.size + end + end + + def test_should_auto_flush_every_n_messages + @logger.auto_flushing = 5 + + 4.times do + @logger.info 'wait for it..' + assert @output.string.empty?, @output.string + end + + @logger.info 'there it is.' + assert !@output.string.empty?, @output.string + end end