Clase Logger: conociendo qué ocurre en el sistema

¡Hola! De nuevo aquí me encuentro, dispuesto a seguir desgranando cada detalle de la implementación de LibWiiEsp. Hoy toca la clase Logger, que es muy útil para conocer los detalles de la ejecución de un programa en nuestra consola, eso sí, a posteriori. Y es que, como ya comenté en su momento, debuggear un programa en Nintendo Wii es bastante complicado. Cuando me ponga con los manuales, el primero que va a caer es el de instalación del entorno y de la biblioteca, pero el segundo será una importante ayuda para encontrar esos típicos fallos (generalmente tontos, otras veces no tanto) que nos traen de cabeza a los desarrolladores, pero que a ver quién es el guapo que localiza el origen de éste. Existen un par de herramientas que se pueden utilizar, pero que aportan más bien poca información.

¡Pero todo a su tiempo! De momento, hoy voy a describir la clase Logger, una forma muy sencilla de saber qué está pasando en las tripas de nuestro programa cuando lo ejecutamos.

Como ya he comentado, esta clase pretende ser una forma sencilla pero eficaz de registrar los eventos que se deseen durante la ejecución de un programa. Al ejecutarse un programa directamente en la videoconsola, no se dispone de ninguna herramienta que permita conocer el valor de expresiones o variables en tiempo de ejecución. Logger es de ayuda cuando sucede algún comportamiento anómalo o no esperado en la ejecución, ya que permite almacenar cadenas de texto en un búffer, y guardar éste en un archivo situado en la tarjeta SD para poder consultarlo posteriormente.

La clase proporciona cuatro niveles de registro, cada uno de los cuales se centra en un tipo concreto de información. Estos niveles son apagado (no se registra ningún evento) información (aquí se incluye cualquier tipo de información relevante sobre el comportamiento del sistema durante la ejecución), aviso (en este nivel se debería incluir información concreta sobre comportamientos que, sin llegar a provocar un error, no son esperados), y error (nivel de registro para almacenar mensajes sobre errores que pueden provocar la parada de la ejecución).

Logger implementa un patrón Singleton, de tal manera que se tendrá una única instancia fácilmente localizable en el sistema. Además, está pensada para ser combinada con un sistema de gestión de excepciones, ya que todos los eventos e informaciones que se registran en el archivo de log son cadenas de texto de alto nivel (de tipo std::string). Esto último facilita enormemente el poder registrar los mensajes de toda excepción que disponga de un método a la usanza de what() de las excepciones estándar (toda aquella que derive de std::exception), que devuelve una cadena de texto con el mensaje de la excepción.

Se debe tener en cuenta que las operaciones de lectura, y más aún las de escritura, en la tarjeta SD de la consola son muy lentas. Es por este motivo por el que se permite desactivar la función de log, mediante el nivel de registro OFF, cuando el programa no necesite información de depuración. Desactivando el registro de eventos se consigue que, al final del programa (que es cuando se produce la escritura del búffer en el archivo de log), no se sobrecargue el sistema con la operación de salida, y la ejecución pueda terminar en un intervalo de tiempo normal.

Funcionamiento interno

Los niveles de registro están agrupados en una enumeración que, a su vez, se define como tipo público de la clase para facilitar su utilización. El orden es desde el nivel más restrictivo (OFF, no se registra nada) a más amplio (INFO, se registra todo). Un nivel más amplio incluye a los más restrictivos que él, lo cual quiere decir que si, por ejemplo, se activara el nivel AVISO, se registrarían tanto mensajes de aviso como de error. Es por esto que se recomienda, en caso de necesitar representar los niveles como enteros, se utilice el cero para OFF, uno para ERROR, dos para AVISO y tres para INFO, con la intención de respetar la jerarquía de niveles. Por supuesto, la decisión final queda en manos del desarrollador.

Cuando se inicializa el sistema de registro de eventos, se guarda el nivel de log introducido como parámetro, y si éste no es OFF (no registrar nada), se sigue adelante. Se comprueba que la tarjeta SD esté disponible para realizar operaciones de entrada/salida, se abre el archivo de log indicado en el primer parámetro en modo escritura (si no existiera, se crea), y se establece una cadena de caracteres de alto nivel como búffer para los mensajes de log.

La clase irá registrando eventos en el búffer, cada uno en una línea, y comenzando por las cadenas [INFO] para el nivel de información, [AVISO] para el nivel de aviso, y [ERROR] para una cadena que contenga un mensaje con nivel de registro error. El guardado de eventos se realiza por orden de ejecución, de tal manera que cuanto más adelante se encuentre una línea en el archivo de log, será posterior en su ejecución a los eventos reflejados en líneas anteriores.

Por último, hay que tener en cuenta que el volcado del búffer en el archivo se realiza cuando se destruye la instancia de la clase. La ventaja de esta decisión es que, al realizarse un único guardado, el rendimiento del programa con Logger activado no se ve afectado durante la ejecución, hecho que merece la pena aún sabiendo que, al finalizar la aplicación, habrá que esperar a que finalice la operación de salida.

Ejemplo de uso

// Inicializar Logger con nivel de registro de avisos
logger->inicializar( "/apps/wiipang/info.log", Logger::AVISO );
// Registrar un mensaje de error
logger->error( "Esto es un mensaje de error" );
// Registrar un mensaje de aviso
logger->aviso( "Esto es un mensaje de aviso" );
// Registrar un mensaje de información, que no se guardará en el archivo de log
logger->info( "Esto es un mensaje de información, no se guardará" );

Y eso es todo lo que hay que contar sobre la clase Logger. Como podéis ver, es una idea muy simple, pero muy útil a la hora de pulir esos pequeños (y puñeteros) detalles de las aplicaciones que se desarrollen con LibWiiEsp. Como todos los elementos de la biblioteca, estará sujeto a cambios en una siguiente versión, pero de momento, cumple con bastante efectividad lo que se pretendía con la clase.

Por lo demás, comento (que no sé si lo habré dicho o no) que todas estas entradas en el blog son las descripciones de las clases de LibWiiEsp, y que se están recogiendo en los archivos de cabecera con la intención de generar la documentación completa de la biblioteca mediante Doxygen. Cuando acabe la redacción de todas las descripciones de clases y/o módulos, subiré en el apartado web de la forja la documentación en formato HTML, incluiré el Doxyfile en la carpeta doc, y también ahí pondré la propia documentación (a ver si le meto mano al Latex y la dejo bien decente en este formato también). Los manuales irán en el apartado de Ficheros de la Forja, pero para eso aún queda una semana y media, más o menos.

En fin, como siempre digo, ¡mañana más!

, , , , , , , ,

  1. Deja un comentario

Deja un comentario