Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[HttpKernel] Outdated DebugLoggerInterface::getLogs PHPDoc #47396

Closed
@MatTheCat

Description

@MatTheCat

Symfony version(s) affected

5.4, 6

Description

While trying to implement a DebugLoggerInterface around HttpKernel’s Logger I read the following:

* A log is an array with the following mandatory keys:
* timestamp, message, priority, and priorityName.
* It can also have an optional context key containing an array.

But it seems that since #42195 the LoggerDataCollector will expect the keys

  • channel
  • context
  • message
  • priority
  • priorityName
  • timestamp_rfc3339

So

  • timestamp is not needed
  • context is not optional
  • timestamp_rfc3339and channel are mandatory

It seems to me DebugLoggerInterface is almost exclusively used by the LoggerDataCollector so I guess the keys should match.

How to reproduce

Decorate HttpKernel’s logger to implement DebugLoggerInterface:

<?php

namespace App\Log;

use Psr\Log\LoggerInterface;
use Psr\Log\LoggerTrait;
use Psr\Log\LogLevel;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;

#[AsDecorator('logger')]
class DebugLogger implements LoggerInterface, DebugLoggerInterface
{
    use LoggerTrait;
    
    private array $logsByRequest = [];
    
    public function __construct(
        private readonly LoggerInterface $logger,
        private readonly RequestStack $requestStack,
    ) {}

    public function log($level, $message, array $context = []): void
    {
        $this->logger->log($level, $message, $context);
        
        $request = $this->requestStack->getCurrentRequest();

        $this->logsByRequest[$request ? spl_object_hash($request) : ''][] = [
            'context' => $context,
            'message' => $message,
            'priority' => [
                LogLevel::DEBUG => 0,
                LogLevel::INFO => 1,
                LogLevel::NOTICE => 2,
                LogLevel::WARNING => 3,
                LogLevel::ERROR => 4,
                LogLevel::CRITICAL => 5,
                LogLevel::ALERT => 6,
                LogLevel::EMERGENCY => 7,
            ][$level],
            'priorityName' => $level,
            'timestamp' => time(),
        ];
    }

    public function getLogs(Request $request = null): array
    {
        if ($request) {
            return $this->logsByRequest[spl_object_hash($request)] ?? [];
        }
        
        return array_merge(...array_values($this->logsByRequest));
    }

    public function countErrors(Request $request = null): int
    {
        $errorCount = 0;
        foreach ($this->getLogs($request) as $log) {
            if ($log['priority'] >= 4) {
                ++$errorCount;
            }
        }
        return $errorCount;
    }

    public function clear()
    {
        $this->logsByRequest = [];
    }
}

then access the profiler’s logger panel. It will crash.

Possible Solution

Update mandatory keys to be used by the LoggerDataCollector.

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions