diff --git a/CHANGELOG.md b/CHANGELOG.md index 557f7b41..d090053b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,10 @@ * Added support for the PHP 7.x `mongodb` extension in the MongoDBHandler * Fixed many minor issues in various handlers, and probably added a few regressions too +### 1.25.1 (2019-09-06) + + * Fixed forward-compatible interfaces to be compatible with Monolog 1.x too. + ### 1.25.0 (2019-09-06) * Deprecated SlackbotHandler, use SlackWebhookHandler or SlackHandler instead diff --git a/src/Monolog/Formatter/JsonFormatter.php b/src/Monolog/Formatter/JsonFormatter.php index de1f6964..e7e80ca7 100644 --- a/src/Monolog/Formatter/JsonFormatter.php +++ b/src/Monolog/Formatter/JsonFormatter.php @@ -137,7 +137,7 @@ class JsonFormatter extends NormalizerFormatter return 'Over '.$this->maxNormalizeDepth.' levels deep, aborting normalization'; } - if (is_array($data) || $data instanceof \Traversable) { + if (is_array($data)) { $normalized = []; $count = 1; diff --git a/src/Monolog/Handler/FilterHandler.php b/src/Monolog/Handler/FilterHandler.php index e62d43fc..f8d10072 100644 --- a/src/Monolog/Handler/FilterHandler.php +++ b/src/Monolog/Handler/FilterHandler.php @@ -13,6 +13,7 @@ namespace Monolog\Handler; use Monolog\Logger; use Monolog\ResettableInterface; +use Monolog\Formatter\FormatterInterface; /** * Simple handler wrapper that filters records based on a list of levels @@ -22,7 +23,7 @@ use Monolog\ResettableInterface; * @author Hennadiy Verkh * @author Jordi Boggiano */ -class FilterHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface +class FilterHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface, FormattableHandlerInterface { use ProcessableHandlerTrait; @@ -48,7 +49,7 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese protected $bubble; /** - * @param callable|HandlerInterface $handler Handler or factory callable($record, $this). + * @param callable|HandlerInterface $handler Handler or factory callable($record|null, $filterHandler). * @param int|array $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided * @param int|string $maxLevel Maximum level to accept, only used if $minLevelOrList is not an array * @param bool $bubble Whether the messages that are handled can bubble up the stack or not @@ -106,19 +107,11 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese return false; } - // The same logic as in FingersCrossedHandler - if (!$this->handler instanceof HandlerInterface) { - $this->handler = call_user_func($this->handler, $record, $this); - if (!$this->handler instanceof HandlerInterface) { - throw new \RuntimeException("The factory callable should return a HandlerInterface"); - } - } - if ($this->processors) { $record = $this->processRecord($record); } - $this->handler->handle($record); + $this->getHandler($record)->handle($record); return false === $this->bubble; } @@ -135,7 +128,44 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface, Rese } } - $this->handler->handleBatch($filtered); + $this->getHandler($filtered[count($filtered) - 1])->handleBatch($filtered); + } + + /** + * Return the nested handler + * + * If the handler was provided as a factory callable, this will trigger the handler's instantiation. + * + * @return HandlerInterface + */ + public function getHandler(array $record = null) + { + if (!$this->handler instanceof HandlerInterface) { + $this->handler = call_user_func($this->handler, $record, $this); + if (!$this->handler instanceof HandlerInterface) { + throw new \RuntimeException("The factory callable should return a HandlerInterface"); + } + } + + return $this->handler; + } + + /** + * {@inheritdoc} + */ + public function setFormatter(FormatterInterface $formatter): HandlerInterface + { + $this->getHandler()->setFormatter($formatter); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getFormatter(): FormatterInterface + { + return $this->getHandler()->getFormatter(); } public function reset() diff --git a/src/Monolog/Handler/FingersCrossedHandler.php b/src/Monolog/Handler/FingersCrossedHandler.php index 11f3b505..3e529f50 100644 --- a/src/Monolog/Handler/FingersCrossedHandler.php +++ b/src/Monolog/Handler/FingersCrossedHandler.php @@ -15,6 +15,7 @@ use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; use Monolog\Handler\FingersCrossed\ActivationStrategyInterface; use Monolog\Logger; use Monolog\ResettableInterface; +use Monolog\Formatter\FormatterInterface; /** * Buffers all records until a certain level is reached @@ -32,7 +33,7 @@ use Monolog\ResettableInterface; * * @author Jordi Boggiano */ -class FingersCrossedHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface +class FingersCrossedHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface, FormattableHandlerInterface { use ProcessableHandlerTrait; @@ -46,7 +47,7 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa protected $bubble; /** - * @param callable|HandlerInterface $handler Handler or factory callable($record, $fingersCrossedHandler). + * @param callable|HandlerInterface $handler Handler or factory callable($record|null, $fingersCrossedHandler). * @param int|string|ActivationStrategyInterface $activationStrategy Strategy which determines when this handler takes action, or a level name/value at which the handler is activated * @param int $bufferSize How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. * @param bool $bubble Whether the messages that are handled can bubble up the stack or not @@ -95,15 +96,8 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa if ($this->stopBuffering) { $this->buffering = false; } - if (!$this->handler instanceof HandlerInterface) { - $record = end($this->buffer) ?: null; - $this->handler = call_user_func($this->handler, $record, $this); - if (!$this->handler instanceof HandlerInterface) { - throw new \RuntimeException("The factory callable should return a HandlerInterface"); - } - } - $this->handler->handleBatch($this->buffer); + $this->getHandler(end($this->buffer) ?: null)->handleBatch($this->buffer); $this->buffer = []; } @@ -125,7 +119,7 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa $this->activate(); } } else { - $this->handler->handle($record); + $this->getHandler($record)->handle($record); } return false === $this->bubble; @@ -147,8 +141,8 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa $this->resetProcessors(); - if ($this->handler instanceof ResettableInterface) { - $this->handler->reset(); + if ($this->getHandler() instanceof ResettableInterface) { + $this->getHandler()->reset(); } } @@ -174,11 +168,48 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa return $record['level'] >= $level; }); if (count($this->buffer) > 0) { - $this->handler->handleBatch($this->buffer); + $this->getHandler(end($this->buffer) ?: null)->handleBatch($this->buffer); } } $this->buffer = []; $this->buffering = true; } + + /** + * Return the nested handler + * + * If the handler was provided as a factory callable, this will trigger the handler's instantiation. + * + * @return HandlerInterface + */ + public function getHandler(array $record = null) + { + if (!$this->handler instanceof HandlerInterface) { + $this->handler = call_user_func($this->handler, $record, $this); + if (!$this->handler instanceof HandlerInterface) { + throw new \RuntimeException("The factory callable should return a HandlerInterface"); + } + } + + return $this->handler; + } + + /** + * {@inheritdoc} + */ + public function setFormatter(FormatterInterface $formatter): HandlerInterface + { + $this->getHandler()->setFormatter($formatter); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getFormatter(): FormatterInterface + { + return $this->getHandler()->getFormatter(); + } } diff --git a/src/Monolog/Handler/SamplingHandler.php b/src/Monolog/Handler/SamplingHandler.php index 814c9048..29647873 100644 --- a/src/Monolog/Handler/SamplingHandler.php +++ b/src/Monolog/Handler/SamplingHandler.php @@ -11,6 +11,8 @@ namespace Monolog\Handler; +use Monolog\Formatter\FormatterInterface; + /** * Sampling handler * @@ -25,7 +27,7 @@ namespace Monolog\Handler; * @author Bryan Davis * @author Kunal Mehta */ -class SamplingHandler extends AbstractHandler implements ProcessableHandlerInterface +class SamplingHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface { use ProcessableHandlerTrait; @@ -40,7 +42,7 @@ class SamplingHandler extends AbstractHandler implements ProcessableHandlerInter protected $factor; /** - * @param callable|HandlerInterface $handler Handler or factory callable($record, $fingersCrossedHandler). + * @param callable|HandlerInterface $handler Handler or factory callable($record|null, $samplingHandler). * @param int $factor Sample factor (e.g. 10 means every ~10th record is sampled) */ public function __construct($handler, int $factor) @@ -56,27 +58,56 @@ class SamplingHandler extends AbstractHandler implements ProcessableHandlerInter public function isHandling(array $record): bool { - return $this->handler->isHandling($record); + return $this->getHandler($record)->isHandling($record); } public function handle(array $record): bool { if ($this->isHandling($record) && mt_rand(1, $this->factor) === 1) { - // The same logic as in FingersCrossedHandler - if (!$this->handler instanceof HandlerInterface) { - $this->handler = call_user_func($this->handler, $record, $this); - if (!$this->handler instanceof HandlerInterface) { - throw new \RuntimeException("The factory callable should return a HandlerInterface"); - } - } - if ($this->processors) { $record = $this->processRecord($record); } - $this->handler->handle($record); + $this->getHandler($record)->handle($record); } return false === $this->bubble; } + + /** + * Return the nested handler + * + * If the handler was provided as a factory callable, this will trigger the handler's instantiation. + * + * @return HandlerInterface + */ + public function getHandler(array $record = null) + { + if (!$this->handler instanceof HandlerInterface) { + $this->handler = call_user_func($this->handler, $record, $this); + if (!$this->handler instanceof HandlerInterface) { + throw new \RuntimeException("The factory callable should return a HandlerInterface"); + } + } + + return $this->handler; + } + + /** + * {@inheritdoc} + */ + public function setFormatter(FormatterInterface $formatter): HandlerInterface + { + $this->getHandler()->setFormatter($formatter); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getFormatter(): FormatterInterface + { + return $this->getHandler()->getFormatter(); + } }