我在我的應用程序中使用Monolog作爲獨立庫,最近我遇到了一個問題。比方說,在我的應用程序某些時候我趕上一個例外,我想記錄它:使用Monolog記錄完整堆棧跟蹤
$mylogger->error('Exception caught', array('exception' => $exception));
這工作完全只是一件小事情 - 它不記錄整個堆棧跟蹤。是否有可能使用monolog內置格式化程序記錄異常的完整堆棧跟蹤?
我在我的應用程序中使用Monolog作爲獨立庫,最近我遇到了一個問題。比方說,在我的應用程序某些時候我趕上一個例外,我想記錄它:使用Monolog記錄完整堆棧跟蹤
$mylogger->error('Exception caught', array('exception' => $exception));
這工作完全只是一件小事情 - 它不記錄整個堆棧跟蹤。是否有可能使用monolog內置格式化程序記錄異常的完整堆棧跟蹤?
不,您不能使用內置格式化程序記錄堆棧跟蹤。看到我的問題here。
如果你看看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();
}
}
我初始化我的記錄,像這樣:
$logFile = 'MyLogFile.txt';
$handler = new StreamHandler($logFile);
$handler->setFormatter(new ExceptionLineFormatter);
$log = new Logger('MyLogger');
$handler = self::getStreamHander();
$log->pushHandler($handler);
這將打印出您的堆棧跟蹤。
實際上,由於版本1.12.0
有可能在您的日誌文件中包含堆棧跟蹤:LineFormatter
有一個新方法,稱爲includeStacktraces
。
要使用此,你需要重寫獨白格式的默認行爲:
config.yml
monolog:
handlers:
main:
formatter: your.monolog.service.id
(rest of config is as usual)
services.yml
services:
your.monolog.service.id:
class: Monolog\Formatter\LineFormatter
calls:
- [includeStacktraces]
檢查github上更多info: Pull request
我有一個非常簡單的解決方案!
$mylogger->error((string) $exception);
謝謝阿米爾! !!! !!! – adjenks
你甚至可以忽略(字符串)調用。至少如果你使用Monolog。 –
getTraceAsString會爲您提供Stack Trace數組作爲'End of Line'分隔字符串。在PHP_EOL上展開,然後通過數組記錄每個元素。希望這可以幫助。
<?php
function test() {
throw new Exception;
}
try {
test();
} catch(Exception $e) {
$array = explode(PHP_EOL, $e->getTraceAsString());
foreach($array as $line){
$mylogger->error($line);
}
應該產生這樣的:
#0 index.php(14): test()
#1 {main}
這是我要做的事,是年後...
$mylogger->error('Exception caught', $exception->getTrace());
因爲getTrace()返回一個數組,這是Monolog想要的。
對於像我這樣使用過的人來說,要注意的事實是,如果你使用Gelf處理程序,這會引發異常。由於getTrace數組從0開始計數,這是'GelfMessage :: setAdditional()'中的無效鍵, –
添加到Tomasz Madeyski's answer,這是你怎麼能僅通過代碼中使用它:
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);
的Upvoted answer works,但你不會被強迫創建一個定製服務。
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');
}
}
的獨白處理程序似乎並不在默認情況下接收服務,所以你還是要指定它。例如:
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
它還與使用所述方法,無需一個配置所需的代碼存在於JsonFormatter – magnetik
我添加了一個[單獨的應答(https://stackoverflow.com/a/46379123/1344955)文件。用戶不允許對其他人的答案進行實質性編輯,但如果您想編輯它,我將刪除我的答案。 – SeinopSys