<?php
namespace App\EventSubscriber;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleErrorEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use App\Utils\Logging\Logger\CustomJsonFormatter as Formatter;
class LoggerSubscriber implements EventSubscriberInterface
{
public const SHORT_MESSAGE_CORE_API_RESPONSE = 'CORE API RESPONSE';
public const SHORT_MESSAGE_CORE_API_REQUEST = 'CORE API INPUT';
public const SHORT_MESSAGE_CORE_API_ERROR = 'CORE API ERROR';
public const DIRECTION_CORE_O = 'CORE-O';
public const DIRECTION_CORE_I = 'CORE-I';
private $logger;
private $isExitWithError;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
$this->isExitWithError = false;
}
public function onConsoleError(ConsoleErrorEvent $event): void
{
if (!$event->getError()) {
return;
}
$command = $event->getCommand();
$this->isExitWithError = true;
$this->logger->error(sprintf('Command: %s execution error: %s', $command ? $command->getName() : 'null', $event->getError()->getMessage()), [
Formatter::MSG_SUBJECT => $event->getError(),
Formatter::TYPE => Formatter::TYPE_COMMAND,
]);
}
public function onConsoleTerminate(ConsoleTerminateEvent $event): void
{
if ($this->isExitWithError) {
return;
}
$command = $event->getCommand();
$this->logger->info('Command end: ' . ($command ? $command->getName() : 'null'), [
Formatter::MSG_SUBJECT => ['EXIT_CODE' => $event->getExitCode()],
Formatter::TYPE => Formatter::TYPE_COMMAND,
]);
}
public function onCommand(ConsoleCommandEvent $event): void
{
$command = $event->getCommand();
$this->logger->info('Command start: ' . ($command ? $command->getName() : 'null'), [
Formatter::MSG_SUBJECT => $event->getInput()->getArguments(),
Formatter::TYPE => Formatter::TYPE_COMMAND,
]);
}
public function onKernelRequest(RequestEvent $event): void
{
if ($this->isExitWithError) {
return;
}
$this->logger->info(self::SHORT_MESSAGE_CORE_API_REQUEST, [
Formatter::MSG_SUBJECT => $event->getRequest(),
Formatter::MSG_DIRECTION => self::DIRECTION_CORE_I,
Formatter::TYPE => Formatter::TYPE_REQUEST,
]);
}
public function onKernelResponse(ResponseEvent $event): void
{
if ($this->isExitWithError) {
return;
}
if ($event->getResponse() instanceof JsonResponse) {
$this->logger->info(self::SHORT_MESSAGE_CORE_API_RESPONSE, [
Formatter::MSG_SUBJECT => json_decode($event->getResponse()->getContent() ?? '', true),
Formatter::MSG_STATUS_CODE => $event->getResponse()->getStatusCode(),
Formatter::MSG_DIRECTION => self::DIRECTION_CORE_O,
Formatter::TYPE => Formatter::TYPE_RESPONSE,
]);
return;
}
$this->logger->info(self::SHORT_MESSAGE_CORE_API_RESPONSE, [
Formatter::MSG_SUBJECT => $event->getResponse()->getContent(),
Formatter::MSG_STATUS_CODE => $event->getResponse()->getStatusCode(),
Formatter::MSG_DIRECTION => self::DIRECTION_CORE_O,
Formatter::TYPE => Formatter::TYPE_RESPONSE,
]);
}
public function onKernelException(ExceptionEvent $event): void
{
$this->isExitWithError = true;
$this->logger->error(self::SHORT_MESSAGE_CORE_API_ERROR, [
Formatter::MSG_SUBJECT => $event->getThrowable(),
Formatter::TYPE => Formatter::TYPE_RESPONSE,
]);
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => ['onKernelRequest', 7],
KernelEvents::RESPONSE => ['onKernelResponse', 1],
KernelEvents::EXCEPTION => 'onKernelException',
ConsoleEvents::ERROR => 'onConsoleError',
ConsoleEvents::TERMINATE => 'onConsoleTerminate',
ConsoleEvents::COMMAND => 'onCommand',
];
}
}