1
0
mirror of https://github.com/Seldaek/monolog.git synced 2025-08-06 05:07:36 +02:00

Move the stack handling to the Logger class

This commit is contained in:
Jordi Boggiano
2011-02-25 22:00:51 +01:00
parent 1983270611
commit 903bbd0fd6
6 changed files with 40 additions and 83 deletions

View File

@@ -25,7 +25,6 @@ abstract class AbstractHandler implements HandlerInterface
{ {
protected $level; protected $level;
protected $bubble; protected $bubble;
protected $parent;
protected $formatter; protected $formatter;
protected $processors = array(); protected $processors = array();
@@ -36,18 +35,15 @@ abstract class AbstractHandler implements HandlerInterface
$this->bubble = $bubble; $this->bubble = $bubble;
} }
public function getHandler($message) public function isHandling($message)
{ {
if ($message['level'] < $this->level) { return $message['level'] >= $this->level;
return $this->parent ? $this->parent->getHandler($message) : null;
}
return $this;
} }
public function handle($message) public function handle($message)
{ {
if ($message['level'] < $this->level) { if ($message['level'] < $this->level) {
return $this->parent ? $this->parent->handle($message) : false; return false;
} }
$originalMessage = $message; $originalMessage = $message;
@@ -63,10 +59,7 @@ abstract class AbstractHandler implements HandlerInterface
$message = $this->formatter->format($message); $message = $this->formatter->format($message);
$this->write($message); $this->write($message);
if ($this->bubble && $this->parent) { return false === $this->bubble;
$this->parent->handle($originalMessage);
}
return true;
} }
abstract public function write($message); abstract public function write($message);
@@ -115,21 +108,6 @@ abstract class AbstractHandler implements HandlerInterface
return $this->bubble; return $this->bubble;
} }
public function getParent()
{
return $this->parent;
}
/**
* Sets the parent handler
*
* @param Monolog\Handler\HandlerInterface
*/
public function setParent(HandlerInterface $parent)
{
$this->parent = $parent;
}
public function __destruct() public function __destruct()
{ {
$this->close(); $this->close();

View File

@@ -73,10 +73,7 @@ class FingersCrossedHandler extends AbstractHandler
} else { } else {
$this->handler->handle($message); $this->handler->handle($message);
} }
if ($this->bubble && $this->parent) { return false === $this->bubble;
$this->parent->handle($message);
}
return true;
} }
/** /**

View File

@@ -18,11 +18,7 @@ namespace Monolog\Handler;
*/ */
interface HandlerInterface interface HandlerInterface
{ {
public function getHandler($message); public function isHandling($message);
public function handle($message); public function handle($message);
public function getParent();
public function setParent(HandlerInterface $parent);
} }

View File

@@ -26,12 +26,9 @@ class NullHandler extends AbstractHandler
public function handle($message) public function handle($message)
{ {
if ($message['level'] < $this->level) { if ($message['level'] < $this->level) {
return $this->parent ? $this->parent->handle($message) : false; return false;
} }
if ($this->bubble && $this->parent) { return false === $this->bubble;
$this->parent->handle($originalMessage);
}
return true;
} }
public function write($message) public function write($message)

View File

@@ -56,11 +56,11 @@ class Logger
protected $name; protected $name;
/** /**
* The handler instance at the top of the handler stack * The handler stack
* *
* @var Monolog\Handler\HandlerInterface * @var array of Monolog\Handler\HandlerInterface
*/ */
protected $handler; protected $handlers = array();
protected $processors = array(); protected $processors = array();
@@ -71,38 +71,33 @@ class Logger
public function pushHandler(HandlerInterface $handler) public function pushHandler(HandlerInterface $handler)
{ {
if ($this->handler) { array_unshift($this->handlers, $handler);
if ($this->handler === $handler) {
throw new \UnexpectedValueException('Circular reference, do not add the same handler instance twice.');
}
$handler->setParent($this->handler);
}
$this->handler = $handler;
} }
public function popHandler() public function popHandler()
{ {
if (null === $this->handler) { if (!$this->handlers) {
throw new \LogicException('You tried to pop from an empty handler stack.'); throw new \LogicException('You tried to pop from an empty handler stack.');
} }
$top = $this->handler; return array_shift($this->handlers);
$this->handler = $top->getParent();
return $top;
} }
public function pushProcessor($callback) public function pushProcessor($callback)
{ {
$this->processors[] = $callback; array_unshift($this->processors, $callback);
} }
public function popProcessor() public function popProcessor()
{ {
return array_pop($this->processors); if (!$this->processors) {
throw new \LogicException('You tried to pop from an empty processor stack.');
}
return array_shift($this->processors);
} }
public function addMessage($level, $message) public function addMessage($level, $message)
{ {
if (null === $this->handler) { if (!$this->handlers) {
$this->pushHandler(new StreamHandler('php://stderr', self::DEBUG)); $this->pushHandler(new StreamHandler('php://stderr', self::DEBUG));
} }
$message = array( $message = array(
@@ -113,14 +108,23 @@ class Logger
'datetime' => new \DateTime(), 'datetime' => new \DateTime(),
'extra' => array(), 'extra' => array(),
); );
$handler = $this->handler->getHandler($message); $handlerKey = null;
if (!$handler) { foreach ($this->handlers as $key => $handler) {
if ($handler->isHandling($message)) {
$handlerKey = $key;
break;
}
}
if (null === $handlerKey) {
return false; return false;
} }
foreach ($this->processors as $processor) { foreach ($this->processors as $processor) {
$message = call_user_func($processor, $message, $this); $message = call_user_func($processor, $message, $this);
} }
$handler->handle($message); while (isset($this->handlers[$handlerKey]) &&
false === $this->handlers[$handlerKey]->handle($message)) {
$handlerKey++;
}
return true; return true;
} }

View File

@@ -29,36 +29,21 @@ class AbstractHandlerTest extends \PHPUnit_Framework_TestCase
public function testHandleBubbling() public function testHandleBubbling()
{ {
$topHandler = new TestHandler(Logger::DEBUG, true); $handler = new TestHandler(Logger::DEBUG, true);
$bottomHandler = new TestHandler(Logger::INFO); $this->assertFalse($handler->handle($this->getMessage()));
$topHandler->setParent($bottomHandler);
$this->assertTrue($topHandler->handle($this->getMessage()));
$this->assertTrue($bottomHandler->hasWarningMessages());
} }
public function testHandleNotBubbling() public function testHandleNotBubbling()
{ {
$topHandler = new TestHandler(Logger::DEBUG); $handler = new TestHandler(Logger::DEBUG);
$bottomHandler = new TestHandler(Logger::INFO); $this->assertTrue($handler->handle($this->getMessage()));
$topHandler->setParent($bottomHandler);
$this->assertTrue($topHandler->handle($this->getMessage()));
$this->assertFalse($bottomHandler->hasWarningMessages());
} }
public function testGetHandlerReturnEarly() public function testIsHandling()
{ {
$topHandler = new TestHandler(Logger::DEBUG); $handler = new TestHandler(Logger::WARNING);
$bottomHandler = new TestHandler(Logger::INFO); $this->assertTrue($handler->handle($this->getMessage()));
$topHandler->setParent($bottomHandler); $this->assertFalse($handler->handle($this->getMessage(Logger::DEBUG)));
$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) protected function getMessage($level = Logger::WARNING)