PHP:生产中的FATAL错误的日志堆栈跟踪

时间:2012-01-24 17:01:40

标签: php error-handling

我想记录每个致命错误,甚至超时和其他E_ERRORS错误。我使用set_error_handler和shutdown函数,但是最后一个我没有stacktrace。有没有办法拥有它?

我想在生产服务器上记录致命错误,以帮助解决仅在生产中发生的错误。我知道,开发服务器上的xdebug必须足够,但事实并非如此。也许我们可以使用xdebug激活最少的选项,或者使用它的剥离版本将堆栈跟踪添加到错误日志中?

如果发生一个错误,即使超时,此代码也会打印错误信息。

<?php
function shutdown()
{
    $a=error_get_last();
    if($a!==null) print_r($a);  
}
register_shutdown_function('shutdown');

2 个答案:

答案 0 :(得分:7)

您不会在致命错误上获得堆栈跟踪,因为“FATAL”表示脚本执行会立即停止 ,即无法通过常规通道生成跟踪。因此,如果您已设置自定义错误处理程序以抛出异常,则不会根据PHP manual调用致命错误:

  

使用用户定义无法处理以下错误类型   功能: E_ERROR,E_PARSE,E_CORE_ERROR,E_CORE_WARNING,   E_COMPILE_ERROR,E_COMPILE_WARNING ,以及大多数 E_STRICT   调用set_error_handler()的文件。

获取有关致命错误中发生的事情的最简单方法(在生产环境中不能选择display_errors)是在关机处理程序中自己手动构建错误信息。另外,我不会在生产服务器上使用xdebug ......它用于调试开发环境,并会在生产环境中增加不必要的开销。

因此,修改关闭处理程序可以执行以下操作:

function shutdown()
{
  if ( ! $err = error_get_last()) {
    return;
  }

  $fatals = array(
    E_USER_ERROR      => 'Fatal Error',
    E_ERROR           => 'Fatal Error',
    E_PARSE           => 'Parse Error', 
    E_CORE_ERROR      => 'Core Error',
    E_CORE_WARNING    => 'Core Warning',
    E_COMPILE_ERROR   => 'Compile Error',
    E_COMPILE_WARNING => 'Compile Warning'
  );

  if (isset($fatals[$err['type']])) {
    $msg = $fatals[$err['type']] . ': ' . $err['message'] . ' in ';
    $msg.= $err['file'] . ' on line ' . $err['line'];
    error_log($msg);
  }
}

答案 1 :(得分:3)

如果使用HHVM,可以设置

hhvm.error_handling.call_user_handler_on_fatals = 1

在你的php.ini中让它在致命错误上调用错误处理程序(带有堆栈跟踪)。 (more info

使用分析器也可能是一种选择 - 例如使用XHProf并在致命处理程序中调用xhprof_disable()可能会使您远程类似于堆栈跟踪。 (不知道这是否真的有效。)