2012-02-16 19 views
11

コンソールタスクからのエラーが記録されない理由。 は、PHPの警告上の例の例外の場合:Symfony 2コンソールでの例外のログ

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

私は標準出力に印刷されたかを見るが、何もログに記録されません。 (私はcronでコンソールコマンドを使用しています)。 Webでは、これらの例外はバックトレースでログに記録されました。この状況では、この例外よりも情報が豊富です。

解決策:私はすべてのプロセス機能をtry..catchブロックで囲み、手動でバックトレースを記録します。

コンソールタスクのログを有効にしたり構成する方法は誰にも分かりません。 どこかにあるはずだと思います。

答えて

14

私はコードに従っているので、実際にはコマンドのログを有効にするオプションはありません。 app/consoleでは、このコードです:

use Symfony\Bundle\FrameworkBundle\Console\Application; 

... 

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

それは/ catchブロックを試してみてくださいありますSymfony\Component\Console\Application::run()する呼び出します。例外のメソッドではrenderException()が呼び出されますが、ログはどこにも発生しません。

また、常にデフォルトではapp/consoleが終了し、例外時にエラーコードが出力されます。

Applicationクラスを拡張してSymfony\Bundle\FrameworkBundle\Console\Applicationに拡張し、app/consoleを変更して使用することができます。 run()メソッドをオーバーライドしてエラーログを追加するよりも、このような

それとも、単にapp/consoleを変更し、処理することができerros:

// $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ファイルを起動しますが、アプリケーションクラスで深く掘り下げてください。 しかし、web&consoleのアプリケーションクラスは同じ動作をしているようです。 – Sawered

2

もう一つの方法は、独自のカスタムOutputInterfaceクラスを実装し、そこにエラーをログに記録するwritelnメソッドをオーバーライドすることです。次に、run()メソッドを実行するときに新しいクラスを使用します。

このようにして、基本クラスを変更せずに目標を達成しなくても、symfonyのOpen/Close Principleに準拠することができます。

6

TL; DRは:ちょうどcookbookからthis bundle

を使用するには:

は、自動的にすべてのコマンドのためのキャッチされない例外をログに記録するには、コンソールアプリケーションを取得するには、コンソールイベントを使用することができます。

サービスを作成しますがconsole.exceptionイベントのイベントリスナーとしてタグ付け:

# services.yml 
services: 
    kernel.listener.command_dispatch: 
    class: Acme\DemoBundle\EventListener\ConsoleExceptionListener 
    arguments: 
     logger: "@logger" 
    tags: 
     - { name: kernel.event_listener, event: 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

それは単にの問題だ場合、あなたは画面上の冗長フラグ-vまたは--verbose、意志automatically print the exception traceでアプリケーションを実行できるところ何が悪かったのか理解します。

+0

あなたは正しいですが、ログにエラーを書き込むことについて質問しました(ファイル内など) cronからcliコマンドを実行するときに必要でした – Sawered

+0

真実、申し訳ありませんが、cronの部分を見逃しました。どのようにバックトレースに到達するのか分かりませんでした。すべてを複雑にすることなく、結果を共有することに決めました。 –

+1

@IanBytchek、とにかくありがとう、あなたの答えは私を助けてくれました! –

関連する問題