如何在command中使用log

###1. 在命令行中手動記錄日誌php

// 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 #注意不是繼承的Command類
{
    // ...

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        /** @var $logger LoggerInterface */
        $logger = $this->getContainer()->get('logger');//直接獲取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);
    }
}

###2. 異常自動開啓app

####在服務容器中配置一個console.exception事件的監聽者this

# app/config/services.yml
services:
    kernel.listener.command_dispatch:
        class: AppBundle\EventListener\ConsoleExceptionListener
        arguments:
            logger: '@logger'
        tags:
            - { name: kernel.event_listener, event: console.exception }

####書寫監聽者類spa

// 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));
    }
}

當任何一個命令拋出異常;該監聽者就會接收到事件;事件會傳遞一個ConsoleExceptionEvent對象過來;根據該對象提供的信息記錄日誌命令行

###記錄非0退出狀態日誌

####配置一個console.terminate事件的監聽者code

services:
    kernel.listener.command_dispatch:
        class: AppBundle\EventListener\ErrorLoggerListener
        arguments:
            logger: '@logger'
        tags:
            - { name: kernel.event_listener, event: console.terminate }

####實現監聽者對象

// 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
        ));
    }
}
相關文章
相關標籤/搜索