Browse Source

Merge branch '1.x', clean up close/reset for 2.0, refs #997

Jordi Boggiano 7 năm trước cách đây
mục cha
commit
e07c948042

+ 0 - 1
src/Monolog/Handler/AbstractHandler.php

@@ -92,6 +92,5 @@ abstract class AbstractHandler extends Handler implements ResettableInterface
 
     public function reset()
     {
-        $this->close();
     }
 }

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

@@ -11,10 +11,8 @@
 
 namespace Monolog\Handler;
 
-use Monolog\ResettableInterface;
-
 /**
- * Base Handler class providing the Handler structure
+ * Base Handler class providing the Handler structure, including processors and formatters
  *
  * Classes extending it should (in most cases) only implement write($record)
  *
@@ -55,10 +53,6 @@ abstract class AbstractProcessingHandler extends AbstractHandler implements Proc
     {
         parent::reset();
 
-        foreach ($this->processors as $processor) {
-            if ($processor instanceof ResettableInterface) {
-                $processor->reset();
-            }
-        }
+        $this->resetProcessors();
     }
 }

+ 5 - 1
src/Monolog/Handler/BrowserConsoleHandler.php

@@ -13,7 +13,6 @@ namespace Monolog\Handler;
 
 use Monolog\Formatter\LineFormatter;
 use Monolog\Formatter\FormatterInterface;
-use Monolog\ResettableInterface;
 
 /**
  * Handler sending logs to browser's javascript console with no browser extension required
@@ -75,6 +74,11 @@ class BrowserConsoleHandler extends AbstractProcessingHandler
         }
     }
 
+    public function close()
+    {
+        self::resetStatic();
+    }
+
     public function reset()
     {
         parent::reset();

+ 6 - 0
src/Monolog/Handler/BufferHandler.php

@@ -105,6 +105,8 @@ class BufferHandler extends AbstractHandler implements ProcessableHandlerInterfa
     public function close(): void
     {
         $this->flush();
+
+        $this->handler->close();
     }
 
     /**
@@ -118,8 +120,12 @@ class BufferHandler extends AbstractHandler implements ProcessableHandlerInterfa
 
     public function reset()
     {
+        $this->flush();
+
         parent::reset();
 
+        $this->resetProcessors();
+
         if ($this->handler instanceof ResettableInterface) {
             $this->handler->reset();
         }

+ 7 - 1
src/Monolog/Handler/FilterHandler.php

@@ -12,6 +12,7 @@
 namespace Monolog\Handler;
 
 use Monolog\Logger;
+use Monolog\ResettableInterface;
 
 /**
  * Simple handler wrapper that filters records based on a list of levels
@@ -21,7 +22,7 @@ use Monolog\Logger;
  * @author Hennadiy Verkh
  * @author Jordi Boggiano <j.boggiano@seld.be>
  */
-class FilterHandler extends Handler implements ProcessableHandlerInterface
+class FilterHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface
 {
     use ProcessableHandlerTrait;
 
@@ -137,4 +138,9 @@ class FilterHandler extends Handler implements ProcessableHandlerInterface
 
         $this->handler->handleBatch($filtered);
     }
+
+    public function reset()
+    {
+        $this->resetProcessors();
+    }
 }

+ 25 - 15
src/Monolog/Handler/FingersCrossedHandler.php

@@ -131,25 +131,16 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
      */
     public function close(): void
     {
-        if (null !== $this->passthruLevel) {
-            $level = $this->passthruLevel;
-            $this->buffer = array_filter($this->buffer, function ($record) use ($level) {
-                return $record['level'] >= $level;
-            });
-            if (count($this->buffer) > 0) {
-                $this->handler->handleBatch($this->buffer);
-                $this->buffer = [];
-            }
-        }
+        $this->flushBuffer();
+
+        $this->handler->close();
     }
 
-    /**
-     * Resets the state of the handler. Stops forwarding records to the wrapped handler.
-     */
     public function reset()
     {
-        $this->buffer = array();
-        $this->buffering = true;
+        $this->flushBuffer();
+
+        $this->resetProcessors();
 
         if ($this->handler instanceof ResettableInterface) {
             $this->handler->reset();
@@ -166,4 +157,23 @@ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterfa
         $this->buffer = [];
         $this->reset();
     }
+
+    /**
+     * Resets the state of the handler. Stops forwarding records to the wrapped handler.
+     */
+    private function flushBuffer()
+    {
+        if (null !== $this->passthruLevel) {
+            $level = $this->passthruLevel;
+            $this->buffer = array_filter($this->buffer, function ($record) use ($level) {
+                return $record['level'] >= $level;
+            });
+            if (count($this->buffer) > 0) {
+                $this->handler->handleBatch($this->buffer);
+            }
+        }
+
+        $this->buffer = [];
+        $this->buffering = true;
+    }
 }

+ 2 - 0
src/Monolog/Handler/GroupHandler.php

@@ -93,6 +93,8 @@ class GroupHandler extends Handler implements ProcessableHandlerInterface, Reset
 
     public function reset()
     {
+        $this->resetProcessors();
+
         foreach ($this->handlers as $handler) {
             if ($handler instanceof ResettableInterface) {
                 $handler->reset();

+ 9 - 1
src/Monolog/Handler/HandlerInterface.php

@@ -59,10 +59,18 @@ interface HandlerInterface
     /**
      * Closes the handler.
      *
-     * This will be called automatically when the object is destroyed if you extend Monolog\Handler\Handler
+     * Ends a log cycle and frees all resources used by the handler.
+     *
+     * Closing a Handler means flushing all buffers and freeing any open resources/handles.
      *
      * Implementations have to be idempotent (i.e. it should be possible to call close several times without breakage)
      * and ideally handlers should be able to reopen themselves on handle() after they have been closed.
+     *
+     * This is useful at the end of a request and will be called automatically when the object
+     * is destroyed if you extend Monolog\Handler\Handler.
+     *
+     * If you are thinking of calling this method yourself, most likely you should be
+     * calling ResettableInterface::reset instead. Have a look.
      */
     public function close(): void;
 }

+ 11 - 0
src/Monolog/Handler/ProcessableHandlerTrait.php

@@ -11,6 +11,8 @@
 
 namespace Monolog\Handler;
 
+use Monolog\ResettableInterface;
+
 /**
  * Helper trait for implementing ProcessableInterface
  *
@@ -57,4 +59,13 @@ trait ProcessableHandlerTrait
 
         return $record;
     }
+
+    protected function resetProcessors()
+    {
+        foreach ($this->processors as $processor) {
+            if ($processor instanceof ResettableInterface) {
+                $processor->reset();
+            }
+        }
+    }
 }

+ 11 - 1
src/Monolog/Handler/RollbarHandler.php

@@ -102,7 +102,7 @@ class RollbarHandler extends AbstractProcessingHandler
         $this->hasRecords = true;
     }
 
-    public function flush()
+    public function flush(): void
     {
         if ($this->hasRecords) {
             $this->rollbarLogger->flush();
@@ -117,4 +117,14 @@ class RollbarHandler extends AbstractProcessingHandler
     {
         $this->flush();
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function reset()
+    {
+        $this->flush();
+
+        parent::reset();
+    }
 }

+ 12 - 0
src/Monolog/Handler/RotatingFileHandler.php

@@ -67,6 +67,18 @@ class RotatingFileHandler extends StreamHandler
         }
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function reset()
+    {
+        parent::reset();
+
+        if (true === $this->mustRotate) {
+            $this->rotate();
+        }
+    }
+
     public function setFilenameFormat($filenameFormat, $dateFormat)
     {
         if (!preg_match('{^Y(([/_.-]?m)([/_.-]?d)?)?$}', $dateFormat)) {

+ 27 - 0
src/Monolog/Logger.php

@@ -333,6 +333,33 @@ class Logger implements LoggerInterface, ResettableInterface
         return true;
     }
 
+    /**
+     * Ends a log cycle and frees all resources used by handlers.
+     *
+     * Closing a Handler means flushing all buffers and freeing any open resources/handles.
+     * Handlers that have been closed should be able to accept log records again and re-open
+     * themselves on demand, but this may not always be possible depending on implementation.
+     *
+     * This is useful at the end of a request and will be called automatically on every handler
+     * when they get destructed.
+     */
+    public function close()
+    {
+        foreach ($this->handlers as $handler) {
+            $handler->close();
+        }
+    }
+
+    /**
+     * Ends a log cycle and resets all handlers and processors to their initial state.
+     *
+     * Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal
+     * state, and getting it back to a state in which it can receive log records again.
+     *
+     * This is useful in case you want to avoid logs leaking between two requests or jobs when you
+     * have a long running process like a worker or an application server serving multiple requests
+     * in one process.
+     */
     public function reset()
     {
         foreach ($this->handlers as $handler) {

+ 8 - 2
src/Monolog/ResettableInterface.php

@@ -14,8 +14,14 @@ namespace Monolog;
 /**
  * Handler or Processor implementing this interface will be reset when Logger::reset() is called.
  *
- * Resetting an Handler or a Processor usually means cleaning all buffers or
- * resetting in its internal state. This should also generally close() the handler.
+ * Resetting ends a log cycle gets them back to their initial state.
+ *
+ * Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal
+ * state, and getting it back to a state in which it can receive log records again.
+ *
+ * This is useful in case you want to avoid logs leaking between two requests or jobs when you
+ * have a long running process like a worker or an application server serving multiple requests
+ * in one process.
  *
  * @author Grégoire Pineau <lyrixx@lyrixx.info>
  */