Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Configure Symfony Monolog to send error emails when exceptions are thrown in console commands
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: grouped
grouped:
type: group
members: [streamed, console, buffered]
streamed:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console
buffered:
type: buffer
handler: swift
swift:
type: swift_mailer
from_email: info@example.com
to_email: error@example.com
subject: An Error Occurred!
level: debug
swiftmailer:
#port: 587
#encryption: tls
delivery_address: 'dev@example.com'
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="console.exception_listener" class="Acme\Foo\Infrastructure\Symfony\AppBundle\Listener\ConsoleExceptionListener" public="true">
<argument type="service" id="logger" on-invalid="null" />
<tag name="kernel.event_subscriber" />
<tag name="monolog.logger" channel="console" />
</service>
</services>
</container>
<?php
namespace Acme\Foo\Infrastructure\Symfony\AppBundle\Listener;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Event\ConsoleEvent;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* @author James Halsall <james.t.halsall@googlemail.com>
* @author Robin Chalas <robin.chalas@gmail.com>
*/
class ConsoleExceptionListener implements EventSubscriberInterface
{
private $logger;
public function __construct(LoggerInterface $logger = null)
{
$this->logger = $logger;
}
public function onConsoleException(ConsoleExceptionEvent $event)
{
if (null === $this->logger) {
return;
}
$exception = $event->getException();
$this->logger->error('Exception thrown while running command "{command}". Message: "{message}"', array('exception' => $exception, 'command' => $this->getInputString($event), 'message' => $exception->getMessage()));
}
public function onConsoleTerminate(ConsoleTerminateEvent $event)
{
if (null === $this->logger) {
return;
}
$exitCode = $event->getExitCode();
if (0 === $exitCode) {
return;
}
$this->logger->error('Command "{command}" exited with code "{code}"', array('command' => $this->getInputString($event), 'code' => $exitCode));
}
public static function getSubscribedEvents()
{
return array(
ConsoleEvents::EXCEPTION => array('onConsoleException', -128),
ConsoleEvents::TERMINATE => array('onConsoleTerminate', -128),
);
}
private static function getInputString(ConsoleEvent $event)
{
$commandName = $event->getCommand()->getName();
$input = $event->getInput();
if (method_exists($input, '__toString')) {
return str_replace(array("'$commandName'", "\"$commandName\""), $commandName, (string) $input);
}
return $commandName;
}
}
@webdevilopers
Copy link
Author

webdevilopers commented Dec 11, 2017

The dev.log logs the following when I cause an exception via console:

[2017-12-11 10:24:13] event.DEBUG: Notified event "console.command" to listener "Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::configure". [] []
[2017-12-11 10:24:13] event.DEBUG: Notified event "console.command" to listener "Symfony\Component\HttpKernel\EventListener\DumpListener::configure". [] []
[2017-12-11 10:24:13] event.DEBUG: Notified event "console.command" to listener "Symfony\Bridge\Monolog\Handler\ConsoleHandler::onCommand". [] []
[2017-12-11 10:24:13] event.DEBUG: Notified event "console.exception" to listener "Symfony\Bundle\SwiftmailerBundle\EventListener\EmailSenderListener::onException". [] []
[2017-12-11 10:24:13] event.DEBUG: Notified event "console.terminate" to listener "Symfony\Bridge\Monolog\Handler\SwiftMailerHandler::onCliTerminate". [] []
[2017-12-11 10:24:13] event.DEBUG: Notified event "console.terminate" to listener "Symfony\Bundle\SwiftmailerBundle\EventListener\EmailSenderListener::onTerminate". [] []
[2017-12-11 10:24:13] event.DEBUG: Notified event "console.terminate" to listener "Symfony\Bridge\Monolog\Handler\ConsoleHandler::onTerminate". [] []

@webdevilopers
Copy link
Author

webdevilopers commented Dec 11, 2017

Any exception caused via UI is now logged to file and emailed. But not if the exception is thrown when executing a console command.

@webdevilopers
Copy link
Author

webdevilopers commented Dec 11, 2017

@webdevilopers
Copy link
Author

webdevilopers commented Dec 11, 2017

See added code for integrating the following patch into @symfony 2.8:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment