1
0
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:
Cesar Garcia
2025-10-23 21:12:34 +02:00
committed by GitHub
parent e1d85dbd82
commit 282b43c996
2 changed files with 43 additions and 0 deletions

View File

@@ -38,6 +38,7 @@ class StreamHandler extends AbstractProcessingHandler
/** @var true|null */ /** @var true|null */
private bool|null $dirCreated = null; private bool|null $dirCreated = null;
private bool $retrying = false; 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 * @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 protected function write(LogRecord $record): void
{ {
if ($this->hasUrlInodeWasChanged()) {
$this->close();
$this->write($record);
return;
}
if (!\is_resource($this->stream)) { if (!\is_resource($this->stream)) {
$url = $this->url; $url = $this->url;
if (null === $url || '' === $url) { if (null === $url || '' === $url) {
@@ -157,6 +165,7 @@ class StreamHandler extends AbstractProcessingHandler
} }
stream_set_chunk_size($stream, $this->streamChunkSize); stream_set_chunk_size($stream, $this->streamChunkSize);
$this->stream = $stream; $this->stream = $stream;
$this->inodeUrl = $this->getInodeFromUrl();
} }
$stream = $this->stream; $stream = $this->stream;
@@ -246,4 +255,26 @@ class StreamHandler extends AbstractProcessingHandler
} }
$this->dirCreated = true; $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;
}
} }

View File

@@ -365,4 +365,16 @@ The exception occurred while attempting to log: test');
ini_set('memory_limit', $previousValue); 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);
}
} }