Я создаю микросервис в Symfony, где мне нужно использовать RabbitMQ, чтобы использовать сообщения для создания документа. Потребитель работает, но всякий раз, когда выдается исключение, я хочу записать исключение в формате и в отдельном файле журнала.
Я использую Symfony 4.2, и все выданные исключения регистрируются в dev.log. Я создал новый канал в Monolog и вызвал исключение, чтобы я мог управлять своими регистрациями.
Для этого я использую ExceptionListener и следовал инструкциям из документов Symfony.
У меня есть настройки потребителя следующим образом
public function execute(AMQPMessage $msg): int
{
try {
return $this->documentService->createDocument($this->serializer->deserialize($msg->body, 'array', 'json'));
} catch (\Exception $e) {
$this->logger->error($e);
return ConsumerInterface::MSG_REJECT;
}
}
А внутри сервиса у меня есть следующее:
try {
...
$template = $this->templateRepository->findOneByName($messageData['template']);
if ($template === null) throw new \Exception('Template does not exist');
...
return ConsumerInterface::MSG_ACK;
} catch (\Exception $e) {
$this->logger->error($e);
return ConsumerInterface::MSG_REJECT;
}
Я регистрируюсь в обоих классах, но когда выдается исключение, я получаю исключение в консоли, но слушатель не перехватывает событие ExceptionEvent.
Я пробовал разные события, и я добавил пакет http-kernel в Symfony, так как я использую Symfony Flex, у меня не все пакеты.
Я зарегистрировал своего слушателя в services.yaml следующим образом:
App\EventListener\DocumentExceptionListener:
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
arguments:
$logger: '@monolog.logger.exception' # Log all exceptions to a separate log file
А мой ExceptionListener выглядит следующим образом:
public function __construct(LoggerInterface $logger, SerializerInterface $serializer)
{
$this->logger = $logger;
$this->serializer = $serializer;
$this->logger->info('Starting to listen...');
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
$this->logger->info('currently listening...');
$this->log($event->getException());
}
private function log(\Exception $exception)
{
$log = [
'code' => $exception->getCode(),
'message' => $exception->getMessage(),
'called' => [
'file' => $exception->getTrace()[0]['file'],
'line' => $exception->getTrace()[0]['line'],
],
'occurred' => [
'file' => $exception->getFile(),
'line' => $exception->getLine(),
],
];
if ($exception->getPrevious() instanceof Exception) {
$log += [
'previous' => [
'message' => $exception->getPrevious()->getMessage(),
'exception' => get_class($exception->getPrevious()),
'file' => $exception->getPrevious()->getFile(),
'line' => $exception->getPrevious()->getLine(),
],
];
}
$this->logger->error($this->serializer->serialize($log, 'json'));
}
Мой вывод сейчас:
exception.INFO: Starting to listen... [] []