Symfony 2 在控制台中记录异常

发布于 2025-01-06 02:41:27 字数 353 浏览 1 评论 0原文

为什么不记录控制台任务的错误。 例如 php 警告异常:

[ErrorException]
注意:未定义的偏移:1 in /var/www/project/vendor/doctrine/lib/Doctrine/ORM/Query.php line 298

我看到标准输出中打印的内容,但没有记录到日志中。 (我在 cron 中使用控制台命令)。 在 Web 中,这些异常是通过回溯记录的,在这种情况下,回溯比仅此异常提供更多信息。

作为解决方案:我将所有进程函数包含在 try..catch 块中并手动记录回溯。

有谁知道如何启用或配置控制台任务中的日志记录。 我想它一定在某个地方。

Why errors from console tasks are not logged.
For example Exception on php warning:

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

I see what printed in stdout, but nothing logged to logs. (I use console commands in cron).
In web these exceptions logged with backtrace, which in this situation is more informational than just this exception.

As a solution: I enclose all process function in try..catch block and log the backtrace manually.

Is anyone know how to enable or configure logging in console tasks.
I think it must be somewhere.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

離人涙 2025-01-13 02:41:27

当我跟踪代码时,实际上没有这样的选项来启用命令日志记录。在 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);
}

As I followed the code, there's actually no such an option to enable logging for commands. In app/console is this code:

use Symfony\Bundle\FrameworkBundle\Console\Application;

...

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

It calls Symfony\Component\Console\Application::run() in which there's try/catch block. On exception method renderException() is called, but no logging happens anywhere.

Also note that app/console always by default exits with error code on exception.

You can create you own Application class extending Symfony\Bundle\FrameworkBundle\Console\Application and modify app/console to use it. Than you can override run() method and add errors logging.

Or you can modify just app/console and handle erros like this:

// $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);
}
优雅的叶子 2025-01-13 02:41:27

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

TL;DR : just use this bundle

From the cookbook :

To get your console application to automatically log uncaught exceptions for all of your commands, you can use console events.

Create a service tagged as an event listener for the console.exception event :

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

You can now do whatever you want with console exceptions :

<?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);
    }
}
两相知 2025-01-13 02:41:27

如果只是简单地了解哪里出了问题,您可以使用详细标志 -v--verbose 运行应用程序,这将 自动在屏幕上打印异常跟踪

If that's the matter of simply understanding what went wrong where, you can run your app with the verbose flag -v or --verbose, which will automatically print the exception trace on the screen.

薔薇婲 2025-01-13 02:41:27

另一种方法是实现您自己的自定义 OutputInterface 类并重写 writeln 方法以记录错误。然后在执行 run() 方法时使用新类。

这样你就可以遵守 Symfony 的打开/关闭原则,而无需修改基础课程并仍然实现您的目标。

Another way is to implement your own custom OutputInterface class and override the writeln method to log the error there. Then use the new class when you execute the run() method.

This way you can adhere to the Open/Close Principle of Symfony without having to modify the base classes and still achieve your goals.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文