Crear un sistema de reportes de Excepciones para nuestras Aplicaciones
Publish at Tuesday, March 30, 2010
By Core Developers - Louder
Las aplicaciones están llenas de errores ocultos y una vez puestas en producción su seguimiento y diagnostico
resultan complicados. Una útil herramienta de diagnostico son los sistemas de
CrashReport.
En esta ocasión vamos a desarrollar un sencillo sistema de Crash Report
para nuestras aplicaciones. El objetivo es que se nos envíe un correo si se genera una excepción y la aplicación se encuentra en producción.
Este correo debe darnos suficiente información de lo que estaba sucediendo para tratar de buscar una solución y
corregir el problema.
Capturar las excepciones ocurridas
Para poder capturar las excepciones ocurridas en cualquier parte de la aplicación vamos a usar un plugin de aplicación.
Creamos un archivo de plugin en apps/default/plugins/CrashReport.php con la siguiente clase:
<php
class CrashReportPlugin extends ApplicationPlugin {
public function beforeUncaughtException($exception){
}
}
El método beforeUncaughtException es ejecutado cuando una excepción no fué capturada por la aplicación.
El parámetro $exception es la excepción generada.
Si no se quieren usar plug-in se puede usar el tradicional evento
onException del ControllerBase,
así en apps/default/controllers/application.php:
<php
class ControllerBase {
public function onException($exception){
}
}
Detectar el entorno activo
Cuando la aplicación está en modo test ó modo development lo ideal es poder visualizar la pantalla de excepciones, pero cuando está en producción
es recomendable generar una pantalla adecuada para el usuario. Nuestro CrashReport solo enviará el correo cuando se encuentre la aplicación en modo
production.
$enviroment = CoreConfig::getAppSetting("mode");
if($enviroment=="production"){
} else {
//Si está en modo test ó development se relanza la excepción
throw $exception;
}
En versiones anteriores de Kumbia Enteprise se detecta el entorno así:
El siguiente paso es crear un mensaje de diagnostico con toda la información que podamos que luego pueda ser
analizada por el desarrollador:
$message = "";
//Cuando sucedio?
$message.="Fecha y Hora: ".Date::now()."\n";
//Qué se envíó por GET?
$message.="GET: ".print_r($_GET, true)."\n";
//Qué se envió por POST?
$message.="POST: ".print_r($_POST, true)."\n";
//Qué había en SERVER?
$message.="SERVER: ".print_r($_SERVER, true)."\n";
//Qué había en SESSION?
$message.="SESSION: ".print_r($_SESSION, true)."\n";
//Tipo de Excepción: CoreException, DbException, TagException?
$message.="Tipo: ".get_class($exception)."\n";
//Mensaje de la Excepción
$message.="Mensaje: ".$exception->getMessage()."\n";
//Código de la Excepción
$message.="Código: ".$exception->getCode()."\n";
//Línea donde se produjo la Excepción
$message.="Archivo: ".$exception->getCode()."\n";
//Traza de la excepción
$message.=$exception->getTraceAsString();
//Que había en memoria local?
foreach(Debug::getMemory() as $memory){
foreach($memory as $variable => $valor){
$message.=$variable."=".$valor;
}
}
El mensaje puede tener un mejor formato y otros datos propios de la aplicación como el usuario, el rol, la dirección IP, etc.
Si las excepciones heredan a CoreExcepción hay un extenso API para obtener información de la excepción que puede ser útil en este caso.
Envíar el mensaje en un E-Mail
Para esto usamos la librería por defecto de envio de correos de Kumbia Enterprise llamada Swift.
Core::importFromLibrary("Swift", "Swift.php");
Core::importFromLibrary("Swift", "Swift/Connection/SMTP.php");
$message = new Swift_Message("Ocurrió un error :S");
$recipients = new Swift_RecipientList();
$body_message = new Swift_Message_Part($body, "text/plain");
$body_message->setCharset("UTF-8");
$message->attach($message);
//Se envia el mensaje a los interesados
$recipients->addTo("david@miempresa.com", "David Izquierdo");
$recipients->addTo("antonio@miempresa.com", "Antonio Lopez");
try {
$smtp = new Swift_Connection_SMTP("smtp.miempresa.com");
$smtp->setUsername("soporte@miempresa.com");
$smtp->setPassword("secreto");
$swift = new Swift($smtp);
$swift->send($message, $recipients, new Swift_Address("soporte@miempresa.com", "robot soporte"));
//Mostramos una pantalla mas adecuada
Router::routeTo(array("controller" => "errores", "action" => "index"));
}
catch(Exception $mailException){
//Una excepción dentro de la excepción!
throw $exception;
}
Eso es todo. De esta forma completamos el tutorial. ¿Que queda por hacer? Hay mucho que se puede mejorar pero ya tenemos una buena base.
Conclusiones
Un CrashReport agrega valor a nuestras aplicaciones y mejora nuestra capacidad de diagnostico de problemas
Kumbia Enterprise ofrece varios métodos para darle manejo a las excepciones no capturadas
Tell friends about this article on social networks: