Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$mustRotate in RotatingFileHandler not resetting properly #1905

Open
khoanguyen-3fc opened this issue Aug 6, 2024 · 0 comments
Open

$mustRotate in RotatingFileHandler not resetting properly #1905

khoanguyen-3fc opened this issue Aug 6, 2024 · 0 comments
Labels

Comments

@khoanguyen-3fc
Copy link

Our team is using Monolog version 2 and has encountered an issue where the $mustRotate attribute of the RotatingFileHandler is only set to false if all unrelated conditions in the rotate method are satisfied:

/**
* Rotates the files.
*/
protected function rotate(): void
{
// update filename
$this->url = $this->getTimedFilename();
$this->nextRotation = new \DateTimeImmutable('tomorrow');
// skip GC of old logs if files are unlimited
if (0 === $this->maxFiles) {
return;
}
$logFiles = glob($this->getGlobPattern());
if (false === $logFiles) {
// failed to glob
return;
}
if ($this->maxFiles >= count($logFiles)) {
// no files to remove
return;
}
// Sorting the files by name to remove the older ones
usort($logFiles, function ($a, $b) {
return strcmp($b, $a);
});
foreach (array_slice($logFiles, $this->maxFiles) as $file) {
if (is_writable($file)) {
// suppress errors here as unlink() might fail if two processes
// are cleaning up/rotating at the same time
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline): bool {
return false;
});
unlink($file);
restore_error_handler();
}
}
$this->mustRotate = false;
}

This issue interacts with Octane, leading to a serious problem where logs cannot rotate to a new file. The problem arises because the reset method is called on every RequestReceived:

https://github.com/laravel/octane/blob/2.x/src/Listeners/FlushMonologState.php

When a RotatingFileHandler instance is reset with true === $this->mustRotate, the $this->url and $this->nextRotation attributes are updated by calling rotate:

// update filename
$this->url = $this->getTimedFilename();
$this->nextRotation = new \DateTimeImmutable('tomorrow');

As a result, the write method cannot write to the new stream because $this->close() is never reached. This occurs because $this->nextRotation is already updated during the call to reset:

protected function write(array $record): void
{
// on the first record written, if the log is new, we should rotate (once per day)
if (null === $this->mustRotate) {
$this->mustRotate = null === $this->url || !file_exists($this->url);
}
if ($this->nextRotation <= $record['datetime']) {
$this->mustRotate = true;
$this->close();
}
parent::write($record);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant