Symfony 5 | Receive server errors by email with monolog, swiftmailer and maildev

Prerequisites of the tutorial :

Install monologhttps://packagist.org/packages/symfony/monolog-bundle (Allows to receive server errors by mail)

Install maildev https://github.com/maildev/maildev (Allows to create a local SMTP server)

Install swiftmailer https://packagist.org/packages/symfony/swiftmailer-bundle (Allows to send mails under Symfony)

Configure Monolog :

Go to the file monolog.yaml in the folder config/packages/dev (or prod for the prod..)

And define the options as in the box below to receive critical errors (so 5XX) but it is also possible to configure 4XX errors : See more options

In the “swift” part we define who sends the mail, who will receive the mail, and the subject of the email.

# config/packages/dev/monolog.yaml
monolog:
  handlers:
    main:
      type: fingers_crossed
      # 500 errors are logged at the critical level
      action_level: critical
      # to also log 400 level errors (but not 404's):
      # action_level: error
      # excluded_404s:
      #     - ^/
      handler: deduplicated
    deduplicated:
      type: deduplication
      handler: swift
    swift:
      type: swift_mailer
      from_email: 'error@example.com'
      to_email: 'error@example.com'
      # or list of recipients
      # to_email:   ['dev1@example.com', 'dev2@example.com', ...]                                      
      subject: 'An Error Occurred! %%message%%'
      level: debug
      formatter: monolog.formatter.html
      content_type: text/html

Configure swiftmailer :

In the swiftmailer.yaml file in the config/packages folder, you can see that the SMTP url is ‘%env(MAILER_URL)%’ that means that the variable which contains the url is in the .env file of the project, so you have to go and modify it directly there.

swiftmailer:
    url: '%env(MAILER_URL)%'
    spool: { type: 'memory' }

Go to the .env file and modify the MAILER_URL like this:

MAILER_URL=smtp://localhost:1025

To receive mails locally on the maildev interface, otherwise put the information of your SMTP Learn more.

Launch maildev to receive mail locally:
Go to a command prompt and run the command “maildev“:

MailDev webapp running at http://0.0.0.0:1080
MailDev SMTP Server running at 0.0.0.0:1025

You will see these two lines to indicate the launch of the local smtp, the mails are sent on localhost:1025 and the interface is on port 1080.

Simulate an error in Symfony :

We will now try to send an error mail to our SMTP server.

In my case I created a simple error in my controller.

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class AppController extends AbstractController
{
    /**
     * @Route("/app", name="app")
     */
    public function app(): Response
    {
        $var = "";
        //The error is here
        dump($var->getError());
        return $this->json('error !');
    }
}

The error is simple, getError doesn’t exist which will cause a 5xx error, then monolog will intercept this error, and since we have defined that we want all 5xx errors by mail, it will send it via our swiftmailer configured to send the mails on our local SMTP via maildev

When we access our route we get this error 500, which is sent back to our maildev interface

Here is the maildev interface with our error mail, and if you scroll down you can find the critical error that blocked your serve:

You can now receive server errors from your Symfony server via email to solve them faster in production.

This tutorial is now over, thanks for reading.