diff --git a/lib/rackstash/logger.rb b/lib/rackstash/logger.rb index 8be7f3f..6b5dec9 100644 --- a/lib/rackstash/logger.rb +++ b/lib/rackstash/logger.rb @@ -249,6 +249,25 @@ module Rackstash end alias :log :add + # Create a new buffering {Buffer} and puts in on the {BufferStack} for the + # current Thread. For the duration of the block, all new logged messages + # and any access to fields and tags will be sent to this new buffer. + # Previous buffers will only be visible after the execition left the block. + # + # @param buffer_args [Hash Object>] optional arguments for the new + # {Buffer}. See {Buffer#initialize} for allowed values. + # @return [Object] the return value of the block + def with_buffer(**buffer_args) + raise ArgumentError, 'block required' unless block_given? + + buffer_stack.push(**buffer_args) + begin + yield + ensure + buffer_stack.flush_and_pop + end + end + private def buffer_stack diff --git a/spec/rackstash/logger_spec.rb b/spec/rackstash/logger_spec.rb index 54da7a5..179c403 100644 --- a/spec/rackstash/logger_spec.rb +++ b/spec/rackstash/logger_spec.rb @@ -350,6 +350,34 @@ describe Rackstash::Logger do end end + describe '#with_buffer' do + it 'requires a block' do + expect { logger.with_buffer }.to raise_error ArgumentError + end + + it 'adds a new buffer' do + expect(logger.send(:buffer_stack)).to receive(:push).and_call_original + expect(logger.send(:buffer_stack)).to receive(:flush_and_pop).and_call_original + + logger.fields['key'] = 'outer' + logger.with_buffer do + expect(logger.fields['key']).to be nil + logger.fields['key'] = 'inner' + end + expect(logger.fields['key']).to eql 'outer' + end + + + it 'buffers multiple messages' do + expect(logger.sink).to receive(:flush).once + + logger.with_buffer do + logger.add 1, 'Hello World' + logger.add 0, 'I feel great' + end + end + end + context 'with multiple threads' do it 'maintains thread-local stacks' do first_stack = logger.send(:buffer_stack)