1
0
mirror of https://github.com/Seldaek/monolog.git synced 2025-10-24 18:16:10 +02:00

Fix cycle detection within fibers (#1753)

* Fix cycle detection within fibers

We keep a separate depth count per fiber.

Fixes #1752.

* Avoid additional call to Fiber::getCurrent()

Suppresses phpstan errors, as they're false positives.
This commit is contained in:
Niklas Keller
2023-02-04 15:49:17 +01:00
committed by GitHub
parent 58f503004d
commit 0f014206a4
2 changed files with 106 additions and 4 deletions

View File

@@ -168,6 +168,11 @@ class Logger implements LoggerInterface, ResettableInterface
*/
private $logDepth = 0;
/**
* @var \WeakMap<\Fiber, int>|null Keeps track of depth inside fibers to prevent infinite logging loops
*/
private $fiberLogDepth;
/**
* @var bool Whether to detect infinite logging loops
*
@@ -189,6 +194,13 @@ class Logger implements LoggerInterface, ResettableInterface
$this->setHandlers($handlers);
$this->processors = $processors;
$this->timezone = $timezone ?: new DateTimeZone(date_default_timezone_get() ?: 'UTC');
if (\PHP_VERSION_ID >= 80100) {
// Local variable for phpstan, see https://github.com/phpstan/phpstan/issues/6732#issuecomment-1111118412
/** @var \WeakMap<\Fiber, int> $fiberLogDepth */
$fiberLogDepth = new \WeakMap();
$this->fiberLogDepth = $fiberLogDepth;
}
}
public function getName(): string
@@ -332,12 +344,21 @@ class Logger implements LoggerInterface, ResettableInterface
}
if ($this->detectCycles) {
$this->logDepth += 1;
// @phpstan-ignore-next-line
if (\PHP_VERSION_ID >= 80100 && $fiber = \Fiber::getCurrent()) {
$this->fiberLogDepth[$fiber] = $this->fiberLogDepth[$fiber] ?? 0;
$logDepth = ++$this->fiberLogDepth[$fiber];
} else {
$logDepth = ++$this->logDepth;
}
} else {
$logDepth = 0;
}
if ($this->logDepth === 3) {
if ($logDepth === 3) {
$this->warning('A possible infinite logging loop was detected and aborted. It appears some of your handler code is triggering logging, see the previous log record for a hint as to what may be the cause.');
return false;
} elseif ($this->logDepth >= 5) { // log depth 4 is let through so we can log the warning above
} elseif ($logDepth >= 5) { // log depth 4 is let through, so we can log the warning above
return false;
}
@@ -387,7 +408,12 @@ class Logger implements LoggerInterface, ResettableInterface
}
} finally {
if ($this->detectCycles) {
$this->logDepth--;
if (isset($fiber)) {
// @phpstan-ignore-next-line
$this->fiberLogDepth[$fiber]--;
} else {
$this->logDepth--;
}
}
}