8000 Make logger implement DebugLoggerInterface · symfony/symfony@438b512 · GitHub
[go: up one dir, main page]

Skip to content

Commit 438b512

Browse files
MatTheCatMathieu
authored and
Mathieu
committed
Make logger implement DebugLoggerInterface
1 parent 1159d13 commit 438b512

File tree

3 files changed

+107
-9
lines changed

3 files changed

+107
-9
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddDebugLogProcessorPass.php

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1515
use Symfony\Component\DependencyInjection\ContainerBuilder;
1616
use Symfony\Component\DependencyInjection\Reference;
17+
use Symfony\Component\HttpKernel\Log\Logger;
1718

1819
class AddDebugLogProcessorPass implements CompilerPassInterface
1920
{
@@ -22,22 +23,43 @@ public function process(ContainerBuilder $container)
2223
if (!$container->hasDefinition('profiler')) {
2324
return;
2425
}
25-
if (!$container->hasDefinition('monolog.logger_prototype')) {
26+
27+
if ($container->hasDefinition('monolog.logger_prototype') && $container->hasDefinition('debug.log_processor')) {
28+
$container->getDefinition('monolog.logger_prototype')
29+
->setConfigurator([__CLASS__, 'configureMonologLogger'])
30+
->addMethodCall('pushProcessor', [new Reference('debug.log_processor')])
31+
;
32+
2633
return;
2734
}
28-
if (!$container->hasDefinition('debug.log_processor')) {
35+
36+
if (!$container->hasDefinition('logger')) {
2937
return;
3038
}
3139

32-
$definition = $container->getDefinition('monolog.logger_prototype');
33-
$definition->setConfigurator([__CLASS__, 'configureLogger']);
34-
$definition->addMethodCall('pushProcessor', [new Reference('debug.log_processor')]);
40+
$loggerDefinition = $container->getDefinition('logger');
41+
42+
if (Logger::class === $loggerDefinition->getClass()) {
43+
$loggerDefinition->setConfigurator([__CLASS__, 'configureHttpKernelLogger']);
44+
}
3545
}
3646

37-
public static function configureLogger(mixed $logger)
47+
public static function configureMonologLogger(mixed $logger)
3848
{
39-
if (\is_object($logger) && method_exists($logger, 'removeDebugLogger') && \in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
49+
if (\is_object($logger) && method_exists($logger, 'removeDebugLogger') && self::shouldDisableDebug()) {
4050
$logger->removeDebugLogger();
4151
}
4252
}
53+
54+
public static function configureHttpKernelLogger(Logger $logger)
55+
{
56+
if (self::shouldDisableDebug()) {
57+
$logger->disableDebug();
58+
}
59+
}
60+
61+
private static function shouldDisableDebug(): bool
62+
{
63+
return \in_array(\PHP_SAPI, ['cli', 'phpdbg'], true);
64+
}
4365
}

src/Symfony/Component/HttpKernel/DependencyInjection/LoggerPass.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
use Psr\Log\LoggerInterface;
1515
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1616
use Symfony\Component\DependencyInjection\ContainerBuilder;
17+
use Symfony\Component\DependencyInjection\Reference;
18+
use Symfony\Component\HttpFoundation\RequestStack;
1719
use Symfony\Component\HttpKernel\Log\Logger;
1820

1921
/**
@@ -33,6 +35,7 @@ public function process(ContainerBuilder $container)
3335
}
3436

3537
$container->register('logger', Logger::class)
38+
->setArguments([null, null, null, new Reference(RequestStack::class)])
3639
->setPublic(false);
3740
}
3841
}

src/Symfony/Component/HttpKernel/Log/Logger.php

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414
use Psr\Log\AbstractLogger;
1515
use Psr\Log\InvalidArgumentException;
1616
use Psr\Log\LogLevel;
17+
use Symfony\Component\HttpFoundation\Request;
18+
use Symfony\Component\HttpFoundation\RequestStack;
1719

1820
/**
1921
* Minimalist PSR-3 logger designed to write in stderr or any other stream.
2022
*
2123
* @author Kévin Dunglas <dunglas@gmail.com>
2224
*/
23-
class Logger extends AbstractLogger
25+
class Logger extends AbstractLogger implements DebugLoggerInterface
2426
{
2527
private const LEVELS = [
2628
LogLevel::DEBUG => 0,
@@ -32,17 +34,30 @@ class Logger extends AbstractLogger
3234
LogLevel::ALERT => 6,
3335
LogLevel::EMERGENCY => 7,
3436
];
37+
private const PRIORITIES = [
38+
LogLevel::DEBUG => 100,
39+
LogLevel::INFO => 200,
40+
LogLevel::NOTICE => 250,
41+
LogLevel::WARNING => 300,
42+
LogLevel::ERROR => 400,
43+
LogLevel::CRITICAL => 500,
44+
LogLevel::ALERT => 550,
45+
LogLevel::EMERGENCY => 600,
46+
];
3547

3648
private int $minLevelIndex;
3749
private \Closure $formatter;
50+
private bool $debug = true;
51+
private array $logs = [];
52+
private array $errorCount = [];
3853

3954
/** @var resource|null */
4055
private $handle;
4156

4257
/**
4358
* @param string|resource|null $output
4459
*/
45-
public function __construct(string $minLevel = null, $output = null, callable $formatter = null)
60+
public function __construct(string $minLevel = null, $output = null, callable $formatter = null, private readonly ?RequestStack $requestStack = null)
4661
{
4762
if (null === $minLevel) {
4863
$minLevel = null === $output || 'php://stdout' === $output || 'php://stderr' === $output ? LogLevel::ERROR : LogLevel::WARNING;
@@ -69,6 +84,11 @@ public function __construct(string $minLevel = null, $output = null, callable $f
6984
}
7085
}
7186

87+
public function disableDebug(): void
88+
{
89+
$this->debug = false;
90+
}
91+
7292
public function log($level, $message, array $context = []): void
7393
{
7494
if (!isset(self::LEVELS[$level])) {
@@ -85,6 +105,34 @@ public function log($level, $message, array $context = []): void
85105
} else {
86106
error_log($formatter($level, $message, $context, false));
87107
}
108+
109+
if ($this->debug && $this->requestStack) {
110+
$this->record($level, $message, $context);
111+
}
112+
}
113+
114+
public function getLogs(Request $request = null): array
115+
{
116+
if ($request) {
117+
return $this->logs[spl_object_hash($request)] ?? [];
118+
}
119+
120+
return array_merge(...array_values($this->logs));
121+
}
122+
123+
public function countErrors(Request $request = null): int
124+
{
125+
if ($request) {
126+
return $this->errorCount[spl_object_hash($request)] ?? 0;
127+
}
128+
129+
return array_sum($this->errorCount);
130+
}
131+
132+
public function clear(): void
133+
{
134+
$this->logs = [];
135+
$this->errorCount = [];
88136
}
89137

90138
private function format(string $level, string $message, array $context, bool $prefixDate = true): string
@@ -113,4 +161,29 @@ private function format(string $level, string $message, array $context, bool $pr
113161

114162
return $log;
115163
}
164+
165+
private function record($level, $message, array $context): void
166+
{
167+
$request = $this->requestStack->getCurrentRequest();
168+
$hash = $request ? spl_object_hash($request) : '';
169+
170+
$this->logs[$hash][] = [
171+
'channel' => null,
172+
'context' => $context,
173+
'message' => $message,
174+
'priority' => self::PRIORITIES[$level],
175+
'priorityName' => $level,
176+
'timestamp' => time(),
177+
'timestamp_rfc3339' => date(\DATE_RFC3339_EXTENDED),
178+
];
179+
180+
$this->errorCount[$hash] ??= 0;
181+
switch ($level) {
182+
case LogLevel::ERROR:
183+
case LogLevel::CRITICAL:
184+
case LogLevel::ALERT:
185+
case LogLevel::EMERGENCY:
186+
++$this->errorCount[$hash];
187+
}
188+
}
116189
}

0 commit comments

Comments
 (0)
0