Sie sind auf Seite 1von 15

Logs para java (log4j).

1.- Niveles de las trazas. _________________________________ 2


2.- Recomendaciones de uso de los tipos de trazas. ___________ 3
3.- Configuración. ______________________________________ 4
3.1.- Básica. ______________________________________________ 4
3.2.- Avanzada. ___________________________________________ 7
4.- Trazas en ficheros.__________________________________ 10
5.- Supervisando trazas con Chainsaw.____________________ 11
6.- Referencias. _______________________________________ 13
log4j con ejemplos.

En este monográfico vamos a procurar explicar cómo podemos registrar


las trazas o logs en nuestra aplicación con un API muy popular y gratuito
como es log4j. Dicho API es de código abierto y ha sido implementado
por Apache. Esta disponible en la siguiente URL:
http://logging.apache.org/index.html

Todos los experimentos en este texto se han realizado con la versión


1.2.15 de log4j y con la versión 1.6 de Java.
Todos los ejemplos se pueden descargar en esta URL:
http://www.descarga.criado.org/. Seleccione la opción
“PUBLICACIONES”, el login de acceso es “log4j” y el password es
“27072009”. El monográfico es gratuito y no tiene usted ningún
compromiso, sin embargo le agradecería mucho que una vez leído, me
enviara una valoración (lcriadof@yahoo.es).

1
(c) 2009 Luis Criado Fernández

1.- Niveles de las trazas.

Este API ofrece varios niveles (prioridades diferentes) de logs o trazas,


aunque en muchos libros se ofrece una clasificación lineal de mayor a
menor o viceversa, desde nuestro punto de vista, estas clasificaciones no
son suficientemente claras para el programador, ya que hay ciertos niveles
que incluyen al anterior, pero no se cumple en todos.

Nosotros hemos comprobado experimentalmente que estos niveles


pueden clasificarse en dos categorías: Los niveles de errores y los niveles
de uso para el programador.

Lo que hay que tener claro es que los niveles de errores se incluyen
siempre en cualquier nivel de uso para el programador y que estos niveles
de error obedecen la siguiente prioridad:

• El nivel FATAL no incluye ninguno más.


• El nivel ERROR incluye FATAL.
• El nivel WARN incluye ERROR y FATAL.

Los niveles de uso del programador son los siguientes:

• El nivel INFO incluye WARN, ERROR y FATAL.


• El nivel DEBUG incluye INFO, WARN, ERROR y FATAL.
• El nivel TRACE incluye DEBUG, INFO, WARN, ERROR y
FATAL.

2
log4j con ejemplos.

2.- Recomendaciones de uso de los tipos de trazas.


Anteriormente hemos hablado de niveles o prioridades, ahora nos
referimos a los tipos de trazas, que siguen siendo los seis anteriores, es
decir; TRACE, DEBUG, INFO, WARN, ERROR y FATAL.
Cada uno de ellos tiene asociado un método de la clase “logger” que
permite generar un determinado tipo de traza.
De forma que las trazas de tipo WARN se generan con el método
“warn()”, donde detallaremos fallos que se pueden recuperar fácilmente.
El tipo ERROR (método error() ), se puede reservar para problemas
importantes, pero que no obligan a terminar la aplicación, por ejemplo, no
se puede conectar con la base de datos, aunque hay otras funcionalidades
que sí pueden seguir ofreciéndose, aun sin base de datos. Finalmente el
método fatal() se debe dedicar para errores que obligan a terminar la
aplicación.

En cuanto a los métodos que nos permiten generar logs de desarrollo,


conviene reservar el método info() para señalar algo relevante en el
seguimiento de la ejecución de un programa, de forma, que la activación
del nivel INFO, no genere exceso de logs y que podamos activar este
nivel en producción. De manera, que podemos indicar aquí cuestiones
como por ejemplo, establecer una conexión con base de datos, iniciar una
sesión de un usuario, etc.

Los dos niveles restantes; TRACE y DEBUG, suelen contener


demasiados detalles de la ejecución del programa, de forma que es
habitual usarlos sólo en entornos de desarrollo y/o pruebas. El método
trace() puede usarse para indicar al programador por donde pasa la
ejecución del programa, mientras que debug() se puede dedicar a indicar
valores de variables.

3
(c) 2009 Luis Criado Fernández

3.- Configuración.

Para usar log4j añadimos en la cabecera de nuestro código la siguiente


línea:
import org.apache.log4j.*;

Luego, y esto es muy importante, hay que declarar como atributo de clase
estática un objeto de tipo “Logger” perteneciente a log4j. Este objeto
tiene que hacer referencia al nombre de la clase de la que queremos
obtener trazas. Por ejemplo, si nuestra clase se llama “coordenadas”
realizaremos la siguiente declaración:

static Logger logger = Logger.getLogger(coordenadas.class);

Si no queremos complicarnos la vida, podemos utilizar una configuración


por defecto, que hemos llamado básica. Sin embargo, log4j proporciona
gran flexibilidad en el manejo de logs mediante ficheros de configuración,
que detallamos en el epígrafe “3.2.- Avanzada”.

3.1.- Básica.
En esta configuración básica, antes de usar cualquier método de la clase
“logger”, hay que escribir esta línea de código:

BasicConfigurator.configure();

Obsérvese el código fuente del ejemplo1.java (Figura 1),

4
log4j con ejemplos.

Figura 1: Ejemplo1.java

La línea 3: Es el paquete de las clases log4j.


La línea 10: Define una variable estática de la clase “Logger”
La línea 17: Activa la configuración básica.
De las líneas 19 a 24: Son ejemplos con los diferentes tipos de trazas.

Hemos creado un programa de prueba para probar esta clase (Figura 2)


que simplemente invoca la clase “Ejemplo1.java”. La compilación es
simplemente así:

javac -cp .\;.\log4j-1.2.15.jar ejemplo1.java


javac -cp .\; prueba.java

Para ejecutar, escribimos:


java -cp .\;.\log4j-1.2.15.jar prueba

5
(c) 2009 Luis Criado Fernández

Figura 2: prueba.java

Al ejecutar (Figura 3) se observa que se muestra en pantalla todos los


tipos de logs.

Figura 3: Ejecución prueba con Ejemplo 1

6
log4j con ejemplos.

3.2.- Avanzada.
El uso de ficheros de propiedades, nos permite realizar configuraciones
más avanzadas y flexibles. En este epígrafe damos una muestra de esta
configuración adaptada a mensajes de consola, posteriormente veremos
como es posible canalizar los logs a ficheros e incluso la monitorización
de los mismos con una herramienta llamada Chainsaw que se comunica
mediante un puerto TCP.

En esta configuración, antes de usar cualquier método de la clase


“logger”, hay que escribir esta línea de código:
PropertyConfigurator.configure( "log4j.properties");

El parámetro de que pasa indica el fichero de configuración. Obsérvese el


código fuente del ejemplo2.java (Figura 4), que como en el caso anterior
“básico” mantiene las mismas definiciones, sólo cambia la línea 17, que
hace referencia al fichero de propiedades “log4j.properties” donde hemos
guardado nuestra configuración.

7
(c) 2009 Luis Criado Fernández

Figura 4: Ejemplo2.java
Esta primera versión de fichero “log4j.properties” contiene lo siguiente:

El primer parámetro de la propiedad “log4j.rootLogger” indica que


niveles de error están activos. Esta propiedad aplica restrictivamente a
cualquier otra propiedad de cualquier otro “appender”, que es la clase
encargada de dar formato al mensaje y enviarlo a consola, fichero, etc.
Normalmente se suelen activar todos los niveles y luego restringir al nivel
deseado en cada “Aprender”, de manera que adicionalmente a los seis
niveles vistos con anterioridad, en los ficheros de propiedades se dispone
también de dos más, estos son:
• ALL: Habilita todos los logs.
• OFF: Deshabilita todos los logs
Los siguientes parámetros activan los appenders definidos, en este
ejemplo sencillo hemos definido únicamente “consola”. De forma que la
primera línea de nuestro fichero de propiedades será la siguiente:

log4j.rootLogger=ALL, consola

8
log4j con ejemplos.

Una vez definida, podremos especificar un conjunto de propiedades para


consola. Todas las propiedades de este “appender” comenzarán por
“log4j.appender.consola”.

Figura 5: fichero log4j.properties

En la línea 8 se especifica el nivel INFO, lo que implica mostrar mensajes


de INFO, WARN, ERROR y FATAL, tal y como vimos en el epígrafe 1
de este monográfico.

La línea 11 sirve para enviar los mensajes a consola,. En la línea 14


forzamos a actualizar los logs de forma inmediata. Las líneas 17 y 19
definen el formato del mensaje, es muy interesante conocer un poco
mejor los patrones que maneja la propiedad “ConversionPattern”, ya que
proporciona gran flexibilidad, estos son algunos de ellos:

• %F: Nombre del fichero.


• %l: Número de línea.
• %d{ISO8601}: Fecha en el estándar ISO 8601 (2003-01-12
17:26:30,234)
• %r: Milisegundos desde que comenzó el programa
• %t: Hilo que llamo al Logger.
En los ejemplos 1 y 2, la línea 10 especifica nuestra clase de manera
implícita. Pero es más cómodo utilizar esta otra línea de código genérica.

9
(c) 2009 Luis Criado Fernández

De esta forma nos olvidamos de particularizarlo en los diferentes ficheros


de nuestro programa:
Logger logger = Logger.getLogger(this.getClass());

También conviene utilizar un directorio para los ficheros de


configuración, de forma que el fichero properties (línea 16) sería mejor
guardarlo en el directorio relativo ./conf:
PropertyConfigurator.configure( "./conf/log4jFichero.properties");

4.- Trazas en ficheros.


Vamos a añadir a nuestra configuración la posibilidad de guardar las trazas
en un fichero, pero claro, el fichero puede crecer indefinidamente
ejecución tras ejecución. Por lo tanto, conviene limitar su tamaño y
conservar los últimos logs. Afortunadamente esto se puede hacer.

Figura 6: fichero ./conf/log4jFichero.properties

En la Figura 6 hemos definimos un appender llamado fichero, de forma


que la cabecera de nuestro properties será:
log4j.rootLogger=ALL, fichero

La declaración de la línea 4 sirve para enviar los mensajes a fichero:


El formato del mensaje, se define con la propiedad “ConversionPattern”
(lineas 13 y 14) al igual que hicimos en el ejemplo por consola. También
activamos la propiedad “ImmediateFlush” y “Append” (líneas 11 y 12).

10
log4j con ejemplos.

La propiedad “File” (línea 7) define el camino y el nombre del fichero de


logs. La propiedad “MaxFileSize” (línea 8) el tamaño y
“MaxBackupIndex” (línea 9) el número de ficheros de backup.
En este ejemplo, se ha definido como nombre del fichero “trazas.log” con
un tamaño máximo de 10 Mbytes y tres ficheros de backup. Lo que
significa que cuando el fichero “trazas.log” alcance los 10 Mbytes, se
renombra como “trazas.log.1” y así hasta mantener 3 backups, es decir,
conservaremos 40 Mbytes de logs distribuidos en cuatro ficheros
“trazas.log”, “trazas.log.1”, “trazas.log.2” y “trazas.log.3”. Las trazas más
antiguas se irán sustituyendo por lo más nuevo. De forma, que las trazas
más actuales estarán siempre al final del fichero “trazas.log”.
Para probar esto ejecute el ejempo3.java

5.- Supervisando trazas con Chainsaw.

Esta versión de log4j incluye también un monitorizador gráfico de logs

Figura 7: Supervisando logs con ChainSaw

11
(c) 2009 Luis Criado Fernández

Para lanzar esta herramienta ejecute lo siguiente:

java -cp .\;.\log4j-1.2.15.jar org.apache.log4j.chainsaw.Main

La configuración del fichero “log4jChainsaw.properties” (Figura 8)


contiene dos appenders: fichero y chainsaw.

La configuración del appender “fichero” es la misma que se ha definido


en ./conf/log4jFichero.properties.

Figura 8: ./conf/log4jChainsaw.properties

Respecto a la configuración del appender “Chainsaw” hay que matizar que


en línea 18 se canaliza el mensaje vía socket. El atributo remoteHost (línea
19) especifica la IP y el puerto se especifica mediante el atributo “port”
(línea 20) que por defecto, la herramienta gráfica escucha en el 4445.
Para probar esto ejecute el ejempo4.java

12
log4j con ejemplos.

6.- Referencias.

http://www.chuidiang.com/chuwiki/index.php?title=Ejemplo_con_log4j
http://www.manual-java.com/codigos-java/sistema-trazas.html
http://www.proactiva-calidad.com/java/herramientas/log4j/index.html

13