viernes, 27 de noviembre de 2009

Configuración de Log4j en una aplicación web

Log4j es una librería que permite guardar registros informativos sobre el funcionamiento de una aplicación. En este artículo vamos a ver cómo configurar Log4j para su uso en una aplicación web.

En primer lugar vamos a crear en Eclipse un proyecto war Maven que se llame PruebaLog4jWeb. Crearemos también una página de inicio index.jsp y desplegaremos la aplicación en un servidor. La URL de la aplicación será http://localhost:8080/PruebaLog4jWeb/.

Añadimos la dependencia a la API de servlets para poder trabajar en nuestro proyecto con sus clases. Esta librería no hace falta desplegarla en el servidor, puesto que éste tendrá su propia implementación de esta API:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>

Añadimos la dependencia a Log4j en el pom.xml del proyecto:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
</dependency>

Ahora vamos a crear el siguiente servlet:
package com.roldan.log4j;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

public class ServletPrueba extends HttpServlet {

private static final long serialVersionUID = 1L;

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

public ServletPrueba() { }

protected void doGet(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

logger.debug("Se ha llamado al servlet mediante un GET.");

execute(request, response);
}

protected void doPost(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

logger.debug("Se ha llamado al servlet mediante un POST.");

execute(request, response);
}

protected void execute(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

logger.info("Se redirige a la página de inicio.");

RequestDispatcher rd =
request.getRequestDispatcher("index.jsp");
rd.forward(request, response);
}
}

En él hemos creado un logger estático de Log4j que usamos en los distintos métodos del servlet para mostrar logs con distinto grado de importancia.

Para configurar la salida de los logs tenemos que crear un archivo log4j.properties, donde definiremos cómo queremos que se muestren los logs. Vamos a mostrar los logs de nuestra aplicación tanto por consola como en un archivo:
log4j.logger.com.roldan.log4j=debug, stdout, file

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=example.log

log4j.appender.file.MaxFileSize=100KB
# Keep one backup file
log4j.appender.file.MaxBackupIndex=1

log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%p %t %c - %m%n

Por último, debemos inicializar Log4j dentro de cada aplicación web, para que cada aplicación pueda trabajar satisfactoriamente de modo independiente. Para ello, vamos a incluir en la aplicación el siguiente servlet de inicialización:
package com.roldan.log4j;

import org.apache.log4j.PropertyConfigurator;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Log4jInit extends HttpServlet {

public void init() {
String prefix = getServletContext().getRealPath("/");
String file = getInitParameter("log4j-init-file");

if(file != null) {
PropertyConfigurator.configure(prefix+file);
}
}

public void doGet(HttpServletRequest req, HttpServletResponse res) {}
}

E incluiremos la siguiente configuración en el archivo web.xml:
<servlet>
<servlet-name>log4j-init</servlet-name>
<servlet-class>com.roldan.log4j.Log4jInit</servlet-class>
<init-param>
<param-name>log4j-init-file</param-name>
<param-value>WEB-INF/log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

Cuando redesplegamos y ejecutamos la aplicación llamando al servlet mediante la URL http://localhost:8080/PruebaLog4jWeb/ServletPrueba se muestran los siguientes logs en la consola:
DEBUG [http-8080-2] (ServletPrueba.java:23) 
- Se ha llamado al servlet mediante un GET.
INFO [http-8080-2] (ServletPrueba.java:39)
- Se redirige a la página de inicio.

Referencias:
http://logging.apache.org/log4j/1.2/index.html
http://logging.apache.org/log4j/1.2/manual.html

3 comentarios:

  1. Buenas Jorge,

    Sobre el Conversion Pattern añadiría el modificador %d al inicio para que me mostrase la fecha y hora del mensaje y en lugar %p pondría %-5p para que de esta forma los mensajes me saliesen alineados.

    Pequeñas manías :-)

    ResponderEliminar
  2. Todo eso ya, a gusto del consumidor... ;-)

    ResponderEliminar