Skip to content

Commit aa53cd9

Browse files
authored
Restore the log depth counter when an aborted logging cycle returns early (#2072)
The infinite loop guard in Logger::addRecord() incremented the depth counter and then returned before the try/finally that decrements it. Every aborted cycle therefore left the counter raised: after the first one it stayed at 3, the next nested record pushed it to 5, and from then on the logger silently dropped every record for the rest of the process. Long-running workers are hit hardest. Legitimate nesting (e.g. a handler whose synchronous HTTP call runs the shared Guzzle promise queue, which in turn runs callbacks that log) trips the guard once, and the process never logs again until it is restarted. Moving the guard inside the try block makes the early returns run the same finally as every other exit.
1 parent d94b61e commit aa53cd9

2 files changed

Lines changed: 21 additions & 7 deletions

File tree

‎src/Monolog/Logger.php‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -353,15 +353,15 @@ public function addRecord(int|Level $level, string $message, array $context = []
353353
$logDepth = 0;
354354
}
355355

356-
if ($logDepth === 3) {
357-
$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.');
356+
try {
357+
if ($logDepth === 3) {
358+
$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.');
358359

359-
return false;
360-
} elseif ($logDepth >= 5) { // log depth 4 is let through, so we can log the warning above
361-
return false;
362-
}
360+
return false;
361+
} elseif ($logDepth >= 5) { // log depth 4 is let through, so we can log the warning above
362+
return false;
363+
}
363364

364-
try {
365365
$recordInitialized = \count($this->processors) === 0;
366366

367367
$record = new LogRecord(

‎tests/Monolog/LoggerTest.php‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,20 @@ public function testLogCycleDetectionWithFibersWithCycle()
10521052

10531053
self::assertCount(3, $testHandler->getRecords());
10541054
}
1055+
1056+
public function testLogCycleDetectionRecoversAfterAbortedCycle()
1057+
{
1058+
$logger = new Logger(__METHOD__);
1059+
1060+
$logger->pushHandler(new LoggingHandler($logger));
1061+
$logger->pushHandler($testHandler = new TestHandler());
1062+
1063+
// an aborted cycle must not leave the depth counter raised, or the logger goes silent for good
1064+
$logger->info('first');
1065+
$logger->info('second');
1066+
1067+
self::assertCount(6, $testHandler->getRecords());
1068+
}
10551069
}
10561070

10571071
class LoggingHandler implements HandlerInterface

0 commit comments

Comments
 (0)