mirror of
https://github.com/Seldaek/monolog.git
synced 2025-10-27 10:46:22 +01:00
Add handling of inode changes to reopen files in StreamHandler (#1963)
This commit is contained in:
@@ -38,6 +38,7 @@ class StreamHandler extends AbstractProcessingHandler
|
||||
/** @var true|null */
|
||||
private bool|null $dirCreated = null;
|
||||
private bool $retrying = false;
|
||||
private int|null $inodeUrl = null;
|
||||
|
||||
/**
|
||||
* @param resource|string $stream If a missing path can't be created, an UnexpectedValueException will be thrown on first write
|
||||
@@ -133,6 +134,13 @@ class StreamHandler extends AbstractProcessingHandler
|
||||
*/
|
||||
protected function write(LogRecord $record): void
|
||||
{
|
||||
if ($this->hasUrlInodeWasChanged()) {
|
||||
$this->close();
|
||||
$this->write($record);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!\is_resource($this->stream)) {
|
||||
$url = $this->url;
|
||||
if (null === $url || '' === $url) {
|
||||
@@ -157,6 +165,7 @@ class StreamHandler extends AbstractProcessingHandler
|
||||
}
|
||||
stream_set_chunk_size($stream, $this->streamChunkSize);
|
||||
$this->stream = $stream;
|
||||
$this->inodeUrl = $this->getInodeFromUrl();
|
||||
}
|
||||
|
||||
$stream = $this->stream;
|
||||
@@ -246,4 +255,26 @@ class StreamHandler extends AbstractProcessingHandler
|
||||
}
|
||||
$this->dirCreated = true;
|
||||
}
|
||||
|
||||
private function getInodeFromUrl(): ?int
|
||||
{
|
||||
if ($this->url === null || $this->url === 'php://memory') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$inode = @fileinode($this->url);
|
||||
|
||||
return $inode === false ? null : $inode;
|
||||
}
|
||||
|
||||
private function hasUrlInodeWasChanged(): bool
|
||||
{
|
||||
if ($this->inodeUrl === null || $this->retrying || $this->inodeUrl === $this->getInodeFromUrl()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->retrying = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,4 +365,16 @@ The exception occurred while attempting to log: test');
|
||||
ini_set('memory_limit', $previousValue);
|
||||
}
|
||||
}
|
||||
|
||||
public function testReopensFileIfInodeChanges()
|
||||
{
|
||||
$filename = __DIR__ . '/test.log';
|
||||
$handler = new StreamHandler($filename);
|
||||
$handler->setFormatter($this->getIdentityFormatter());
|
||||
$handler->handle($this->getRecord(Level::Warning, 'test1'));
|
||||
@unlink($filename);
|
||||
$handler->handle($this->getRecord(Level::Warning, 'test2'));
|
||||
$data = @file_get_contents($filename);
|
||||
$this->assertEquals('test2', $data);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user