8000 [HttpKernel] Make Logger implement DebugLoggerInterface by MatTheCat · Pull Request #47483 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[HttpKernel] Make Logger 8000 implement DebugLoggerInterface #47483

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function __construct(RequestStack $requestStack = null)

private function doInvoke(array|LogRecord $record): array|LogRecord
{
$hash = $this->requestStack && ($request = $this->requestStack->getCurrentRequest()) ? spl_object_hash($request) : '';
$key = $this->requestStack && ($request = $this->requestStack->getCurrentRequest()) ? spl_object_id($request) : '';

$timestamp = $timestampRfc3339 = false;
if ($record['datetime'] instanceof \DateTimeInterface) {
Expand All @@ -43,7 +43,7 @@ private function doInvoke(array|LogRecord $record): array|LogRecord
$timestampRfc3339 = (new \DateTimeImmutable($record['datetime']))->format(\DateTimeInterface::RFC3339_EXTENDED);
}

$this->records[$hash][] = [
$this->records[$key][] = [
'timestamp' => $timestamp,
'timestamp_rfc3339' => $timestampRfc3339,
'message' => $record['message'],
Expand All @@ -53,16 +53,16 @@ private function doInvoke(array|LogRecord $record): array|LogRecord
'channel' => $record['channel'] ?? '',
];

if (!isset($this->errorCount[$hash])) {
$this->errorCount[$hash] = 0;
if (!isset($this->errorCount[$key])) {
$this->errorCount[$key] = 0;
}

switch ($record['level']) {
case Logger::ERROR:
case Logger::CRITICAL:
case Logger::ALERT:
case Logger::EMERGENCY:
++$this->errorCount[$hash];
++$this->errorCount[$key];
}

return $record;
Expand All @@ -71,7 +71,7 @@ private function doInvoke(array|LogRecord $record): array|LogRecord
public function getLogs(Request $request = null): array
{
if (null !== $request) {
return $this->records[spl_object_hash($request)] ?? [];
return $this->records[spl_object_id($request)] ?? [];
}

if (0 === \count($this->records)) {
Expand All @@ -84,7 +84,7 @@ public function getLogs(Request $request = null): array
public function countErrors(Request $request = null): int
{
if (null !== $request) {
return $this->errorCount[spl_object_hash($request)] ?? 0;
return $this->errorCount[spl_object_id($request)] ?? 0;
}

return array_sum($this->errorCount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\Log\Logger;

class AddDebugLogProcessorPass implements CompilerPassInterface
{
Expand All @@ -22,22 +23,38 @@ public function process(ContainerBuilder $container)
if (!$container->hasDefinition('profiler')) {
return;
}
if (!$container->hasDefinition('monolog.logger_prototype')) {

if ($container->hasDefinition('monolog.logger_prototype') && $container->hasDefinition('debug.log_processor')) {
$container->getDefinition('monolog.logger_prototype')
->setConfigurator([__CLASS__, 'configureMonologLogger'])
->addMethodCall('pushProcessor', [new Reference('debug.log_processor')])
;

return;
}
if (!$container->hasDefinition('debug.log_processor')) {

if (!$container->hasDefinition('logger')) {
return;
}

$definition = $container->getDefinition('monolog.logger_prototype');
$definition->setConfigurator([__CLASS__, 'configureLogger']);
$definition->addMethodCall('pushProcessor', [new Reference('debug.log_processor')]);
$loggerDefinition = $container->getDefinition('logger');

if (Logger::class === $loggerDefinition->getClass()) {
$loggerDefinition->setConfigurator([__CLASS__, 'configureHttpKernelLogger']);
}
}

public static function configureLogger(mixed $logger)
public static function configureMonologLogger(mixed $logger)
{
if (\is_object($logger) && method_exists($logger, 'removeDebugLogger') && \in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && \is_object($logger) && method_exists($logger, 'removeDebugLogger')) {
$logger->removeDebugLogger();
}
}

public static function configureHttpKernelLogger(Logger $logger)
{
if (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && method_exists($logger, 'enableDebug')) {
$logger->enableDebug();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Log\Logger;

/**
Expand All @@ -33,6 +35,7 @@ public function process(ContainerBuilder $container)
}

$container->register('logger', Logger::class)
->setArguments([null, null, null, new Reference(RequestStack::class)])
->setPublic(false);
}
}
77 changes: 75 additions & 2 deletions src/Symfony/Component/HttpKernel/Log/Logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
use Psr\Log\AbstractLogger;
use Psr\Log\InvalidArgumentException;
use Psr\Log\LogLevel;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;

/**
* Minimalist PSR-3 logger designed to write in stderr or any other stream.
*
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class Logger extends AbstractLogger
class Logger extends AbstractLogger implements DebugLoggerInterface
{
private const LEVELS = [
LogLevel::DEBUG => 0,
Expand All @@ -32,17 +34,30 @@ class Logger extends AbstractLogger
LogLevel::ALERT => 6,
LogLevel::EMERGENCY => 7,
];
private const PRIORITIES = [
LogLevel::DEBUG => 100,
LogLevel::INFO => 200,
LogLevel::NOTICE => 250,
LogLevel::WARNING => 300,
LogLevel::ERROR => 400,
LogLevel::CRITICAL => 500,
LogLevel::ALERT => 550,
LogLevel::EMERGENCY => 600,
];

private int $minLevelIndex;
private \Closure $formatter;
private bool $debug = false;
private array $logs = [];
private array $errorCount = [];

/** @var resource|null */
private $handle;

/**
* @param string|resource|null $output
*/
public function __construct(string $minLevel = null, $output = null, callable $formatter = null)
public function __construct(string $minLevel = null, $output = null, callable $formatter = null, private readonly ?RequestStack $requestStack = null)
{
if (null === $minLevel) {
$minLevel = null === $output || 'php://stdout' === $output || 'php://stderr' === $output ? LogLevel::ERROR : LogLevel::WARNING;
Expand All @@ -69,6 +84,11 @@ public function __construct(string $minLevel = null, $output = null, callable $f
}
}

public function enableDebug(): void
{
$this->debug = true;
}

public function log($level, $message, array $context = []): void
{
if (!isset(self::LEVELS[$level])) {
Expand All @@ -85,6 +105,34 @@ public function log($level, $message, array $context = []): void
} else {
error_log($formatter($level, $message, $context, false));
}

if ($this->debug && $this->requestStack) {
$this->record($level, $message, $context);
}
}

public function getLogs(Request $request = null): array
{
if ($request) {
return $this->logs[spl_object_id($request)] ?? [];
}

return array_merge(...array_values($this->logs));
}

public function countErrors(Request $request = null): int
{
if ($request) {
return $this->errorCount[spl_object_id($request)] ?? 0;
}

return array_sum($this->errorCount);
}

public function clear(): void
{
$this->logs = [];
$this->errorCount = [];
}

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

return $log;
}

private function record($level, $message, array $context): void
{
$request = $this->requestStack->getCurrentRequest();
$key = $request ? spl_object_id($request) : '';

$this->logs[$key][] = [
'channel' => null,
'context' => $context,
'message' => $message,
'priority' => self::PRIORITIES[$level],
'priorityName' => $level,
'timestamp' => time(),
'timestamp_rfc3339' => date(\DATE_RFC3339_EXTENDED),
];

$this->errorCount[$key] ??= 0;
switch ($level) {
case LogLevel::ERROR:
case LogLevel::CRITICAL:
case LogLevel::ALERT:
case LogLevel::EMERGENCY:
++$this->errorCount[$key];
}
}
}
0