2012-02-16 60 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中,這些異常用backtrace記錄,在這種情況下,這種情況比這個異常更具信息性。

作爲解決方案:我將所有進程函數放在try..catch塊中,並手動記錄回溯。

是否有人知道如何在控制檯任務中啓用或配置日誌記錄。 我認爲它一定是在某個地方。

回答

14

正如我遵循的代碼,實際上沒有這樣的選項來啓用記錄的命令。在app/console是這樣的代碼:

use Symfony\Bundle\FrameworkBundle\Console\Application; 

... 

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

它調用Symfony\Component\Console\Application::run()其中有try/catch塊。在異常方法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

感謝您的解釋。我深入瞭解啓動文件console&index.php,但應深入研究Application類。 但似乎應用程序類的Web控制檯和共享相同的行爲。 – Sawered 2012-02-16 09:43:33

2

另一種方式是實現自己的自定義OutputInterface類並覆蓋writeln方法記錄的錯誤。然後在執行run()方法時使用新類。

通過這種方式,您可以堅持Symfony的Open/Close Principle,而無需修改基類並仍能實現您的目標。

6

TL; DR:只使用this bundle

cookbook

爲了讓您的控制檯應用程序來自動記錄所有的命令捕獲的異常,就可以使用控制檯的事件。

創建標記爲一個事件偵聽器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 2014-10-07 20:17:59

6

如果這僅僅事瞭解了什麼錯在何處,您可以在屏幕上詳細標誌-v--verbose,這將automatically print the exception trace運行你的應用程序。

+0

你是對的,但問題是關於寫入錯誤記錄(爲前。文件) 這是必要的,當我從cron – Sawered 2015-01-13 14:29:54

+0

運行CLI命令真,對不起,錯過了的cron部分。無法弄清楚如何在不使事情複雜化的情況下進行回溯,決定分享研究結果。 – 2015-01-13 14:49:02

+1

@IanBytchek,無論如何,謝謝你,你的回答幫了我很多! – 2017-03-30 10:18:20