jueves, 26 de abril de 2012

Librerías de logging para Java (slf4j, log4j, java.util.logging, logback, MentaLog)

Java
Prácticamente toda aplicación incluye un sistema para emitir trazas con información relevate de lo que está realizando a un fichero o a la salida estándar. Dependiendo de la información y detalle de la misma esta puede ser muy útil para determinar la causa de un posible fallo o algún mal funcionamiento de la aplicación ya que el log es un registro no solo de la excepción producida sino también de su contexto con las acciones anteriores realizadas. También puede servir para monitorizar en tiempo real las acciones que está llevando a cabo el sistema que de otra forma no podríamos realizar o sería utilizando herramientas más complejas.

slf4j
Generar trazas en una aplicación es muy barato y simple comparado con la información que puede proporcionar, su utilidad y tiempo que puede ahorrar a la hora de descubrir problemas. Básicamente, las trazas que queremos generar las insertamos dentro del propio código de la aplicación que están compuestas del mensaje que queremos emitir, el nivel de la traza y la categoría a la misma. El mensaje puede ser cualquier cadena que queramos que creamos que nos puede ser útil pudiendo contener datos procedentes de variables o cualquier otra cosa de la que pueda disponer el programa. Los niveles de las trazas en muchos sistemas son las siguientes por orden de relevancia de mayor a menor: fatal, error, warn, info, debug. Estos niveles de las trazas nos pemitirán utilizalos posteriormente para en tiempo de ejecución y mendiante la configuración del sistema de logging filtrar las mismas por el nivel que queramos pudiendo obtener únicamente las trazas de nivel warn o superior. Las categorías representan la pieza dentro de nuestro sistema que emite la traza que también podremos utilizar para filtrar los mensajes que queramos. Por supuesto, podremos utilizar las combinaciones de nivel y categoría que queramos teniendo en nuestras manos un sistema muy flexible para obtener la información que queramos y que genere la aplicación.

Veamos un pequeño programa para hacernos una idea de que es todo esto:

package es.com.blogspot.elblogdepicodev.slf4j;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
  public static void main(String[] args) {
    // logger es un referncia a la categoria
    Logger logger = LoggerFactory.getLogger(getClass().getName());
    // debug es el nivel de la traza
    // Hello world! es el mensaje que se emite
    logger.debug("Hello world!");
  }
}

Como normalmente ocurre en el mundo del software libre y de código abierto y muchas veces en java hay más de una librería a nuestra disposición para cada funcionalidad que queramos incorporar en una aplicción. En el caso del sistema de trazas por supuesto esto no es menos. Dos de las más conocidas son log4j y la propia que incorpora el JDK de Java, java.util.logging. Aunque ambas librerías/api son prácticamente iguales salvo por llamar de forma diferente a los mismos conceptos normalmete la elección se decanta por log4j por ser más flexible y poseer algunas más opciones más (log4j vs java.util.logging). Salvo que no queramos o no podamos añadir una nueva dependencia a nuestro proyecto posiblemente elijamos log4j u otra como logback.

Logback es otra librería para logging denominandose a si misma la sucesora de log4j y siendo sus autores los mismos, con lo que han plasmado en esta nueva librería la experiencia aprendida en log4j. Hay varias razones por las que podríamos querer usar logback en vez de log4j, entre ellas es más rápido (según dicen ellos unas 10 veces más rápido), configuración usando Groovy, recarga automática de la configuración, compresión y eliminación automática de archivos históricos y trazas con información de empaquetado entre otras.

El ejemplo de código anterior hace uso de otra librería llamada slf4j que permite abstraernos de la libreria que decidamos utilizar ya sea lof4j, java.util.logging o logback. Usando slf4j si posteriormente queremos cambiar de una librería a otra será tan fácil como realizar un nuevo archivo de configuración y sustituir su jar por el de la otra librería, no tendremos que tocar ninguna linea de nuestro código. Por tanto podemos tener las siguientes combinaciones:
  • slf4j + log4j
  • slf4j + java.util.logging
  • slf4j + logback
Posibles bindings para slf4j
Como se puede ver en la imagen logback no necesita un adaptador que penaliza el rendimiento como en el caso de log4j o java.util.logging.

Por si estas opciones no fueran suficientes existen más, otra con interesantes características es MentaLog. Por citar algunas de sus propiedades:
  • Configuración programática (sin archivos de configuración)
  • Mejor rendimiento incluso por encima de logback
  • Varargs y placeholders en los métodos de logging
  • Sin reserva de memoria y por tanto sin sobrecarga para el garbage collector
  • Soporta colores para la consola
  • Los loggers son enumerados
Tenemos a nuestra disposición varias posibilidades y si tenemos la posibilidad de elegir quizás una opción recomendable sea la combinación slf4j + logback, ya que con ella siempre podremos pasar a utilizar cualquiera de log4j, java.util.logging o logback de forma sencilla y sin ningún cambio en el código. Y aunque MentaLog parece que no tiene todas las opciones de la anterior combinación si cumple con nuestras necesidades tambien sea otra opción a considerar por sus características.


Referencia:
Logging usando marcadores con slf4j y logback
http://logging.apache.org/log4j/1.2/
http://docs.oracle.com/javase/7/docs/api/java/util/logging/package-summary.html
http://logback.qos.ch/
http://logback.qos.ch/reasonsToSwitch.html
http://mentalog.soliveirajr.com/posts/list/26.page