Log4J: Tutorial y configuración rápida


  1. ¿Qué es Log4J?.
  2. Configuración básica por defecto.
  3. Niveles de Log o Traza.
  4. Obtener Loggers.
  5. Fichero de configuración.
  6. Appenders.
  7. Cargar fichero log4j.properties.
  8. Additivity – Additividad.

  • ¿Qué es Log4J?:

Log4j es una librería adicional de java que permite a nuestra aplicación mostrar mensajes de información de lo que está sucediendo en ella, lo que habitualmente se conoce como un log. Tiene la ventaja de ser dinámico y, por tanto, configurable.

Esta librería fue creada por Apache, y podemos descargarla desde aquí.

  • Configuración básica por defecto:

Una de las ventajas de Log4j es que es configurable a través de un fichero, pero lo dejamos para más adelante. Vamos a ver ahora la configuración por defecto. Para ello, basta poner lo siguiente en nuestro código:

Esto sacará por la salida estándar (la pantalla habitualmente), en caso de ser un Warning, algo como:

Los objetos que invoca una aplicación para generar log se denominan “loggers” y son de la clase Logger. Para obtener un Logger debemos pedírselo a la clase Logger de log4j por un nombre. De esta forma, log4j creará un Logger con ese nombre si no existe ya, o nos devolverá el existente si ya lo tiene creado. El código sería:

Donde el texto “Logger de Ejemplo” es cualquier texto que queramos.

  • Niveles de Log o Traza:

Una vez obtenido el Logger y guardado en la variable log, podemos sacar varios tipos de mensajes según su importancia. Los nieveles posibles de Traza son:

Traza Explicación Ejemplo
trace() El menos importante, que se suele usar en la fase de desarrollo. Es el típico System.out.println(“paso por aquí”).
debug() Información útil para depurar. Algún resultado parcial, el valor de alguna variable, etc.
info() Información sobre la aplicación que pueden tener cierto interés para ser mostrados en el log. Se establece una conexión con base de datos, se conecta un cliente a nuestro servidor, un usuario entra en sesión, se guarda la sesión en base de datos, etc.
warn() Advertencias o fallos sin importancia para la ejecución del programa. Un usuario introduce una contraseña errónea, un fichero de configuración no existe y la aplicación coge la configuración por defecto que se establezca en el código, etc.
error() Errores importantes, pero que no obligan a terminar la aplicación. No se puede conectar a la base de datos pero hay ciertas funcionalidades que sí pueden seguir ofreciéndose, aun sin base de datos.
fatal() Errores que obligan a terminar la aplicación. Se acaba la memoria disponible.

Usando los métodos al efecto:

Un pequeño código de ejemplo sería el siguiente:

Y su salida sería algo como:

  • Obtener Loggers:

Lo habitual es obtener un Logger para cada clase. Además, no tiene sentido obtener el Logger cada vez que lo necesitemos, por eso suele guardarse el Logger en un atributo privado, final y estático (private final static) de la clase:

¿Por qué se hace así?. Al tener un Logger para cada clase, luego log4j nos permite configurar cada Logger de forma distinta, por lo que la salida de cada clase podría tener un formato distinto, ir a distinto sitio (ficheros distintos, pantalla) o incluso no salir el log de unas clases y sí el de otras.

  • Fichero de configuración:

Lo habitual es meter esta configuración en un fichero de propiedades o un fichero XML y cargar dicha configuración desde nuestro programa, y no como hemos visto hasta ahora, que teníamos la configuración básica.

Por tanto, creamos un fichero log4j.properties (o el nombre que queramos) con el siguiente contenido:

Primero, debemos decir para cada Logger que vayamos a usar dos cosas: a partir de qué nivel de errores queremos que se muestren y cómo queremos que se muestren. Para ello, ponemos una línea así:

Lo de log4j es fijo. Luego podemos poner logger si queremos hacer referencia a un Logger concreto de los que usemos en el programa, o bien rootCategory si queremos hacer referencia a todos los Logger del programa. En el ejemplo, hemos puesto log4j.logger y a continuación el nombre del Logger. En nuestro caso, el nombre completo era “com.jias.ejemplo.EjemploLog4j”, pero como indicamos anteriormente, podemos “cortar” el nombre en cualquiera de los puntos de separación y así afectará a todos los Logger de las clases cuyo paquete empiece por “com.jias”. Es decir, podemos crear una jerarquía de logs, afectando así y teniendo la misma configuración los paquetes hijos de aquel que se especifica.

Tras el igual, indicamos el nivel a partir del cual queremos que se visualicen los mensajes. Si ponemos ALL, se visualizarán todos. Si ponemos, por ejemplo, WARN, sólo se verán los mensajes de warn() y los más importantes a WARN, que son error() y fatal(). Finalmente, CONSOLA podrá llevar el nombre que queramos, y hace referencia a un dónde y cómo escribir dichos mensajes. Debemos, por tanto, definir CONSOLA más adelante en el fichero:

El formato del ConversionPattern podemos verlo explicado aquí.

  • Appenders:

Cada Logger tiene asociado uno o más “appenders” o “canales de salida” del log. Si observamos el inicio del archivo de configuración veremos que hay dos “appenders” definidos a nuestra disposición, con nombres auto-descriptivos:

Podrían ser más, siendo sólo uno imprescindible. Cada “appender” apunta a una clase proporcionada por Log4j que define su comportamiento. Para nuestro caso:

Cada tipo de “appender” tiene parámetros complementarios que requieren consultar su documentación (por ejemplo, el FileAppender require el nombre del archivo de destino). Sin embargo, todos soportan la configuración de su “layout” el cual determina qué información y en qué formato es impresa o grabada. En la mayoría de casos se emplea con este fin el “org.apache.log4j.PatternLayout” que a su vez permite especificar un formato mediante su opción “ConversionPattern“.

¿Y qué hay si queremos sobreescribir el fichero de log generado (“prueba.log” en el ejemplo anterior) en lugar de ir añadiendo la información de cada ejecución?. También es posible indicarlo, tanto como por el fichero de configuración:

como por código Java:

Este “false” que aparecen en ambos casos, indica que no queremos que se haga el append, sino que en su lugar, se reemplazará completamente el fichero.

  • Cargar fichero log4j.properties:

La carga se hace con la clase PropertyConfigurator, llamando al método configure() y pasando como parámetro el nombre del fichero con su path:

Fuentes:
Chuwiki.
Americati.
Softuses.