How to report exceptions via email automatically in Symfony 3.4 using MonologBundle

How to report exceptions via email automatically in Symfony 3.4 using MonologBundle

Monolog is the de facto standard logging library for PHP and comes out of the box in the most popular PHP frameworks, such as Laravel and Symfony. It implements PSR-3 - a common interface for logging libraries defined by PHP-Fig. Type-hinting Psr\Log\LoggerInterface in your application enables interoperability, allowing you change the logging library for another that implements PSR-3 without too much headache. This library is already included in Symfony 3 by default, so you will be able to intercept exceptions in production and send an email with the details about the failure.

In this article we'll show you how to configure monolog to send emails about critical errors automatically using Swift Mailer.

Requirements

You will need to have installed the following packages in your Symfony application (they're normally already installed, however check that they're installed in your composer.json):

  • Swift Mailer (symfony/swiftmailer-bundle).
  • Monolog (symfony/monolog-bundle).

After checking that the previous tools are installed on your app, proceed with the configuration of the automatic error reporting via email.

1. Configure App Mailer (Swift Mailer)

In order to send the error email, Monolog will need the default mailer configured with Swiftmailer in your application. This can be easily done in your config.yml and providing the email credentials, the transport mode, encryption etc (more information about swiftmailer configuration here):

# app/config/config.yml

# Swiftmailer Configuration
# Note: the setup may change according to your email provider
# for example, with zoho, the configuration for the mailer would
# be something like this.
swiftmailer:
    transport: smtp
    host:      smtp.zoho.com
    username:  mail@myexamplemail.com
    password:  password123
    port: 465
    encryption: ssl
    spool:     { type: memory }

As mentioned, be sure that the mailer works previously because Monolog won't throw any exception if the mailer isn't configured correctly.

2. Configure Monolog Email Report

For sanity reasons, you want the email report automatically activated only in production environment, so you need to enable monolog in the config_prod.yml file. You will need as well, to send the exception via email and write it to the logs, so you need to be careful with the configuration of Monolog in production:

# app/config/config_prod.yml
imports:
    - { resource: config.yml }

monolog:
    handlers:
        main:
            type:         fingers_crossed
            action_level: critical
            handler:      grouped
        grouped:
            type:    group
            members: [streamed, deduplicated]
        streamed:
            type:  stream
            path:  '%kernel.logs_dir%/%kernel.environment%.log'
            level: debug
        deduplicated:
            type:    deduplication
            handler: swift
        swift:
            type:       swift_mailer
            from_email: 'from_email@test.com'
            # Or multiple receivers:
            # to_email:   ['to_email1@ourcodeworld.com', 'to_email2@ourcodeworld.com']
            to_email:   'to_email@ourcodeworld.com'
            subject:    'An Error Occurred! %%message%%'
            level:      debug
            formatter:  monolog.formatter.html
            content_type: text/html

The mail handler is a fingers_crossed handler which means that it is only triggered when the action level, in this case critical is reached (5xx HTTP code errors). If this level is reached once, the fingers_crossed handler will log all messages regardless of their level. The handler setting means that the output is then passed onto the deduplicated handler.

The messages are then passed to the swift handler. This is the handler that actually deals with emailing you the error. The settings for this are straightforward, the to and from addresses, the formatter, the content type and the subject. The previous snippet is the best configuration to get the errors still logged on the server and emailed as well.

3. Causing intentional exception to test in production

After registering the email report of monolog, you need to test if it works. You can test in your local environment accessing your app from the production environment, however don't forget to clear the cache of the project previously using:

php bin/console cache:clear

In our example, we'll trigger a simple exception from a controller in the index action:

<?php

namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class PagesController extends Controller
{
    public function indexAction()
    {
        // Test non-existent class
        throw new Exception("That's too bad !");
    }
}

After accesing the index action in your browser, monolog will send the email in the background and will display a 500 error in the browser. Now if you check your mail, you will see the exception message, the class and the file where the exception was triggered, the line etc:

Email Error Report Symfony 3.4 MonologBundle

Now you will be able to debug and fix those errors without asking to the user what he did to replicate the issue.

Happy coding !

Become a more social person