使 Laravel 6.x/Monolog 输出先前异常的堆栈跟踪

Make Laravel 6.x/Monolog output stack trace of previous exceptions

Laravel 控制台异常输出使用 nunomaduro/collision 包,它似乎将异常和所有链接的异常堆栈跟踪合并到一个非常有用的输出中。

然而,

Laravel 日志输出使用 Monolog,默认情况下它似乎不会这样做,并且似乎只输出最后一个抛出的异常的堆栈跟踪。它输出先前异常的消息,但不是堆栈跟踪

当使用捕获异常的异常方法时,创建一个新的异常,添加更多上下文信息并将前一个附加到它,创建一个异常链。仅对抛出的最后一个异常进行堆栈跟踪并不是特别有用。

抛出的第一个异常(链中的最后一个)是错误的原始原因,所有其他异常只是简单地向其添加 context/information。

有没有办法让 Laravel 合并链中每个异常的堆栈跟踪?

做不到这一点,有没有办法让 Laravel/Monolog 输出第一个抛出的异常(链中的最后一个)的堆栈跟踪,而不是最后一个抛出的异常(链中的第一个)链)?

(非常做作)代码示例:

<?php
method1();

function method1()
{
    try {
        method2();
    } catch (\Exception $e) {
        // Laravel outputs the stack trace of this one in the logs, but it is of
        // little real-world use.
        throw new \Exception('Calling method1 failed because blah', $e->getCode(), $e);
    }
}

function method2()
{
    try {
        method3();
    } catch (\Exception $e) {
        throw new \Exception('Calling method2 failed because blah', $e->getCode(), $e);
    }
}

function method3()
{
    // I'd like a stack trace of this one, or even better a merged 
    // stack trace of all 3 exceptions to be output in the logs by Laravel/monolog.
    throw new \Exception('Ooops an error!');
}

深入挖掘后,这只是 LineFormatter 中 Monolog 1.x 的问题。其他格式化程序工作。

Monolog 2.x 已通过此拉取请求在 LineFormatter 中解决了此问题:https://github.com/Seldaek/monolog/pull/1170.

解决方案是升级到 monolog 2.x( 受 Laravel 6.x 支持)。

另一种解决方案,如果你有依赖于 Monolog 的包 1.x 将使用不同的格式化程序或编写你自己的扩展 LineFormatter 的 Monolog 格式化程序,并在你的 Laravel 日志记录中使用它配置