Configuring Silex (Symfony2) and Monolog to email errors
There's a pretty good documentation page on how to configure Monolog to email errors in Symfony2. This, and all other documentation that I could find on the subject, works great if: (a) you're using the Symfony2 Standard Edition; and (b) you want to send emails with Swift Mailer. However, I couldn't find anything for my use case, in which: (a) I'm using Silex; and (b) I want to send mail with PHP's native mail handler (Swift Mailer is overkill for me).
Turns out that, after a bit of digging and poking around, it's not so hard to cobble together a solution that meets this use case. I'm sharing it here, in case anyone else finds themselves with similar needs in the future.
The code
Assuming that you've installed both Silex and Monolog (by adding silex/silex
and monolog/monolog
to the require
section of your composer.json
file, or by some alternate install method), you'll need something like this for your app's bootstrap code (in my case, it's in my project/app.php
file):
<?php
/**
* @file
* Bootstraps this Silex application.
*/
$loader = require_once __DIR__ . '/../vendor/autoload.php';
$app = new Silex\Application();
function get_app_env() {
$gethostname_result = gethostname();
$gethostname_map = array(
'prodservername' => 'prod',
'stagingservername' => 'staging',
);
$is_hostname_mapped = !empty($gethostname_result) &&
isset($gethostname_map[$gethostname_result]);
return $is_hostname_mapped ? $gethostname_map[$gethostname_result]
: 'dev';
}
$app['env'] = get_app_env();
$app['debug'] = $app['env'] == 'dev';
$app['email.default_to'] = array(
'Dev Dude <dev.dude@nonexistentemailaddress.com>',
'Manager Dude <manager.dude@nonexistentemailaddress.com>',
);
$app['email.default_subject'] = '[My App] Error report';
$app['email.default_from'] =
'My App <my.app@nonexistentemailaddress.com>';
$app->register(new Silex\Provider\MonologServiceProvider(), array(
'monolog.logfile' => __DIR__ . '/../log/' . $app['env'] . '.log',
'monolog.name' => 'myapp',
));
$app['monolog'] = $app->share($app->extend('monolog',
function($monolog, $app) {
if (!$app['debug']) {
$monolog->pushHandler(new Monolog\Handler\NativeMailerHandler(
$app['email.default_to'],
$app['email.default_subject'],
$app['email.default_from'],
Monolog\Logger::CRITICAL
));
}
return $monolog;
}));
return $app;
I've got some code here for determining the current environment (which can be prod
, staging
or dev
), and for only enabling the error emailing functionality for environments other than dev
. Up to you whether you want / need that functionality; plus, this example is just one of many possible ways to implement it.
I followed the Silex docs for customising Monolog by adding extra handlers, which is actually very easy to use, although it's lacking any documented examples.
That's about it, really. Using this code, you can have a Silex app which logs errors to a file (the usual) when running in your dev environment, but that also sends an error email to one or more addresses, when running in your other environments. Not rocket science – but, in my opinion, it's an important setup to be able to achieve in pretty much any web framework (i.e. regardless of your technology stack, receiving email notification of critical errors is a recommended best practice); and it doesn't seem to be documented anywhere so far for Silex.