Louder Developer Zone
Articles, Tutorials and Tips from the community and Louder developers

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í:

$config = CoreConfig::readAppConfig();
if($config->application->mode=="production"){

}

Crear el mensaje de diagnostico

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:



blog comments powered by Disqus

Previous: Geo-Localización en Kumbia Enterprise Next: Implementar Aspectos de Seguridad con KEF

Colaborate

Colaborate

We invite you to submit articles and tutorials to the Developer Zone.

Archive

  • Mayo 2009

Maybe you are interested

Added value to your Business.

Become a Solution Partner Louder Now.

Bring to the Open-Source retroactively..

Learn more about Shared Louder Labs