Quellcode durchsuchen

Add FallbackGroupHandler

Malachi Soord vor 6 Jahren
Ursprung
Commit
ab236865a7

+ 5 - 0
doc/02-handlers-formatters-processors.md

@@ -108,6 +108,11 @@
    exceptions raised by each child handler. This allows you to ignore issues
    exceptions raised by each child handler. This allows you to ignore issues
    where a remote tcp connection may have died but you do not want your entire
    where a remote tcp connection may have died but you do not want your entire
    application to crash and may wish to continue to log to other handlers.
    application to crash and may wish to continue to log to other handlers.
+- [_FallbackGroupHandler_](../src/Monolog/Handler/FallbackGroupHandler.php): This handler extends the _GroupHandler_ ignoring
+   exceptions raised by each child handler, until one has handled without throwing.
+   This allows you to ignore issues where a remote tcp connection may have died 
+   but you do not want your entire application to crash and may wish to continue 
+   to attempt log to other handlers, until one does not throw.
 - [_BufferHandler_](../src/Monolog/Handler/BufferHandler.php): This handler will buffer all the log records it receives
 - [_BufferHandler_](../src/Monolog/Handler/BufferHandler.php): This handler will buffer all the log records it receives
   until `close()` is called at which point it will call `handleBatch()` on the
   until `close()` is called at which point it will call `handleBatch()` on the
   handler it wraps with all the log messages at once. This is very useful to
   handler it wraps with all the log messages at once. This is very useful to

+ 63 - 0
src/Monolog/Handler/FallbackGroupHandler.php

@@ -0,0 +1,63 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Throwable;
+
+class FallbackGroupHandler extends GroupHandler
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function handle(array $record): bool
+    {
+        if ($this->processors) {
+            foreach ($this->processors as $processor) {
+                $record = call_user_func($processor, $record);
+            }
+        }
+        foreach ($this->handlers as $handler) {
+            try {
+                $handler->handle($record);
+                break;
+            } catch (Throwable $e) {
+                // What throwable?
+            }
+        }
+        return false === $this->bubble;
+    }
+    /**
+     * {@inheritdoc}
+     */
+    public function handleBatch(array $records): void
+    {
+        if ($this->processors) {
+            $processed = [];
+            foreach ($records as $record) {
+                foreach ($this->processors as $processor) {
+                    $record = call_user_func($processor, $record);
+                }
+                $processed[] = $record;
+            }
+            $records = $processed;
+        }
+
+        foreach ($this->handlers as $handler) {
+            try {
+                $handler->handleBatch($records);
+                break;
+            } catch (Throwable $e) {
+                // What throwable?
+            }
+        }
+    }
+}

+ 27 - 0
tests/Monolog/Handler/ExceptionTestHandler.php

@@ -0,0 +1,27 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Exception;
+
+class ExceptionTestHandler extends TestHandler
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function handle(array $record): bool
+    {
+        throw new Exception("ExceptionTestHandler::handle");
+
+        parent::handle($record);
+    }
+}

+ 141 - 0
tests/Monolog/Handler/FallbackGroupHandlerTest.php

@@ -0,0 +1,141 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Test\TestCase;
+
+class FallbackGroupHandlerTest extends TestCase
+{
+    /**
+     * @covers Monolog\Handler\FallbackGroupHandler::__construct
+     * @covers Monolog\Handler\FallbackGroupHandler::handle
+     */
+    public function testHandle()
+    {
+        $testHandlerOne = new TestHandler();
+        $testHandlerTwo = new TestHandler();
+        $testHandlers = [$testHandlerOne, $testHandlerTwo];
+        $handler = new FallbackGroupHandler($testHandlers);
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::INFO));
+
+        $this->assertCount(2, $testHandlerOne->getRecords());
+        $this->assertCount(0, $testHandlerTwo->getRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\FallbackGroupHandler::__construct
+     * @covers Monolog\Handler\FallbackGroupHandler::handle
+     */
+    public function testHandleExceptionThrown()
+    {
+        $testHandlerOne = new ExceptionTestHandler();
+        $testHandlerTwo = new TestHandler();
+        $testHandlers = [$testHandlerOne, $testHandlerTwo];
+        $handler = new FallbackGroupHandler($testHandlers);
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::INFO));
+
+        $this->assertCount(0, $testHandlerOne->getRecords());
+        $this->assertCount(2, $testHandlerTwo->getRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\FallbackGroupHandler::handleBatch
+     */
+    public function testHandleBatch()
+    {
+        $testHandlerOne = new TestHandler();
+        $testHandlerTwo = new TestHandler();
+        $testHandlers = [$testHandlerOne, $testHandlerTwo];
+        $handler = new FallbackGroupHandler($testHandlers);
+        $handler->handleBatch([$this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO)]);
+        $this->assertCount(2, $testHandlerOne->getRecords());
+        $this->assertCount(0, $testHandlerTwo->getRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\FallbackGroupHandler::handleBatch
+     */
+    public function testHandleBatchExceptionThrown()
+    {
+        $testHandlerOne = new ExceptionTestHandler();
+        $testHandlerTwo = new TestHandler();
+        $testHandlers = [$testHandlerOne, $testHandlerTwo];
+        $handler = new FallbackGroupHandler($testHandlers);
+        $handler->handleBatch([$this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO)]);
+        $this->assertCount(0, $testHandlerOne->getRecords());
+        $this->assertCount(2, $testHandlerTwo->getRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\FallbackGroupHandler::isHandling
+     */
+    public function testIsHandling()
+    {
+        $testHandlers = [new TestHandler(Logger::ERROR), new TestHandler(Logger::WARNING)];
+        $handler = new FallbackGroupHandler($testHandlers);
+        $this->assertTrue($handler->isHandling($this->getRecord(Logger::ERROR)));
+        $this->assertTrue($handler->isHandling($this->getRecord(Logger::WARNING)));
+        $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG)));
+    }
+
+    /**
+     * @covers Monolog\Handler\FallbackGroupHandler::handle
+     */
+    public function testHandleUsesProcessors()
+    {
+        $test = new TestHandler();
+        $handler = new FallbackGroupHandler([$test]);
+        $handler->pushProcessor(function ($record) {
+            $record['extra']['foo'] = true;
+
+            return $record;
+        });
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $this->assertTrue($test->hasWarningRecords());
+        $records = $test->getRecords();
+        $this->assertTrue($records[0]['extra']['foo']);
+    }
+
+    /**
+     * @covers Monolog\Handler\FallbackGroupHandler::handleBatch
+     */
+    public function testHandleBatchUsesProcessors()
+    {
+        $testHandlerOne = new ExceptionTestHandler();
+        $testHandlerTwo = new TestHandler();
+        $testHandlers = [$testHandlerOne, $testHandlerTwo];
+        $handler = new FallbackGroupHandler($testHandlers);
+        $handler->pushProcessor(function ($record) {
+            $record['extra']['foo'] = true;
+
+            return $record;
+        });
+        $handler->pushProcessor(function ($record) {
+            $record['extra']['foo2'] = true;
+
+            return $record;
+        });
+        $handler->handleBatch([$this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO)]);
+        $this->assertEmpty($testHandlerOne->getRecords());
+        $this->assertTrue($testHandlerTwo->hasDebugRecords());
+        $this->assertTrue($testHandlerTwo->hasInfoRecords());
+        $this->assertCount(2, $testHandlerTwo->getRecords());
+        $records = $testHandlerTwo->getRecords();
+        $this->assertTrue($records[0]['extra']['foo']);
+        $this->assertTrue($records[1]['extra']['foo']);
+        $this->assertTrue($records[0]['extra']['foo2']);
+        $this->assertTrue($records[1]['extra']['foo2']);
+    }
+}

+ 0 - 13
tests/Monolog/Handler/WhatFailureGroupHandlerTest.php

@@ -136,16 +136,3 @@ class WhatFailureGroupHandlerTest extends TestCase
         $this->assertTrue($records[0]['extra']['foo']);
         $this->assertTrue($records[0]['extra']['foo']);
     }
     }
 }
 }
-
-class ExceptionTestHandler extends TestHandler
-{
-    /**
-     * {@inheritdoc}
-     */
-    public function handle(array $record): bool
-    {
-        parent::handle($record);
-
-        throw new \Exception("ExceptionTestHandler::handle");
-    }
-}