From bcb51e01406965ebd030d4b99eb199a9226c3fef Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 11 Nov 2012 18:03:04 +0100 Subject: [PATCH] Add $flushOnOverflow and refactor BufferHandler's internals, fixes #120, fixes #104 --- src/Monolog/Handler/BufferHandler.php | 46 ++++++++++++++------- tests/Monolog/Handler/BufferHandlerTest.php | 46 +++++++++++++++++++++ 2 files changed, 78 insertions(+), 14 deletions(-) diff --git a/src/Monolog/Handler/BufferHandler.php b/src/Monolog/Handler/BufferHandler.php index afbb4a6a..133524ff 100644 --- a/src/Monolog/Handler/BufferHandler.php +++ b/src/Monolog/Handler/BufferHandler.php @@ -24,20 +24,24 @@ use Monolog\Logger; class BufferHandler extends AbstractHandler { protected $handler; - protected $bufferSize; + protected $bufferSize = 0; + protected $bufferLimit; + protected $flushOnOverflow; protected $buffer = array(); /** - * @param HandlerInterface $handler Handler. - * @param integer $bufferSize How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. - * @param integer $level The minimum logging level at which this handler will be triggered - * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param HandlerInterface $handler Handler. + * @param integer $bufferSize How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. + * @param integer $level The minimum logging level at which this handler will be triggered + * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not + * @param Boolean $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded */ - public function __construct(HandlerInterface $handler, $bufferSize = 0, $level = Logger::DEBUG, $bubble = true) + public function __construct(HandlerInterface $handler, $bufferSize = 0, $level = Logger::DEBUG, $bubble = true, $flushOnOverflow = false) { parent::__construct($level, $bubble); $this->handler = $handler; - $this->bufferSize = $bufferSize; + $this->bufferLimit = (int) $bufferSize; + $this->flushOnOverflow = $flushOnOverflow; // __destructor() doesn't get called on Fatal errors register_shutdown_function(array($this, 'close')); @@ -52,22 +56,36 @@ class BufferHandler extends AbstractHandler return false; } - $this->buffer[] = $record; - if ($this->bufferSize > 0 && count($this->buffer) > $this->bufferSize) { - array_shift($this->buffer); + if ($this->bufferLimit > 0 && $this->bufferSize === $this->bufferLimit) { + if ($this->flushOnOverflow) { + $this->flush(); + } else { + array_shift($this->buffer); + $this->bufferSize--; + } } + $this->buffer[] = $record; + $this->bufferSize++; return false === $this->bubble; } + public function flush() + { + if ($this->bufferSize === 0) { + return; + } + + $this->handler->handleBatch($this->buffer); + $this->bufferSize = 0; + $this->buffer = array(); + } + /** * {@inheritdoc} */ public function close() { - if ($this->buffer) { - $this->handler->handleBatch($this->buffer); - $this->buffer = array(); - } + $this->flush(); } } diff --git a/tests/Monolog/Handler/BufferHandlerTest.php b/tests/Monolog/Handler/BufferHandlerTest.php index 5b3c4c8a..9e9795f1 100644 --- a/tests/Monolog/Handler/BufferHandlerTest.php +++ b/tests/Monolog/Handler/BufferHandlerTest.php @@ -36,6 +36,7 @@ class BufferHandlerTest extends TestCase /** * @covers Monolog\Handler\BufferHandler::close + * @covers Monolog\Handler\BufferHandler::flush */ public function testDestructPropagatesRecords() { @@ -65,6 +66,36 @@ class BufferHandlerTest extends TestCase $this->assertFalse($test->hasDebugRecords()); } + /** + * @covers Monolog\Handler\BufferHandler::handle + */ + public function testHandleBufferLimitWithFlushOnOverflow() + { + $test = new TestHandler(); + $handler = new BufferHandler($test, 3, Logger::DEBUG, true, true); + + // send two records + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::DEBUG)); + $this->assertFalse($test->hasDebugRecords()); + $this->assertCount(0, $test->getRecords()); + + // overflow + $handler->handle($this->getRecord(Logger::INFO)); + $this->assertTrue($test->hasDebugRecords()); + $this->assertCount(3, $test->getRecords()); + + // should buffer again + $handler->handle($this->getRecord(Logger::WARNING)); + $this->assertCount(3, $test->getRecords()); + + $handler->close(); + $this->assertCount(5, $test->getRecords()); + $this->assertTrue($test->hasWarningRecords()); + $this->assertTrue($test->hasInfoRecords()); + } + /** * @covers Monolog\Handler\BufferHandler::handle */ @@ -81,4 +112,19 @@ class BufferHandlerTest extends TestCase $this->assertTrue($test->hasInfoRecords()); $this->assertFalse($test->hasDebugRecords()); } + + /** + * @covers Monolog\Handler\BufferHandler::flush + */ + public function testFlush() + { + $test = new TestHandler(); + $handler = new BufferHandler($test, 0); + $handler->handle($this->getRecord(Logger::DEBUG)); + $handler->handle($this->getRecord(Logger::INFO)); + $handler->flush(); + $this->assertTrue($test->hasInfoRecords()); + $this->assertTrue($test->hasDebugRecords()); + $this->assertFalse($test->hasWarningRecords()); + } }