Explorar el Código

Fix support of yearly and monthly rotation log file to rotate only once a month/year (#1805)

Co-authored-by: liutao <liutao@ifun.com>
Co-authored-by: liutao02 <liutao02@xiaoduotech.com>
liutao hace 2 años
padre
commit
8c70660c17
Se han modificado 1 ficheros con 27 adiciones y 14 borrados
  1. 27 14
      src/Monolog/Handler/RotatingFileHandler.php

+ 27 - 14
src/Monolog/Handler/RotatingFileHandler.php

@@ -43,13 +43,12 @@ class RotatingFileHandler extends StreamHandler
      * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write)
      * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write)
      * @param bool     $useLocking     Try to lock log file before doing any writes
      * @param bool     $useLocking     Try to lock log file before doing any writes
      */
      */
-    public function __construct(string $filename, int $maxFiles = 0, int|string|Level $level = Level::Debug, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false)
+    public function __construct(string $filename, int $maxFiles = 0, int|string|Level $level = Level::Debug, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false, string $dateFormat = self::FILE_PER_DAY, string $filenameFormat  = '{filename}-{date}')
     {
     {
         $this->filename = Utils::canonicalizePath($filename);
         $this->filename = Utils::canonicalizePath($filename);
         $this->maxFiles = $maxFiles;
         $this->maxFiles = $maxFiles;
-        $this->nextRotation = new \DateTimeImmutable('tomorrow');
-        $this->filenameFormat = '{filename}-{date}';
-        $this->dateFormat = static::FILE_PER_DAY;
+        $this->setFilenameFormat($filenameFormat, $dateFormat);
+        $this->nextRotation = $this->getNextRotation();
 
 
         parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission, $useLocking);
         parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission, $useLocking);
     }
     }
@@ -80,21 +79,13 @@ class RotatingFileHandler extends StreamHandler
 
 
     public function setFilenameFormat(string $filenameFormat, string $dateFormat): self
     public function setFilenameFormat(string $filenameFormat, string $dateFormat): self
     {
     {
-        if (0 === preg_match('{^[Yy](([/_.-]?m)([/_.-]?d)?)?$}', $dateFormat)) {
-            throw new InvalidArgumentException(
-                'Invalid date format - format must be one of '.
-                'RotatingFileHandler::FILE_PER_DAY ("Y-m-d"), RotatingFileHandler::FILE_PER_MONTH ("Y-m") '.
-                'or RotatingFileHandler::FILE_PER_YEAR ("Y"), or you can set one of the '.
-                'date formats using slashes, underscores and/or dots instead of dashes.'
-            );
-        }
+        $this->setDateFormat($dateFormat);
         if (substr_count($filenameFormat, '{date}') === 0) {
         if (substr_count($filenameFormat, '{date}') === 0) {
             throw new InvalidArgumentException(
             throw new InvalidArgumentException(
                 'Invalid filename format - format must contain at least `{date}`, because otherwise rotating is impossible.'
                 'Invalid filename format - format must contain at least `{date}`, because otherwise rotating is impossible.'
             );
             );
         }
         }
         $this->filenameFormat = $filenameFormat;
         $this->filenameFormat = $filenameFormat;
-        $this->dateFormat = $dateFormat;
         $this->url = $this->getTimedFilename();
         $this->url = $this->getTimedFilename();
         $this->close();
         $this->close();
 
 
@@ -126,7 +117,7 @@ class RotatingFileHandler extends StreamHandler
     {
     {
         // update filename
         // update filename
         $this->url = $this->getTimedFilename();
         $this->url = $this->getTimedFilename();
-        $this->nextRotation = new \DateTimeImmutable('tomorrow');
+        $this->nextRotation = $this->getNextRotation();
 
 
         // skip GC of old logs if files are unlimited
         // skip GC of old logs if files are unlimited
         if (0 === $this->maxFiles) {
         if (0 === $this->maxFiles) {
@@ -198,4 +189,26 @@ class RotatingFileHandler extends StreamHandler
 
 
         return $glob;
         return $glob;
     }
     }
+
+    protected function setDateFormat(string $dateFormat): void
+    {
+        if (0 === preg_match('{^[Yy](([/_.-]?m)([/_.-]?d)?)?$}', $dateFormat)) {
+            throw new InvalidArgumentException(
+                'Invalid date format - format must be one of '.
+                'RotatingFileHandler::FILE_PER_DAY ("Y-m-d"), RotatingFileHandler::FILE_PER_MONTH ("Y-m") '.
+                'or RotatingFileHandler::FILE_PER_YEAR ("Y"), or you can set one of the '.
+                'date formats using slashes, underscores and/or dots instead of dashes.'
+            );
+        }
+        $this->dateFormat = $dateFormat;
+    }
+
+    protected function getNextRotation(): \DateTimeImmutable
+    {
+        return match (str_replace(['/','_','.'], '-', $this->dateFormat)) {
+            self::FILE_PER_MONTH => (new \DateTimeImmutable('first day of next month'))->setTime(0, 0, 0),
+            self::FILE_PER_YEAR => (new \DateTimeImmutable('first day of January next year'))->setTime(0, 0, 0),
+            default => (new \DateTimeImmutable('tomorrow'))->setTime(0, 0, 0),
+        };
+    }
 }
 }