Symfony 2コンソールのロギング例外
-
25-10-2019 - |
質問
コンソールタスクからのエラーが記録されない理由。たとえば、PHP警告の例外:
[ErrorException]
Notice: Undefined offset: 1 in /var/www/project/vendor/doctrine/lib/Doctrine/ORM/Query.php line 298
stdoutで印刷されたものがわかりますが、ログにログに記録するものはありません。 (Cronでコンソールコマンドを使用しています)。 Webでは、これらの例外がBackTraceで記録されていますが、この状況ではこの例外よりも情報が高くなります。
解決策として:Try..Catchブロックですべてのプロセス関数を囲み、バックトレースを手動でログに記録します。
コンソールタスクでログを有効または構成する方法を知っている人はいますか?どこかにあるに違いないと思います。
解決
コードに従ったとき、コマンドのログを有効にするためのそのようなオプションは実際にはありません。の app/console
このコードですか:
use Symfony\Bundle\FrameworkBundle\Console\Application;
...
$application = new Application($kernel);
$application->run();
それは呼び出します 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);
}
他のヒント
それがどこで何がうまくいかなかったかを単に理解することの問題である場合、冗長なフラグでアプリを実行できます -v
また --verbose
, 、それはそうします 例外トレースを自動的に印刷します 画面上。
tl; dr :使用するだけです このバンドル
から 料理本 :
コンソールアプリケーションを取得するには、すべてのコマンドに対して猛攻撃の例外を自動的にログに記録するには、コンソールイベントを使用できます。
イベントリスナーとしてタグ付けされたサービスを作成します 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);
}
}
別の方法は、独自の習慣を実装することです OutputInterface
クラスとオーバーライド writeln
そこでエラーを記録する方法。次に、実行するときに新しいクラスを使用します run()
方法。
このようにして、次に付着することができます オープン/クローズ原理 ベースクラスを変更し、それでも目標を達成する必要がなく、シュマフニーの。