2012-02-16 6 views
11

콘솔 작업의 오류가 기록되지 않는 이유. PHP는 경고에 예를 들어 예외 : 나는 표준 출력에 인쇄,하지만 아무것도 로그에 기록되지 것을 볼symfony 2 콘솔의 예외 로깅

[ErrorException]
Notice: Undefined offset: 1 in /var/www/project/vendor/doctrine/lib/Doctrine/ORM/Query.php line 298

. (저는 cron에서 콘솔 명령을 사용합니다). 웹에서 이러한 예외는 역 추적으로 기록되며이 상황에서는이 예외보다 정보가 더 많이 필요합니다.

해결 방법 : 모든 프로세스 기능을 try..catch 블록으로 묶고 백 트레이스를 수동으로 기록하십시오.

콘솔 작업에서 로깅을 설정하거나 구성하는 방법을 알고있는 사람은 누구나 있습니다. 어딘가에 있어야한다고 생각합니다.

답변

14

코드를 따라갈 때 실제로 명령에 대한 로깅을 사용하는 옵션은 없습니다.

use Symfony\Bundle\FrameworkBundle\Console\Application; 

... 

$application = new Application($kernel); 
$application->run(); 

그것은하는/catch 블록을 시도있다 Symfony\Component\Console\Application::run()를 호출 app/console에서이 코드입니다. 예외 메서드 인 경우 renderException()이 호출되지만 아무 것도 발생하지 않습니다.

기본적으로 app/console은 항상 기본적으로 예외 상태의 오류 코드와 함께 종료됩니다.

Application 클래스를 확장하여 Symfony\Bundle\FrameworkBundle\Console\Application까지 확장하고 app/console을 수정하여 사용할 수 있습니다. run() 메서드를 무시하고 오류 로깅을 추가 할 수 있습니다. 이 같은

아니면 단지 app/console을 수정하고 처리 할 수하는 오류 :

// $application->run(); 
$application->setCatchExceptions(false); 
try { 
    $output = new Symfony\Component\Console\Output\ConsoleOutput(); 
    $application->run(null, $output); 
} catch (Exception $e) { 
    ... error logging ... 

    $application->renderException($e, $output); 

    $statusCode = $e->getCode(); 
    $statusCode = is_numeric($statusCode) && $statusCode ? $statusCode : 1; 
    exit($statusCode); 
} 
+0

설명해 주셔서 감사합니다. 나는 콘솔 & index.php 파일을 발굴하지만 응용 프로그램 클래스에서 더 깊이 파고해야합니다. 하지만 웹 및 콘솔의 애플리케이션 클래스는 동일한 동작을 공유하는 것으로 보입니다. – Sawered

2

또 다른 방법은 사용자 정의 OutputInterface 클래스를 구현하고 거기에 오류를 기록하는 writeln 메소드를 오버라이드 (override)하는 것입니다. 그런 다음 run() 메서드를 실행할 때 새 클래스를 사용합니다.

이 방법을 사용하면 기본 클래스를 수정하지 않고도 목표를 달성 할 필요없이 Symfony의 Open/Close Principle을 준수 할 수 있습니다.

6

TL; DR이 : 그냥 cookbook에서 this bundle

를 사용 :

자동으로 모든 명령에 대한 캐치되지 않는 예외를 로그 콘솔 응용 프로그램을 얻으려면, 당신은 콘솔 이벤트를 사용할 수 있습니다.

console.exception 이벤트에 대한 이벤트 리스너로 태그 서비스 만들기 : 그것은 단지의 문제는 경우

<?php 
// src/Acme/DemoBundle/EventListener/ConsoleExceptionListener.php 
namespace Acme\DemoBundle\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); 
    } 
} 
+0

예, Symfony 2.3 이후로 더 나은 해결책입니다. – Martin

6

:

# services.yml 
services: 
    kernel.listener.command_dispatch: 
    class: Acme\DemoBundle\EventListener\ConsoleExceptionListener 
    arguments: 
     logger: "@logger" 
    tags: 
     - { name: kernel.event_listener, event: console.exception } 

당신은 지금 할 수있는 당신이 콘솔 예외가 원하는대로를 무엇이 잘못되었는지 이해하면 -v 또는 --verbose이라는 자세한 플래그로 앱을 실행할 수 있습니다.이 경우 화면에 automatically print the exception trace이 표시됩니다.

+0

당신 말이 맞지만 문제를 로그에 기록하는 것에 관한 것이 었습니다. (예 : 파일 용) cron에서 cli 명령을 실행할 때 필요했습니다. – Sawered

+0

죄송합니다. cron 부분을 놓쳤습니다. 백 카운트를 너무 복잡하게 만들지 않고 어떻게 결과를 공유하기로 결정했는지 알아낼 수 없었습니다. –

+1

@IanBytchek, 어쨌든 고맙습니다. 당신의 대답은 제게 많은 도움이되었습니다! –