简体   繁体   中英

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

Laravel console exception output uses nunomaduro/collision package, which seems to merge the exception and all chained exception stack traces into one incredibly useful output.

Laravel log output however uses Monolog, which doesn't appear to do this by default, and only appears to output the stack trace of the last exception thrown. It will output the messages of the previous exceptions, but not the stack traces .

When using an exception methodology which catches an exception, creates a new exception adding more contextual information and attaching the previous one to it, creating a chain of exceptions. Having the stack trace of only the last exception thrown isn't particularly useful.

The first exception thrown (last one in the chain) is the original cause of the error, all of the other exceptions are simply adding context/information to it.

Is there a way to get Laravel to merge the stack traces of each exception in the chain?

Failing that, is there a way to just get Laravel/Monolog to output the stack trace of the first exception thrown (the last one in the chain), instead of the last exception thrown (the first one in the chain)?

(Very contrived) code example:

<?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!');
}

After digging a bit deeper, this is an issue with Monolog 1.x in the LineFormatter only. The other formatters work.

Monolog 2.x has resolved this issue with in the LineFormatter by this pull request: https://github.com/Seldaek/monolog/pull/1170 .

The solution is to upgrade to monolog 2.x (which is supported by Laravel 6.x).

An alternative solution, should you have packages which depend on Monolog 1.x would be to use a different formatter or write your own Monolog Formatter which extends LineFormatter, and use that in your Laravel logging config.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM