Search code examples
phpsymfonyexceptionloggingsymfony4

How to send logs to email on exception or error in Symfony?


My requirements: Whenever an error occurs in application send that error logs to email.

I am trying to send any exception/error logs to email which occurs in our app. Here is what I tried but I am not receiving logs in email.

Note: Email sending functionality is working fine because I have tested it in a test controller. But it's not working with this Listener.

What happens when I hit TestController Index Route?

When I vist index route it throws 500 internal server error ( because we intentionality thrown an exception ). However if this exception occurs it should send the logs to email. Because in the ExceptionListener I have coded the email sending of logs. But it is not sending logs (:

ExceptionListener.php:

<?php

namespace App\EventListener;

use App\Service\EmailService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;

class ExceptionListener
{
    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    public function onKernelException(EmailService $emailService, ExceptionEvent $event)
    {
        // You get the exception object from the received event
        $exception = $event->getThrowable();
        $message = sprintf(
            'My Error says: %s with code: %s',
            $exception->getMessage(),
            $exception->getCode()
        );

        try {
            $emailService->sendLogToMail("[email protected]", $message);
        } catch (TransportExceptionInterface $e) {
            //
        }

    }
}

I have registered the Listener in services.yaml:

App\EventListener\ExceptionListener:
        tags:
            - { name: kernel.event_listener, event: kernel.exception }

TestController where I intentionality generate an exception:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Exception;

class TestController extends AbstractController
{

    public function index() {

      throw new Exception("It's bad");

    }

}

I am using Symfony v4.4


Solution

  • Edit2: Add the email service in the constructor and stick to the standard definition of onKernelException

    There is a very good article in the symfony documentation to talk about this. documentation

    If you are using Monolog and SwiftMailer, this is done in a matter of minutes. I think everything is super well explained, but let us know if you are facing difficulties.

    EDIT: I actually noticed you do not use Monolog. I would recommend using it so you also have a log file with the error. Once done, whenever you fire $this->logger->error('My error'); An email will be sent with the error and the stack trace. This is very convenient in the early days of production.