Просмотр исходного кода

Added a Processor stack to the Logger class, added getHandler() to check if any handler is going to handle the message before processing it, handlers are now calling their parent in a chain

Jordi Boggiano 15 лет назад
Родитель
Сommit
a426ce2815

+ 23 - 9
src/Monolog/Handler/AbstractHandler.php

@@ -21,7 +21,7 @@ abstract class AbstractHandler implements HandlerInterface
     protected $parent;
 
     protected $formatter;
-    protected $processor;
+    protected $processors = array();
 
     public function __construct($level = Logger::DEBUG, $bubble = false)
     {
@@ -29,14 +29,25 @@ abstract class AbstractHandler implements HandlerInterface
         $this->bubble = $bubble;
     }
 
+    public function getHandler($message)
+    {
+        if ($message['level'] < $this->level) {
+            return $this->parent ? $this->parent->getHandler($message) : null;
+        }
+        return $this;
+    }
+
     public function handle($message)
     {
         if ($message['level'] < $this->level) {
-            return false;
+            return $this->parent ? $this->parent->handle($message) : false;
         }
 
-        if ($this->processor) {
-            $message = call_user_func($this->processor, $message, $this);
+        $originalMessage = $message;
+        if ($this->processors) {
+            foreach ($this->processors as $processor) {
+                $message = call_user_func($processor, $message, $this);
+            }
         }
 
         if (!$this->formatter) {
@@ -45,7 +56,10 @@ abstract class AbstractHandler implements HandlerInterface
         $message = $this->formatter->format($message);
 
         $this->write($message);
-        return false === $this->bubble;
+        if ($this->bubble && $this->parent) {
+            $this->parent->handle($originalMessage);
+        }
+        return true;
     }
 
     abstract public function write($message);
@@ -54,14 +68,14 @@ abstract class AbstractHandler implements HandlerInterface
     {
     }
 
-    public function setProcessor($callback)
+    public function pushProcessor($callback)
     {
-        $this->processor = $callback;
+        $this->processors[] = $callback;
     }
 
-    public function getProcessor()
+    public function popProcessor()
     {
-        return $this->processor;
+        return array_pop($this->processors);
     }
 
     public function setFormatter($formatter)

+ 2 - 8
src/Monolog/Handler/HandlerInterface.php

@@ -13,15 +13,9 @@ namespace Monolog\Handler;
 
 interface HandlerInterface
 {
-    public function handle($message);
-
-    public function setLevel($level);
-
-    public function getLevel();
+    public function getHandler($message);
 
-    public function setBubble($bubble);
-
-    public function getBubble();
+    public function handle($message);
 
     public function getParent();
 

+ 32 - 18
src/Monolog/Logger.php

@@ -54,6 +54,8 @@ class Logger
      */
     protected $handler;
 
+    protected $processors = array();
+
     public function __construct($name)
     {
         $this->name = $name;
@@ -77,6 +79,16 @@ class Logger
         return $top;
     }
 
+    public function pushProcessor($callback)
+    {
+        $this->processors[] = $callback;
+    }
+
+    public function popProcessor()
+    {
+        return array_pop($this->processors);
+    }
+
     public function addMessage($level, $message)
     {
         if (null === $this->handler) {
@@ -90,33 +102,35 @@ class Logger
             'datetime' => new \DateTime(),
             'extra' => array(),
         );
-        $handled = false;
-        $handler = $this->handler;
-        while ($handler && true !== $handled) {
-            $handled = (bool) $handler->handle($message);
-            $handler = $handler->getParent();
+        $handler = $this->handler->getHandler($message);
+        if (!$handler) {
+            return false;
+        }
+        foreach ($this->processors as $processor) {
+            $message = call_user_func($processor, $message, $this);
         }
-        return $handled;
+        $handler->handle($message);
+        return true;
     }
 
     public function addDebug($message)
     {
-        $this->addMessage(self::DEBUG, $message);
+        return $this->addMessage(self::DEBUG, $message);
     }
 
     public function addInfo($message)
     {
-        $this->addMessage(self::INFO, $message);
+        return $this->addMessage(self::INFO, $message);
     }
 
     public function addWarning($message)
     {
-        $this->addMessage(self::WARNING, $message);
+        return $this->addMessage(self::WARNING, $message);
     }
 
     public function addError($message)
     {
-        $this->addMessage(self::ERROR, $message);
+        return $this->addMessage(self::ERROR, $message);
     }
 
     public static function getLevelName($level)
@@ -128,41 +142,41 @@ class Logger
 
     public function debug($message)
     {
-        $this->addMessage(self::DEBUG, $message);
+        return $this->addMessage(self::DEBUG, $message);
     }
 
     public function info($message)
     {
-        $this->addMessage(self::INFO, $message);
+        return $this->addMessage(self::INFO, $message);
     }
 
     public function notice($message)
     {
-        $this->addMessage(self::INFO, $message);
+        return $this->addMessage(self::INFO, $message);
     }
 
     public function warn($message)
     {
-        $this->addMessage(self::WARNING, $message);
+        return $this->addMessage(self::WARNING, $message);
     }
 
     public function err($message)
     {
-        $this->addMessage(self::ERROR, $message);
+        return $this->addMessage(self::ERROR, $message);
     }
 
     public function crit($message)
     {
-        $this->addMessage(self::ERROR, $message);
+        return $this->addMessage(self::ERROR, $message);
     }
 
     public function alert($message)
     {
-        $this->addMessage(self::ERROR, $message);
+        return $this->addMessage(self::ERROR, $message);
     }
 
     public function emerg($message)
     {
-        $this->addMessage(self::ERROR, $message);
+        return $this->addMessage(self::ERROR, $message);
     }
 }

+ 30 - 2
tests/Monolog/Handler/AbstractHandlerTest.php

@@ -29,8 +29,36 @@ class AbstractHandlerTest extends \PHPUnit_Framework_TestCase
 
     public function testHandleBubbling()
     {
-        $handler = new TestHandler(Logger::DEBUG, true);
-        $this->assertFalse($handler->handle($this->getMessage()));
+        $topHandler = new TestHandler(Logger::DEBUG, true);
+        $bottomHandler = new TestHandler(Logger::INFO);
+        $topHandler->setParent($bottomHandler);
+        $this->assertTrue($topHandler->handle($this->getMessage()));
+        $this->assertTrue($bottomHandler->hasWarningMessages());
+    }
+
+    public function testHandleNotBubbling()
+    {
+        $topHandler = new TestHandler(Logger::DEBUG);
+        $bottomHandler = new TestHandler(Logger::INFO);
+        $topHandler->setParent($bottomHandler);
+        $this->assertTrue($topHandler->handle($this->getMessage()));
+        $this->assertFalse($bottomHandler->hasWarningMessages());
+    }
+
+    public function testGetHandlerReturnEarly()
+    {
+        $topHandler = new TestHandler(Logger::DEBUG);
+        $bottomHandler = new TestHandler(Logger::INFO);
+        $topHandler->setParent($bottomHandler);
+        $this->assertEquals($topHandler, $topHandler->getHandler($this->getMessage()));
+    }
+
+    public function testGetHandlerReturnsParent()
+    {
+        $topHandler = new TestHandler(Logger::ERROR);
+        $bottomHandler = new TestHandler(Logger::INFO);
+        $topHandler->setParent($bottomHandler);
+        $this->assertEquals($bottomHandler, $topHandler->getHandler($this->getMessage()));
     }
 
     protected function getMessage($level = Logger::WARNING)

+ 6 - 15
tests/Monolog/LoggerTest.php

@@ -22,28 +22,19 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
             ->method('handle');
         $logger->pushHandler($handler);
 
-        $logger->addWarning('test');
+        $this->assertTrue($logger->addWarning('test'));
     }
 
-    /**
-     * @dataProvider logValues
-     */
-    public function testLogUntilHandled($bubble)
+    public function testLogNoHandler()
     {
         $logger = new Logger(__METHOD__);
 
-        $bottomHandler = $this->getMock('Monolog\Handler\NullHandler', array('handle'));
-        $bottomHandler->expects($bubble ? $this->once() : $this->never())
+        $handler = $this->getMock('Monolog\Handler\NullHandler', array('handle'), array(Logger::ERROR));
+        $handler->expects($this->never())
             ->method('handle');
-        $logger->pushHandler($bottomHandler);
-
-        $topHandler = $this->getMock('Monolog\Handler\NullHandler', array('handle'));
-        $topHandler->expects($this->once())
-            ->method('handle')
-            ->will($this->returnValue(!$bubble));
-        $logger->pushHandler($topHandler);
+        $logger->pushHandler($handler);
 
-        $logger->addWarning('test');
+        $this->assertFalse($logger->addWarning('test'));
     }
 
     public function logValues()