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

Céd*_*ard 8 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');
Run Code Online (Sandbox Code Playgroud)

rdl*_*rey 7

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

使用用户定义的函数无法处理以下错误类型:E_ERROR,E_PARSE,E_CORE_ERROR,E_CORE_WARNING,E_COMPILE_ERROR,E_COMPILE_WARNING,以及调用set_error_handler()的文件中引发的大部分E_STRICT.

获取有关致命错误(缺少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);
  }
}
Run Code Online (Sandbox Code Playgroud)