记录带有堆栈跟踪的异常日志

65

如果我在PHP中没有捕获异常,我会在我的error.log文件中得到一个带有堆栈跟踪的有用错误信息。例如,如果我运行:

<?php

  function foo() {
    throw new Exception('Oh no!');
  } 

  foo();

?>

然后我会在日志中记录下以下内容:

[Wed Mar 06 10:35:32 2013] [error] [client 86.146.145.175] PHP致命错误: 在/var/www/test.php的第4行抛出了一个消息为"Oh no!"的异常\n堆栈跟踪:\n#0 /var/www/test.php(7): foo()\n#1 {main}\n

有时我想捕获异常,但仍要记录该详细信息。我的想法是像这样:

<?php

  function foo() {
    throw new Exception('Oh no!');
  } 

  try {
      foo();
  } catch (Exception $e) {
      log_exception($e);
  }

?>

log_exception函数会以与未捕获异常自动写入的基本相同格式写入错误日志,除了使用Caught exception代替PHP Fatal error: Uncaught exception之外,它们可能几乎完全相同。

是否有内置函数可以记录异常信息或将其捕获为字符串?我想象中的类似于Python中的traceback.format_exc()的东西。

4个回答

95
error_log($e);

它做你想要的事情。它记录了与未捕获异常记录完全相同的内容,只是在开头减去了“Uncaught”一词。这样做是因为 Exception 类的 __toString() 魔术方法 的返回值。

您可以在 catch 块中执行此操作:

try {
    foo();
} catch (Exception $e) {
    error_log("Caught $e");
}

或者在异常处理程序中:

set_exception_handler(function($exception) {
    error_log($exception);
    error_page("Something went wrong!");
});

ExceptiontoString 成员函数有什么“神奇”之处? - lmat - Reinstate Monica
@lmat-ReinstateMonica,这只是调用未捕获异常的方法,并在error_log函数中将异常转换为“可记录”的字符串。 - Jay K

10
你可以使用来自PHP的基础Exception的方法。
使用getMessage获取消息Oh no!,并使用getTraceAsString获取格式化的跟踪信息。

8

我们在应用程序中使用Monolog进行日志记录。Monolog有一个格式化程序,可以打印堆栈跟踪信息。为了记录带有跟踪信息的异常,我们使用LineFormatter,并在其上调用includeStacktraces()函数。(代码如下)

$handler = new \Monolog\Handler\StreamHandler(STDOUT);

$lineFormatter = new \Monolog\Formatter\LineFormatter();
$lineFormatter->includeStacktraces();

$handler->setFormatter($lineFormatter);

$logger = new \Monolog\Logger('root', [$handler]);

try {
    //do some throwing
} catch (Exception $e) {
    //do some logging, add exception to context
    $logger->error($e->getMessage(), ['exception' => $e]);
}

-3

6
描述说这将为未捕获的异常设置一个处理程序,而我询问的情况恰好不是这种情况。 - Mark Amery

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接