.. index:: single: Logging; Emailing errors How to Configure Monolog to Email Errors ======================================== .. caution:: This feature is not compatible yet with the new :doc:`Symfony mailer `, so it requires using SwiftMailer. `Monolog`_ can be configured to send an email when an error occurs within an application. The configuration for this requires a few nested handlers in order to avoid receiving too many emails. This configuration looks complicated at first but each handler is fairly straightforward when it is broken down. .. configuration-block:: .. code-block:: yaml # config/packages/prod/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 .. code-block:: xml error@example.com .. code-block:: php // config/packages/prod/monolog.php $container->loadFromExtension('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 a 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', ], ], ]); The ``main`` handler is a ``fingers_crossed`` handler which means that it is only triggered when the action level, in this case ``critical`` is reached. The ``critical`` level is only triggered for 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. .. tip:: If you want both 400 level and 500 level errors to trigger an email, set the ``action_level`` to ``error`` instead of ``critical``. See the code above for an example. The ``deduplicated`` handler keeps all the messages for a request and then passes them onto the nested handler in one go, but only if the records are unique over a given period of time (60 seconds by default). If the records are duplicates they are discarded. Adding this handler reduces the amount of notifications to a manageable level, specially in critical failure scenarios. You can adjust the time period using the ``time`` option: .. configuration-block:: .. code-block:: yaml # config/packages/prod/monolog.yaml monolog: handlers: # ... deduplicated: type: deduplication # the time in seconds during which duplicate entries are discarded (default: 60) time: 10 handler: swift .. code-block:: xml .. code-block:: php // config/packages/prod/monolog.php $container->loadFromExtension('monolog', [ 'handlers' => [ // ... 'deduplicated' => [ 'type' => 'deduplication', // the time in seconds during which duplicate entries are discarded (default: 60) 'time' => 10, 'handler' => 'swift', ], ], ]); 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. You can combine these handlers with other handlers so that the errors still get logged on the server as well as the emails being sent: .. configuration-block:: .. code-block:: yaml # config/packages/prod/monolog.yaml 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: 'error@example.com' to_email: 'error@example.com' subject: 'An Error Occurred! %%message%%' level: debug formatter: monolog.formatter.html content_type: text/html .. code-block:: xml error@example.com .. code-block:: php // config/packages/prod/monolog.php $container->loadFromExtension('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' => 'error@example.com', 'to_email' => 'error@example.com', // or a 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', ], ], ]); This uses the ``group`` handler to send the messages to the two group members, the ``deduplicated`` and the ``stream`` handlers. The messages will now be both written to the log file and emailed. .. _Monolog: https://github.com/Seldaek/monolog