PSR-3: El estándar para las librerías logger de PHP

Posted by victor on February 9th, 2013
php-logoEl PSR-3 es un proposed-standard-request que describe una interfaz común que deberían cumplir las librerías que realizan logger, registrar las acciones que ocurren durante la ejecución, en nuestras aplicaciones PHP. Los PSR son como los RFC o Request for Comments, documentos que describe como se lleva a cabo una tarea y que se someten a comentarios y a voto para adoptarse como estándar. PSR-3 propone un conjunto de interfaces para que, en todas las librerías que cumplan el estándar, se registren los mensajes de igual manera. En PSR-3 cada mensaje consta de un texto, que describe la anomalía o evento sucedido, unas variables de contexto y un nivel de importancia. Los niveles de importancia, debug, info, notice, warning, error, critical, alert, emergency, se basan los declarados en el RFC 5424 que describe el formato de los mensajes de log empleado por grandes sistemas operativos como Linux.

El Mensaje

El mensaje es el texto que se almacena en el fichero, base de datos o el soporte que se crea necesario y describe la acción o evento sucedido. Todos los métodos que implementan la interfaz propuesta por PSR-3 admiten string u objetos que se puedan convertir a string mediante la implementación de la función mágica __tostring(). Las variables de contexto de cada mensaje son un conjunto de pares clave-valor que se pasan como array y cuya clave será buscada en el mensaje y reemplazada con el valor:
//...
$contexto = array('nombreUsuario' => 'Symfony-user');
$this->logger->info('El usuario {nombreUsuario} ha iniciado sesión', $context);
Mediante la interpolación de los valores de contexto, en el mensaje final se tendrá el siguiente texto: El usuario Symfony-user ha iniciado sesión El nombre de cada clave en el mensaje debe ir entre llaves y sin espacios en blanco en el interior. Los caracteres válidos van de a-z, A-Z, _ y el .. Existe una clave especial llamada exception cuya misión es incluir un objeto de tipo Exception que serviría al logger para incluir detalles del error. Los niveles de importancia de cada mensaje los describo de menor a mayor importancia:
  • debug: Información de debug de la aplicación. No usado en entornos de producción.
  • info: Eventos interesantes como el inicio de sesión de usuarios.
  • notice: Eventos normales pero significativos.
  • warning: Ocurrencias excepcionales que no llegan a ser error.
  • error: Errores de ejecución que permiten continuar con la ejecución de la aplicación pero que deben ser monitorizados.
  • critical: Situaciones importantes donde se generan excepciones no esperadas o no hay disponible un componente.
  • alert: Se deben tomar medidas inmediatamente. Se da en situaciones como la caída completa de la web, base de datos no disponible etc... En este caso, se suelen enviar mensajes por email.
  • emergency: Es el error más grave e indica que todo el sistema está inutilizable.
Las funciones que un logger debería de implementar tienen el siguiente aspecto:
    public function emergency($message, array $context = array());
    public function alert($message, array $context = array());
    public function critical($message, array $context = array());
    public function error($message, array $context = array());
    public function warning($message, array $context = array());
    public function notice($message, array $context = array());
    public function info($message, array $context = array());

    public function debug($message, array $context = array());

    /**
     * Esta es la función a la que llaman todas las anteriores
     */
    public function log($level, $message, array $context = array());

Críticas al estándar

Existen algunos autores como Stuart Herbert’s que indican que los nombre de los métodos deberían empezar por un verbo para tener mejor legibilidad. Sería usar $this->log->logEmergency(...) en lugar de $this->log->emergency(...). Además, la inclusión de las excepciones en una clave especial llamada exception no suena bien. Sería mejor pasarla como un parámetro opcional y no tener que distinguir este caso en la implementación del logger.   Github: Documentación PSR-3

Comments

comments powered by Disqus