1
0
mirror of https://github.com/Seldaek/monolog.git synced 2025-08-08 14:16:42 +02:00

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>
This commit is contained in:
liutao
2023-06-21 16:37:30 +08:00
committed by GitHub
parent 1fd8e8c2c7
commit 8c70660c17

View File

@@ -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->setFilenameFormat($filenameFormat, $dateFormat);
$this->filenameFormat = '{filename}-{date}'; $this->nextRotation = $this->getNextRotation();
$this->dateFormat = static::FILE_PER_DAY;
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)) { $this->setDateFormat($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.'
);
}
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),
};
}
} }