From 8ac56aa42bff0f099af28ebe03c43004e9bc0c44 Mon Sep 17 00:00:00 2001 From: Gene Alyson Fortunado Torcende Date: Thu, 9 Jun 2022 16:41:11 +0800 Subject: [PATCH] RotatingFileHandler to maintain the correct maximum number files when using folder by date (#1671) --- src/Monolog/Handler/RotatingFileHandler.php | 6 +- .../Handler/RotatingFileHandlerTest.php | 98 +++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/src/Monolog/Handler/RotatingFileHandler.php b/src/Monolog/Handler/RotatingFileHandler.php index 2b7c4803..17745d22 100644 --- a/src/Monolog/Handler/RotatingFileHandler.php +++ b/src/Monolog/Handler/RotatingFileHandler.php @@ -191,7 +191,11 @@ class RotatingFileHandler extends StreamHandler $fileInfo = pathinfo($this->filename); $glob = str_replace( ['{filename}', '{date}'], - [$fileInfo['filename'], '[0-9][0-9][0-9][0-9]*'], + [$fileInfo['filename'], str_replace( + ['Y', 'y', 'm', 'd'], + ['[0-9][0-9][0-9][0-9]', '[0-9][0-9]', '[0-9][0-9]', '[0-9][0-9]'], + $this->dateFormat) + ], $fileInfo['dirname'] . '/' . $this->filenameFormat ); if (isset($fileInfo['extension'])) { diff --git a/tests/Monolog/Handler/RotatingFileHandlerTest.php b/tests/Monolog/Handler/RotatingFileHandlerTest.php index dd77c853..1f94adf5 100644 --- a/tests/Monolog/Handler/RotatingFileHandlerTest.php +++ b/tests/Monolog/Handler/RotatingFileHandlerTest.php @@ -46,11 +46,38 @@ class RotatingFileHandlerTest extends TestCase foreach (glob(__DIR__.'/Fixtures/*.rot') as $file) { unlink($file); } + + if ('testRotationWithFolderByDate' === $this->getName(false)) { + foreach (glob(__DIR__.'/Fixtures/[0-9]*') as $folder) { + $this->rrmdir($folder); + } + } + restore_error_handler(); unset($this->lastError); } + private function rrmdir($directory) { + if (! is_dir($directory)) { + throw new InvalidArgumentException("$directory must be a directory"); + } + + if (substr($directory, strlen($directory) - 1, 1) !== '/') { + $directory .= '/'; + } + + foreach (glob($directory . '*', GLOB_MARK) as $path) { + if (is_dir($path)) { + $this->rrmdir($path); + } else { + unlink($path); + } + } + + return rmdir($directory); + } + private function assertErrorWasTriggered($code, $message) { if (empty($this->lastError)) { @@ -141,6 +168,76 @@ class RotatingFileHandlerTest extends TestCase ]; } + private function createDeep($file) + { + mkdir(dirname($file), 0777, true); + touch($file); + + return $file; + } + + /** + * @dataProvider rotationWithFolderByDateTests + */ + public function testRotationWithFolderByDate($createFile, $dateFormat, $timeCallback) + { + $old1 = $this->createDeep(__DIR__.'/Fixtures/'.date($dateFormat, $timeCallback(-1)).'/foo.rot'); + $old2 = $this->createDeep(__DIR__.'/Fixtures/'.date($dateFormat, $timeCallback(-2)).'/foo.rot'); + $old3 = $this->createDeep(__DIR__.'/Fixtures/'.date($dateFormat, $timeCallback(-3)).'/foo.rot'); + $old4 = $this->createDeep(__DIR__.'/Fixtures/'.date($dateFormat, $timeCallback(-4)).'/foo.rot'); + + $log = __DIR__.'/Fixtures/'.date($dateFormat).'/foo.rot'; + + if ($createFile) { + $this->createDeep($log); + } + + $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2); + $handler->setFormatter($this->getIdentityFormatter()); + $handler->setFilenameFormat('{date}/{filename}', $dateFormat); + $handler->handle($this->getRecord()); + + $handler->close(); + + $this->assertTrue(file_exists($log)); + $this->assertTrue(file_exists($old1)); + $this->assertEquals($createFile, file_exists($old2)); + $this->assertEquals($createFile, file_exists($old3)); + $this->assertEquals($createFile, file_exists($old4)); + $this->assertEquals('test', file_get_contents($log)); + } + + public function rotationWithFolderByDateTests() + { + $now = time(); + $dayCallback = function ($ago) use ($now) { + return $now + 86400 * $ago; + }; + $monthCallback = function ($ago) { + return gmmktime(0, 0, 0, (int) (date('n') + $ago), 1, (int) date('Y')); + }; + $yearCallback = function ($ago) { + return gmmktime(0, 0, 0, 1, 1, (int) (date('Y') + $ago)); + }; + + return [ + 'Rotation is triggered when the file of the current day is not present' + => [true, 'Y/m/d', $dayCallback], + 'Rotation is not triggered when the file of the current day is already present' + => [false, 'Y/m/d', $dayCallback], + + 'Rotation is triggered when the file of the current month is not present' + => [true, 'Y/m', $monthCallback], + 'Rotation is not triggered when the file of the current month is already present' + => [false, 'Y/m', $monthCallback], + + 'Rotation is triggered when the file of the current year is not present' + => [true, 'Y', $yearCallback], + 'Rotation is not triggered when the file of the current year is already present' + => [false, 'Y', $yearCallback], + ]; + } + /** * @dataProvider dateFormatProvider */ @@ -205,6 +302,7 @@ class RotatingFileHandlerTest extends TestCase ['foobar-{date}', true], ['foo-{date}-bar', true], ['{date}-foobar', true], + ['{date}/{filename}', true], ['foobar', false], ]; }