概述 快速入门 教程 手册 最佳实践 组件 参考 贡献

发布于 2015-08-27 16:39:40 | 153 次阅读 | 评论: 0 | 来源: 网络整理

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.

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 framework as described in “创建命令行Command”, your command extends 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 AppBundleCommand;

use SymfonyBundleFrameworkBundleCommandContainerAwareCommand;
use SymfonyComponentConsoleInputInputArgument;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleInputInputOption;
use SymfonyComponentConsoleOutputOutputInterface;
use PsrLogLoggerInterface;

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 app/logs/dev.log or app/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 console events.

2.3 新版功能: Console events were introduced in Symfony 2.3.

First configure a listener for console exception events in the service container:

  • YAML
    # app/config/services.yml
    services:
        kernel.listener.command_dispatch:
            class: AppBundleEventListenerConsoleExceptionListener
            arguments:
                logger: "@logger"
            tags:
                - { name: kernel.event_listener, event: console.exception }
    
  • XML
    <!-- app/config/services.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <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="kernel.listener.command_dispatch" class="AppBundleEventListenerConsoleExceptionListener">
                <argument type="service" id="logger"/>
                <tag name="kernel.event_listener" event="console.exception" />
            </service>
        </services>
    </container>
    
  • PHP
    // app/config/services.php
    use SymfonyComponentDependencyInjectionDefinition;
    use SymfonyComponentDependencyInjectionReference;
    
    $definitionConsoleExceptionListener = new Definition(
        'AppBundleEventListenerConsoleExceptionListener',
        array(new Reference('logger'))
    );
    $definitionConsoleExceptionListener->addTag(
        'kernel.event_listener',
        array('event' => 'console.exception')
    );
    $container->setDefinition(
        'kernel.listener.command_dispatch',
        $definitionConsoleExceptionListener
    );
    

Then implement the actual listener:

// src/AppBundle/EventListener/ConsoleExceptionListener.php
namespace AppBundleEventListener;

use SymfonyComponentConsoleEventConsoleExceptionEvent;
use PsrLogLoggerInterface;

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 ConsoleExceptionEvent object, which has methods to get information about the event and the exception.

Logging non-0 Exit Statuses

The logging capabilities of the console can be further extended by logging non-0 exit statuses. 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:

  • YAML
    # app/config/services.yml
    services:
        kernel.listener.command_dispatch:
            class: AppBundleEventListenerErrorLoggerListener
            arguments:
                logger: "@logger"
            tags:
                - { name: kernel.event_listener, event: console.terminate }
    
  • XML
    <!-- app/config/services.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <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="kernel.listener.command_dispatch" class="AppBundleEventListenerErrorLoggerListener">
                <argument type="service" id="logger"/>
                <tag name="kernel.event_listener" event="console.terminate" />
            </service>
        </services>
    </container>
    
  • PHP
    // app/config/services.php
    use SymfonyComponentDependencyInjectionDefinition;
    use SymfonyComponentDependencyInjectionReference;
    
    $definitionErrorLoggerListener = new Definition(
        'AppBundleEventListenerErrorLoggerListener',
        array(new Reference('logger'))
    );
    $definitionErrorLoggerListener->addTag(
        'kernel.event_listener',
        array('event' => 'console.terminate')
    );
    $container->setDefinition(
        'kernel.listener.command_dispatch',
        $definitionErrorLoggerListener
    );
    

Then implement the actual listener:

// src/AppBundle/EventListener/ErrorLoggerListener.php
namespace AppBundleEventListener;

use SymfonyComponentConsoleEventConsoleTerminateEvent;
use PsrLogLoggerInterface;

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
        ));
    }
}
最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务