From 76d2c91777002a26bf7e8a456278deee9d8a7e5b Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Mon, 16 Jan 2017 10:07:58 +0100 Subject: [PATCH] Update the doc for automatic console logging --- console/logging.rst | 262 +------------------------------------------- 1 file changed, 5 insertions(+), 257 deletions(-) diff --git a/console/logging.rst b/console/logging.rst index 3dadf0479ca..305c2be804b 100644 --- a/console/logging.rst +++ b/console/logging.rst @@ -4,261 +4,9 @@ How to Enable Logging in Console Commands ========================================= -The Console component doesn't provide any logging capabilities out of the box. -Normally, you run console commands manually and observe the output, which is -why logging is not provided. However, there are cases when you might need -logging. For example, if you are running console commands unattended, such -as from cron jobs or deployment scripts, it may be easier to use Symfony's -logging capabilities instead of configuring other tools to gather console -output and process it. This can be especially handful if you already have -some existing setup for aggregating and analyzing Symfony logs. +In Symfony versions prior to 3.3, the Console component didn't provide any +logging capabilities out of the box and you had to implement your own exception +lister for the console. -There are basically two logging cases you would need: - -* Manually logging some information from your command; -* Logging uncaught exceptions. - -Manually Logging from a Console Command ---------------------------------------- - -This one is really simple. When you create a console command within the full-stack -framework as described in ":doc:`/console`", your command extends -:class:`Symfony\\Bundle\\FrameworkBundle\\Command\\ContainerAwareCommand`. -This means that you can simply access the standard logger service through the -container and use it to do the logging:: - - // src/AppBundle/Command/GreetCommand.php - namespace AppBundle\Command; - - use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; - use Symfony\Component\Console\Input\InputArgument; - use Symfony\Component\Console\Input\InputInterface; - use Symfony\Component\Console\Input\InputOption; - use Symfony\Component\Console\Output\OutputInterface; - use Psr\Log\LoggerInterface; - - class GreetCommand extends ContainerAwareCommand - { - // ... - - protected function execute(InputInterface $input, OutputInterface $output) - { - /** @var $logger LoggerInterface */ - $logger = $this->getContainer()->get('logger'); - - $name = $input->getArgument('name'); - if ($name) { - $text = 'Hello '.$name; - } else { - $text = 'Hello'; - } - - if ($input->getOption('yell')) { - $text = strtoupper($text); - $logger->warning('Yelled: '.$text); - } else { - $logger->info('Greeted: '.$text); - } - - $output->writeln($text); - } - } - -Depending on the environment in which you run your command (and your logging -setup), you should see the logged entries in ``var/logs/dev.log`` or ``var/logs/prod.log``. - -Enabling automatic Exceptions Logging -------------------------------------- - -To get your console application to automatically log uncaught exceptions for -all of your commands, you can use :doc:`console events`. - -First configure a listener for console exception events in the service container: - -.. configuration-block:: - - .. code-block:: yaml - - # app/config/services.yml - services: - app.listener.command_exception: - class: AppBundle\EventListener\ConsoleExceptionListener - arguments: ['@logger'] - tags: - - { name: kernel.event_listener, event: console.exception } - - .. code-block:: xml - - - - - - - - - - - - - - .. code-block:: php - - // app/config/services.php - use AppBundle\EventListener\ConsoleExceptionListener; - use Symfony\Component\DependencyInjection\Definition; - use Symfony\Component\DependencyInjection\Reference; - - $definitionConsoleExceptionListener = new Definition( - ConsoleExceptionListener::class, - array(new Reference('logger')) - ); - $definitionConsoleExceptionListener->addTag( - 'kernel.event_listener', - array('event' => 'console.exception') - ); - $container->setDefinition( - 'app.listener.command_exception', - $definitionConsoleExceptionListener - ); - -Then implement the actual listener:: - - // src/AppBundle/EventListener/ConsoleExceptionListener.php - namespace AppBundle\EventListener; - - use Symfony\Component\Console\Event\ConsoleExceptionEvent; - use Psr\Log\LoggerInterface; - - class ConsoleExceptionListener - { - private $logger; - - public function __construct(LoggerInterface $logger) - { - $this->logger = $logger; - } - - public function onConsoleException(ConsoleExceptionEvent $event) - { - $command = $event->getCommand(); - $exception = $event->getException(); - - $message = sprintf( - '%s: %s (uncaught exception) at %s line %s while running console command `%s`', - get_class($exception), - $exception->getMessage(), - $exception->getFile(), - $exception->getLine(), - $command->getName() - ); - - $this->logger->error($message, array('exception' => $exception)); - } - } - -In the code above, when any command throws an exception, the listener will -receive an event. You can simply log it by passing the logger service via the -service configuration. Your method receives a -:class:`Symfony\\Component\\Console\\Event\\ConsoleExceptionEvent` object, -which has methods to get information about the event and the exception. - -.. _logging-non-0-exit-statuses: - -Logging Error Exit Statuses ---------------------------- - -The logging capabilities of the console can be further extended by logging -commands that return error exit statuses, which are any number different than -zero. This way you will know if a command had any errors, even if no exceptions -were thrown. - -First configure a listener for console terminate events in the service container: - -.. configuration-block:: - - .. code-block:: yaml - - # app/config/services.yml - services: - app.listener.command_error: - class: AppBundle\EventListener\ErrorLoggerListener - arguments: ['@logger'] - tags: - - { name: kernel.event_listener, event: console.terminate } - - .. code-block:: xml - - - - - - - - - - - - - - .. code-block:: php - - // app/config/services.php - use AppBundle\EventListener\ErrorLoggerListener; - use Symfony\Component\DependencyInjection\Definition; - use Symfony\Component\DependencyInjection\Reference; - - $definitionErrorLoggerListener = new Definition( - ErrorLoggerListener::class, - array(new Reference('logger')) - ); - $definitionErrorLoggerListener->addTag( - 'kernel.event_listener', - array('event' => 'console.terminate') - ); - $container->setDefinition( - 'app.listener.command_error', - $definitionErrorLoggerListener - ); - -Then implement the actual listener:: - - // src/AppBundle/EventListener/ErrorLoggerListener.php - namespace AppBundle\EventListener; - - use Symfony\Component\Console\Event\ConsoleTerminateEvent; - use Psr\Log\LoggerInterface; - - class ErrorLoggerListener - { - private $logger; - - public function __construct(LoggerInterface $logger) - { - $this->logger = $logger; - } - - public function onConsoleTerminate(ConsoleTerminateEvent $event) - { - $statusCode = $event->getExitCode(); - $command = $event->getCommand(); - - if ($statusCode === 0) { - return; - } - - if ($statusCode > 255) { - $statusCode = 255; - $event->setExitCode($statusCode); - } - - $this->logger->warning(sprintf( - 'Command `%s` exited with status code %d', - $command->getName(), - $statusCode - )); - } - } +Starting from Symfony 3.3, the Console component provides automatic error and +exception logging.