Reputation: 3410
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');
Upvotes: 10
Views: 10290
Reputation: 28160
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.)
Upvotes: 3
Reputation: 695
For catching max execution timeouts you can use php-fpm and set slowlog
+ request_slowlog_timeout which will log full stack traces.
Upvotes: 1
Reputation:
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);
}
}
Upvotes: 6