I want to log every fatal errors, even timeout and others E_ERRORS ones. I use set_error_handler and shutdown function, but with the last one I cannot have the stacktrace. Is there any way to have it?
I want to log fatal errors on a production server to help resolving bugs which occurs only in production. I know, xdebug on dev servers must be enough, but it is not. Maybe we can use xdebug with the minimum of options activated, or a stripped version of it to add stack trace to error log?
This code print error information if one error occur, even a timeout.
<?php
function shutdown()
{
$a=error_get_last();
if($a!==null) print_r($a);
}
register_shutdown_function('shutdown');
You won't get a stack trace on the fatal error because "FATAL" means script execution stops immediately, i.e. the trace can't be generated through the usual channels. So, if you have set a custom error handler to throw exceptions, it won't be invoked for fatal errors as per the PHP manual:
The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called.
The easiest way to get info about what happened in the fatal error (short of turning display_errors
on, which isn't an option in production environments) is to manually build the error information yourself in the shutdown handler. Also, I wouldn't use xdebug on a production server ... it's for debugging your development environment and will add unnecessary overhead in a production environment.
So, modifying your shutdown handler you could do something like this:
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);
}
}
If you use HHVM you can set
hhvm.error_handling.call_user_handler_on_fatals = 1
in your php.ini
to have it call the error handler (with a stack trace) on fatal errors. (more info)
Using a profiler might also be an option - e.g. use XHProf and calling xhprof_disable()
in the fatal handler might get you something remotely resembling a stack trace. (No idea if this actually works.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With