mirror of
https://github.com/meineerde/rackstash.git
synced 2025-10-17 14:01:01 +00:00
Add Logger#push_buffer and Logger#pop_buffer for manual Buffer management
Most of the time, these methods should be used. They are only required for special cases where the Buffer needs to be flushed later than when its poped. In this case, special precautions need to be made to ensure that the Buffer is always reliably poped and flushed to avoid loosing logs.
This commit is contained in:
parent
ca394ddfe4
commit
77675f65a6
@ -342,6 +342,72 @@ module Rackstash
|
||||
buffer.add_exception(exception, force: force)
|
||||
end
|
||||
|
||||
# Create a new {Buffer} and put it on the {BufferStack} for the current
|
||||
# Thread. Until it is poped again with {#pop_buffer}, all newly logged
|
||||
# messages and any access to fields or tags will be sent to this new Buffer.
|
||||
# Previous Buffers will only be visible after it was poped. You should make
|
||||
# sure that the Buffer is only ever used by the calling Thread to retain the
|
||||
# thread-safety guarantees of Rackstash.
|
||||
#
|
||||
# Most of the time, you should use {#with_buffer} instead to ensure that the
|
||||
# Buffer is reliably removed again when the execution leaves the block.
|
||||
# The only sensible use of the manual buffer management is when you need
|
||||
# to flush the Buffer outside of its active scope after it was poped.
|
||||
#
|
||||
# When using this method, it is crucial that you manually pop and flush the
|
||||
# buffer in all cases. This can look like this:
|
||||
#
|
||||
# logger.push_buffer(buffering: true)
|
||||
# begin
|
||||
# logger.fields['key'] = 'value'
|
||||
# logger.info 'performing some work...'
|
||||
# ensure
|
||||
# buffer = logger.pop_buffer
|
||||
# buffer.flush if buffer
|
||||
# end
|
||||
#
|
||||
# By using the `begin ... ensure` block, you can enfore that the buffer is
|
||||
# actually poped and flushed afte the execution leaves your environment,
|
||||
# even in an Exception is raised. If you omit to pop the Buffer from the
|
||||
# stack, weird things can happen and your logs will probably end up not
|
||||
# being consistent or even flushed.
|
||||
#
|
||||
# @see #pop_buffer
|
||||
#
|
||||
# @param buffer_args [Hash<Symbol => Object>] optional arguments for the new
|
||||
# {Buffer}. See {Buffer#initialize} for allowed values.
|
||||
# @return [Buffer] the newly pushed {Buffer} instance
|
||||
def push_buffer(buffer_args = {})
|
||||
buffer_stack.push(buffer_args)
|
||||
end
|
||||
|
||||
# Remove a previously pushed {Buffer} from the {BufferStack} for the current
|
||||
# Thread.
|
||||
#
|
||||
# You should only call this method after having called {#push_buffer} before
|
||||
# in the very same Thread and only exactly as many times as you have called
|
||||
# {#push_buffer} in that Thread. If you call this method too many times or
|
||||
# without first calling {#push_buffer}, it will destroy the consistency of
|
||||
# BufferStack causing undefined (i.e. weird) behavior.
|
||||
#
|
||||
# Since the Buffer is not flushed before returning, it is possible to still
|
||||
# modify the buffer before eventually flushing it on your own.
|
||||
#
|
||||
# Should it happen that there is no Buffer on the {BufferStack} (which can
|
||||
# only happen if the code execution was non-linear and stepped outside the
|
||||
# block scope), we return `nil` and not change the BufferStack.
|
||||
#
|
||||
# @note In contrast to {#with_buffer}, the poped Buffer is not flushed
|
||||
# automatically. You *MUST* call `buffer.flush` yourself to write the
|
||||
# buffered log data to the log adapter(s).
|
||||
# @see #push_buffer
|
||||
#
|
||||
# @return [Buffer, nil] the removed {Buffer} from the current Thread's
|
||||
# {BufferStack} or `nil` if no {Buffer} could be found on the stack.
|
||||
def pop_buffer
|
||||
buffer_stack.pop
|
||||
end
|
||||
|
||||
# Create a new buffering {Buffer} and put 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.
|
||||
|
||||
@ -521,6 +521,30 @@ describe Rackstash::Logger do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#push_buffer' do
|
||||
it 'pushes a new buffer on the BufferStack' do
|
||||
expect(logger.send(:buffer_stack)).to receive(:push).and_call_original
|
||||
buffer = logger.push_buffer
|
||||
expect(buffer).to be_instance_of Rackstash::Buffer
|
||||
|
||||
expect(buffer).to receive(:add_message)
|
||||
logger.info('ping')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#pop_buffer' do
|
||||
it 'pops a buffer from the BufferStack' do
|
||||
pushed_buffer = logger.push_buffer
|
||||
|
||||
expect(logger.send(:buffer_stack)).to receive(:pop).and_call_original
|
||||
expect(logger.pop_buffer).to equal pushed_buffer
|
||||
end
|
||||
|
||||
it 'returns nil of no Buffer can be poped' do
|
||||
expect(logger.pop_buffer).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#with_buffer' do
|
||||
it 'requires a block' do
|
||||
expect { logger.with_buffer }.to raise_error ArgumentError
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user