2012-01-24 14 views
8

Quiero registrar cada error fatal, incluso tiempo de espera y otros E_ERRORS. Yo uso set_error_handler y shutdown function, pero con el último no puedo tener stacktrace. ¿Hay alguna forma de tenerlo?PHP: seguimiento de pila de registro para errores FATAL en producción

Quiero registrar errores fatales en un servidor de producción para ayudar a resolver errores que ocurren solo en producción. Lo sé, xdebug en servidores de desarrollo debe ser suficiente, pero no lo es. ¿Tal vez podamos usar xdebug con el mínimo de opciones activadas, o una versión eliminada de él para agregar el seguimiento de la pila al registro de errores?

Este código imprime la información de error si ocurre un error, incluso un tiempo de espera.

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

Respuesta

7

Usted no recibirá un seguimiento de pila en el error fatal porque "FATAL" significa la ejecución del script se detiene inmediatamente , es decir, la traza no se puede generar a través de los canales habituales. Por lo tanto, si ha configurado un controlador de errores personalizado para lanzar excepciones, no va a ser invocada por los errores fatales como por la PHP manual:

Los siguientes tipos de errores que no se pueden manejar con un usuario definido función: E_ERROR , E_PARSE, E_CORE_ERROR E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, y la mayoría de E_STRICT se crió en el archivo donde se llama set_error_handler().

La forma más sencilla de obtener información sobre lo que ocurrió en el error fatal (abreviatura de convertir en display_errors, que no es una opción en los entornos de producción) es construir manualmente la información de error a sí mismo en el controlador de apagado. Además, no usaría xdebug en un servidor de producción ... es para depurar su entorno de desarrollo y agregará sobrecarga innecesaria en un entorno de producción.

Por lo tanto, la modificación de su manejador de apagado se podría hacer algo como esto:

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); 
    } 
} 
+0

Tenga en cuenta que me tiró en el ** ** E_USER_ERROR en el '$ fatals' array, pero en realidad puede manejarse con éxito mediante un controlador de error personalizado. – rdlowrey

+0

Ok, estaba pensando en un módulo de PHP que acaba de atrapar la stacktrace para errores fatales, como xdebug pero más ligero. Mi búsqueda es cómo tener más información sobre los errores fatales en la producción para ayudar a corregirlos. –

+0

@ CédricGirard Ah, ya veo.Creo que la gran mayoría de los errores fatales son del tipo que pueden eliminarse durante la fase de desarrollo ... el resto son condiciones extraordinarias (como quedarse sin memoria, romper el servidor con un garrote en mitad de la solicitud, etc.). En estos casos, siempre he encontrado que el método anterior proporciona información suficiente para el registro. No he probado para ver si funciona con errores FATAL (creo que debería), pero podrías intentar agregar una llamada a ['debug_print_backtrace'] (http://www.php.net/manual/en/function. debug-print-backtrace.php) dentro de su controlador de apagado para información de rastreo – rdlowrey

1

Para la captura de ejecución máximo los tiempos de espera se puede utilizar PHP-FPM y establecer slowlog + request_slowlog_timeout que ingrese seguimientos de pila completo.

3

Si utiliza HHVM puede establecer

hhvm.error_handling.call_user_handler_on_fatals = 1 

en su php.ini tener que llamar al gestor de errores (con un seguimiento de pila) en errores fatales. (more info)

El uso de un generador de perfiles también puede ser una opción, p. use XHProf y llame al xhprof_disable() en el manejador fatal para obtener algo remotamente parecido a un seguimiento de pila. (Ni idea de si esto realmente funciona.)

+0

La opción HHVM y el enlace son exactamente lo que estaba buscando. –

0

Esto funciona para mí (dentro de un condicional por lo que sólo se ejecuta en un entorno de desarrollo):

if (function_exists('xdebug_break')) { 
    register_shutdown_function(function() { 
     if ($last_error = error_get_last()) { 
      xdebug_break(); 
     } 
    }); 
} 
Cuestiones relacionadas