소스 검색

Add $flushOnOverflow and refactor BufferHandler's internals, fixes #120, fixes #104

Jordi Boggiano 13 년 전
부모
커밋
bcb51e0140
2개의 변경된 파일78개의 추가작업 그리고 14개의 파일을 삭제
  1. 32 14
      src/Monolog/Handler/BufferHandler.php
  2. 46 0
      tests/Monolog/Handler/BufferHandlerTest.php

+ 32 - 14
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();
     }
 }

+ 46 - 0
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());
+    }
 }