php 使用 Monolog 记录完整的堆栈跟踪

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20657309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 03:23:06  来源:igfitidea点击:

Logging full stack trace with Monolog

phpmonolog

提问by Wild One

I use Monologas a stand-alone library in my application and recently I ran into an issue. Let's say, at some point in my application I catch an exception and I want to log it:

我在我的应用程序中使用Monolog作为独立库,最近我遇到了一个问题。比方说,在我的应用程序中的某个时刻,我捕获了一个异常并且我想记录它:

$mylogger->error('Exception caught', array('exception' => $exception));

This works perfectly except one tiny thing - it doesn't log whole stack trace. Is it possible to log exception's full stack trace using monolog build-in formatters?

除了一件小事之外,这非常有效 - 它不会记录整个堆栈跟踪。是否可以使用 monolog 内置格式化程序记录异常的完整堆栈跟踪?

回答by Tomasz Madeyski

Actually since version 1.12.0it is possible to include stacktrace at your log file: there is new method of LineFormattercalled includeStacktraces.

实际上,从版本开始1.12.0,就可以在您的日志文件中包含堆栈跟踪:有一个新方法LineFormatter叫做includeStacktraces.

To use this, you need to overwrite default behaviour of monolog formatter:

要使用它,您需要覆盖 monolog 格式化程序的默认行为:

config.yml

配置文件

monolog:
    handlers:
        main:
            formatter: your.monolog.service.id
            (rest of config is as usual)

services.yml

服务.yml

services:
    your.monolog.service.id:
        class: Monolog\Formatter\LineFormatter
        calls:
            - [includeStacktraces]

Check github for more info: Pull request

检查 github 以获取更多信息: 拉取请求

回答by Amir

I have a very simple solution!!!

我有一个非常简单的解决方案!!!

$mylogger->error((string) $exception);

回答by Rayhan Muktader

No, You cannot log the stack trace using the built-in formatters. See my question here.

不,您不能使用内置格式化程序记录堆栈跟踪。在这里看到我的问题。

If you take a look at LineFormatter.phpyou see that the normalizeExceptionmethod is responsible for grabbing the exception data. So, I had to create a new formatter that extended LineFormatter. Here's the code:

如果您看一下,LineFormatter.php您会看到该normalizeException方法负责抓取异常数据。所以,我必须创建一个新的格式化程序,扩展LineFormatter. 这是代码:

<?php

namespace Monolog\Formatter;

use Exception;

class ExceptionLineFormatter extends LineFormatter
{
    protected function normalizeException(Exception $e)
    {
        return 'Message: ' . $e->getMessage() . 
                'Stack Trace: '. $e->getTraceAsString();
    }
}

And I initialized my logger like so:

我像这样初始化了我的记录器:

$logFile = 'MyLogFile.txt';
$handler = new StreamHandler($logFile);
$handler->setFormatter(new ExceptionLineFormatter);
$log = new Logger('MyLogger');
$handler = self::getStreamHander();
$log->pushHandler($handler);

This will will print out your stack trace.

这将打印出您的堆栈跟踪。

回答by SeinopSys

Adding to Tomasz Madeyski's answer, this is how you can use it via code only:

添加到Tomasz Madeyski 的答案,这是您只能通过代码使用它的方法:

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\ErrorHandler;
use Monolog\Formatter\LineFormatter;

$formatter = new LineFormatter(LineFormatter::SIMPLE_FORMAT, LineFormatter::SIMPLE_DATE);
$formatter->includeStacktraces(true); // <--

$stream = new StreamHandler('error.log');
$stream->setFormatter($formatter);

$logger = new Logger('logger');
$logger->pushHandler($stream);

回答by kxo

You can simply use the config file (Symfony Bundle)with the "include_stacktraces" parameter:

您可以简单地使用带有“ include_stacktraces”参数的配置文件(Symfony Bundle)

monolog:
    handlers:
        main:
            type: stream
            path: "%kernel.logs_dir%/%kernel.environment%.log"
            level: info
            channels: ["!event"]
            max_files: 10
            include_stacktraces: true <--- SET TO TRUE

@seethis commit

@看到这个提交

@seethe full schema (configuration)

@查看完整架构(配置)

回答by ADJenks

This is how I do it, yes years later...

这就是我这样做的方式,是的,多年后......

$mylogger->error('Exception caught', $exception->getTrace());

$mylogger->error('Exception caught', $exception->getTrace());

since getTrace() returns an array, which is what Monolog wants.

因为 getTrace() 返回一个数组,这正是 Monolog 想要的。

回答by eithed

If you want to log stacktrace onlywhen Exception is thrown, you can do this, in the AppServiceProvider:

如果你想记录堆栈跟踪只有当异常被抛出时,你可以做到这一点,在AppServiceProvider

public function register()
{
     $logger = Log::getMonolog();
     $logger->pushProcessor(function ($record) {
        if (isset($record['context']['exception']))
        {
            $record['extra']['stacktrace'] = $record['context']['exception']->getTraceAsString();
        }

        return $record;
    });
}

This will add the stacktrace to extracolumn, which then can be used per LineFormatter

这会将extra堆栈跟踪添加到列,然后可以在每个 LineFormatter 中使用

回答by Soullivaneuh

The Upvoted answer works, but you are not forced to create a custom service for that.

Upvoted答案的作品,但你不会被强迫创建一个定制服务。

The monolog.formatter.linealready exists on Symfony 3.4 full stack. You can simply add a method call on it thanks to the CompilerPassInterface:

monolog.formatter.line已经存在的Symfony的3.4完整的堆栈。您可以简单地在其上添加一个方法调用,这要归功于CompilerPassInterface

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use use Symfony\Component\HttpKernel\Kernel;

class AppKernel extends Kernel implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $container->getDefinition('monolog.formatter.line')->addMethodCall('includeStacktraces');
    }
}

The monolog handler does not seems to receive the service by default, so you still have to specify it. Example:

默认情况下,monolog 处理程序似乎不接收服务,因此您仍然必须指定它。例子:

monolog:
    handlers:
        main:
            type: rotating_file
            max_files: 12
            date_format: 'Y-m'
            path: '%kernel.logs_dir%/%kernel.environment%.log'
            level: debug
            formatter: monolog.formatter.line

回答by php_bob

getTraceAsString will give you the Stack Trace array as a 'End of Line' delimited string. Explode on PHP_EOL and then foreach through the array logging each element. Hope this helps.

getTraceAsString 将为您提供 Stack Trace 数组作为“行尾”分隔的字符串。在 PHP_EOL 上爆炸,然后 foreach 通过记录每个元素的数组。希望这可以帮助。

<?php
function test() {
    throw new Exception;
}

try {
    test();
} catch(Exception $e) {
    $array = explode(PHP_EOL, $e->getTraceAsString());
    foreach($array as $line){
        $mylogger->error($line);
}

Should produce something like this:

应该产生这样的东西:

#0 index.php(14): test()
#1 {main}