Ver Fonte

[#1878] User definable duplication for DeduplicationHandler (#1879)

cracksalad há 1 ano atrás
pai
commit
c48c642b9a
1 ficheiros alterados com 28 adições e 20 exclusões
  1. 28 20
      src/Monolog/Handler/DeduplicationHandler.php

+ 28 - 20
src/Monolog/Handler/DeduplicationHandler.php

@@ -43,8 +43,7 @@ class DeduplicationHandler extends BufferHandler
     protected Level $deduplicationLevel;
 
     protected int $time;
-
-    private bool $gc = false;
+    protected bool $gc = false;
 
     /**
      * @param HandlerInterface                       $handler            Handler.
@@ -70,13 +69,24 @@ class DeduplicationHandler extends BufferHandler
             return;
         }
 
+        $store = null;
+
+        if (file_exists($this->deduplicationStore)) {
+            $store = file($this->deduplicationStore, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+        }
+
         $passthru = null;
 
         foreach ($this->buffer as $record) {
             if ($record->level->value >= $this->deduplicationLevel->value) {
-                $passthru = $passthru === true || !$this->isDuplicate($record);
+                $passthru = $passthru === true || !is_array($store) || !$this->isDuplicate($store, $record);
                 if ($passthru) {
-                    $this->appendRecord($record);
+                    $line = $this->buildDeduplicationStoreEntry($record);
+                    file_put_contents($this->deduplicationStore, $line . "\n", FILE_APPEND);
+                    if (!is_array($store)) {
+                        $store = [];
+                    }
+                    $store[] = $line;
                 }
             }
         }
@@ -93,20 +103,15 @@ class DeduplicationHandler extends BufferHandler
         }
     }
 
-    private function isDuplicate(LogRecord $record): bool
+    /**
+     * If there is a store entry older than e.g. a day, this method should set `$this->gc` to `true` to trigger garbage collection.
+     * @param string[] $store The deduplication store
+     */
+    protected function isDuplicate(array $store, LogRecord $record): bool
     {
-        if (!file_exists($this->deduplicationStore)) {
-            return false;
-        }
-
-        $store = file($this->deduplicationStore, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
-        if (!is_array($store)) {
-            return false;
-        }
-
-        $yesterday = time() - 86400;
         $timestampValidity = $record->datetime->getTimestamp() - $this->time;
         $expectedMessage = preg_replace('{[\r\n].*}', '', $record->message);
+        $yesterday = time() - 86400;
 
         for ($i = count($store) - 1; $i >= 0; $i--) {
             list($timestamp, $level, $message) = explode(':', $store[$i], 3);
@@ -123,6 +128,14 @@ class DeduplicationHandler extends BufferHandler
         return false;
     }
 
+    /**
+     * @return string The given record serialized as a single line of text
+     */
+    protected function buildDeduplicationStoreEntry(LogRecord $record): string
+    {
+        return $record->datetime->getTimestamp() . ':' . $record->level->getName() . ':' . preg_replace('{[\r\n].*}', '', $record->message);
+    }
+
     private function collectLogs(): void
     {
         if (!file_exists($this->deduplicationStore)) {
@@ -158,9 +171,4 @@ class DeduplicationHandler extends BufferHandler
 
         $this->gc = false;
     }
-
-    private function appendRecord(LogRecord $record): void
-    {
-        file_put_contents($this->deduplicationStore, $record->datetime->getTimestamp() . ':' . $record->level->getName() . ':' . preg_replace('{[\r\n].*}', '', $record->message) . "\n", FILE_APPEND);
-    }
 }