Log4J: Cómo crear un log que trabaje hacia una Base de Datos.
Como utilizar JDBCAppender con MySql
Este tutorial pretende ser un ejemplo sencillo de como podemos dirigir el log4j de apache hacia un MySql. Dejaremos en una Base de Datos , trazas de la ejecución de una aplicación Web. Me pasé un día intentando encontrar un ejemplo sencillo. He pensado que podría ser util añadir uno como este.
Tiene el minimo número de elementos que lo hacian funcionar pero también se ha pretendido que no fuera un puro engendro. Es una simplisima aplicación Web
Haremos dos cosas. crearemos el projecto Java, nuestra aplicación y por otro lado haremos el Esquema y la tabla en un MySql.
Se da por supuesto que tenemos un servidor MySql instalado y corriendo. Tambíén hemos de tener un Apache-tomcat instalado que pueda servir nuestra futura aplicación.,aunque no es necesario que esté corriendo. Tomcat será el contenedor Web de nuestro Servlet(index.jsp).
Los objetos a construir son los siguientes:(con Eclipse las lineas a tirar, no llegan a veinte)
Crear una aplicacion Java WEB ,Dynamic Web Project.
Una clase "Entidad.java" con dos log (6 lineas)
:Un jsp "index.jsp", que utilice la Entidad (3 lineas)
:
Un listener "Escuchador.java" , que llame al DOMConfigurator que cargará la configuracion de log4j (1 linea)
:Crear un archivo xml "log4jConfig.xml", que contenga la configuración del log4j (11 lineas)
:Dentro de lib las librerias de log4j-1.2.15.jar y mysql-connector-java-5.1.6-bin.jar
:Crear un Schema en MySql y una tabla para los logs. Trabajamos con el QueryBrowser de MySql
:
- 1 – Crear una aplicacion Dynamic Web Project:
- 2 – Creamos en es.mad.tutorial una clase «Entidad» con dos loggeos
- 3 – Creamos en WebContent la vista que utilice la Entidad. La llamaremos «index.jsp» :
Crearemos una aplicación que se llame "ApacheLog4jMysql". Un paquete es.mad.tutorial
para poder hacer siguiente el import debemos tener la librerÃa log4j-1.2.15.jar en "WebContent/WEB-INF/lib".
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import org.apache.log4j.Logger; public class Entidad { //Crea un objeto Logger al cargar la clase. private static Logger log = Logger.getLogger(Entidad.class); public Entidad() throws Exception{ log.info("un mensaje desde el constructor" ); } public void ejecutar(){ int i = 6; log.info("un mensaje desde ejecutar "+i); } } |
La vista ademas tendrá un link que la redirigirá hacia ella misma
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@page import="es.mad.tutorial.*" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> </head> <body> <% Entidad instanciaEntidad = new Entidad(); instanciaEntidad.ejecutar(); %> <li><strong><A href="<%=request.getContextPath()%>" >RECARGAR PAGINA</a></strong></li></UL> </body> </html> |
En la linea DOMConfigurator cargamos el archivo de configuración log4jConfig.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package es.mad.tutorial; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.log4j.xml.DOMConfigurator; public class Escuchador implements ServletContextListener { public void contextInitialized(ServletContextEvent arg0) { DOMConfigurator.configure(Escuchador.class.getClassLoader().getResource("/es/mad/tutorial/log4jConfig.xml")); } public void contextDestroyed(ServletContextEvent arg0) { } } |
Esto merece una cierto detenimiento. El param name="driver" tiene como valor el protocolo de comunicación con la BBDD. En nuestro caso MySql.
El param URL nos indica la direccion de la BBDD y del esquema. El user el usuario (root) y la password la contraseña de MySql. En nuestro caso ninguna.
El param sql tiene por valor una oracion MySql que será ejecutada para cada log. Nuestra consulta inserta en el Schema:Log en la tabla:ApacheLog4jMysql sobre los campos:Fecha,Clase,Prioridad y Mensaje los valores: fecha ( %n%d{yyyy-MM-dd HH:mm:ss} ), clase ( %c ), prioridad ( %p ) y mensaje ( %m ) que todo log contiene
Recuerdese que nosotros solo les introdujimos mensaje. La clase, fecha y demas son parametros que podemos pedirles.
En root indicamos dos cosas: el nivel de error que queremos que se registre. Segun sean info,debug,war,error o fatal el nivel minimo deseado.
Por otra parte el appender nos indica con que tipo de log4j estamos actualmente trabajando. Siempre podemos añadir otros appenders que generen archivos,o conexiones. Nosotros nos conectaremos a una Base de Datos. Por eso JDBCAppender. Si quieres ver otros appenders pincha aqui
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false"> <appender name="CSF_JDBC" class="org.apache.log4j.jdbc.JDBCAppender"> <param name="driver" value="com.mysql.jdbc.Driver"/> <param name="URL" value="jdbc:mysql://localhost:3306/Log?autoReconnect=true"/> <param name="user" value="root"/> <param name="password" value=""/> <param name="sql" value="INSERT INTO Log.ApacheLog4jMysql (Fecha,Clase,Prioridad,Mensaje) VALUES ( '%n%d{yyyy-MM-dd HH:mm:ss}','%c','%p','%m ')"/> </appender> <root> <priority value="info"/> <appender-ref ref="CSF_JDBC"/> </root> </log4j:configuration> |
La aplicación esta lista.
****** INSERT INTO Log.ApacheLog4jMysql (Fecha,Clase,Prioridad,Mensaje) VALUES ( '%n%d{yyyy-MM-dd HH:mm:ss}','%c','%p','%m ')" ******
Creamos un Schema que se llame «Log» y dentro haremos una tabla «ApacheLog4jMysql» con los campos:
*******INSERT INTO Log.ApacheLog4jMysql (Fecha,Clase,Prioridad,Mensaje) VALUES ( '%n%d{yyyy-MM-dd HH:mm:ss}','%c','%p','%m ')"******
Con los tipos DateTime el primero, y Varchar(55) el resto,
Accion
Tras todo esto nos aseguramos que el servidor MySql siga arrancado. Arrancamos nuestra aplicación en el servidor Tomcat (si trabajamos con eclipse el lo hara comodamente por nosotros)
En ese momento la aplicación ApacheLog4jMysql se carga. El listener «Escuchador» se inicializa y cargará el DOMConfigurator. Este obtendrá la configuración del archivo que se le pase. En nuestro caso, log4jConfig.xml.(Cuando nuestro archivo de configuración sea del tipo clave valor ,y no un xml, trabajaremos con el PropertiesConfigurator en vez del DOM.)
1 2 3 |
public void contextInitialized(ServletContextEvent arg0) { DOMConfigurator.configure(Escuchador.class.getClassLoader().getResource("/es/mad/tutorial/log4jConfig.xml")); } |
Los logs están esperando que alguien los llame. Carguemos en el navegador «localhost:8080/ApacheLog4jMysql». Hemos de ver el enlace «RECARGAR PAGINA».La pagina ya se ha cargado. Pero si pinchamos sobre el enlace la vista index.jsp se recargará otra vez, ya qué elenlace apunta hacia sí mismo:
1 |
<A href="<%=request.getContextPath()%>" >RECARGAR PAGINA</a> |
Cada vez que lo haga creará un objeto de la clase «Entidad» y le pasará un método. Estos crearán los logs.
1 2 |
<% Entidad instanciaEntidad = new Entidad(); instanciaEntidad.ejecutar(); %> |
1 2 3 4 |
public Entidad() throws Exception{ log.info("un mensaje desde el constructor" ); } |
1 2 3 4 |
public void ejecutar(){ int i = 6; log.info("un mensaje desde ejecutar "+i); } |
listo!
Los logs se activan y van a parar a la Base de Datos que le hemos indicado. En mi caso yo tengo un campo id en la tabla. Manias.
Id | Fecha | Clase | Prioridad | Mensaje | 110 | 2008-12-27 20:26:42 | es.mad.tutorial.Entidad | INFO | un mensaje desde el constructor |
---|---|---|---|---|
111 | 2008-12-27 20:26:42 | es.mad.tutorial.Entidad | INFO | un mensaje desde ejecutar 6 |
112 | 2008-12-27 20:26:43 | es.mad.tutorial.Entidad | INFO | un mensaje desde el constructor |
113 | 2008-12-27 20:26:43 | es.mad.tutorial.Entidad | INFO | un mensaje desde ejecutar 6 |
114 | 2008-12-27 20:26:44 | es.mad.tutorial.Entidad | INFO | un mensaje desde el constructor |
115 | 2008-12-27 20:26:44 | es.mad.tutorial.Entidad | INFO | un mensaje desde ejecutar 6 |
116 | 2008-12-27 20:26:44 | es.mad.tutorial.Entidad | INFO | un mensaje desde el constructor |
117 | 2008-12-27 20:26:44 | es.mad.tutorial.Entidad | INFO | un mensaje desde ejecutar 6 |
118 | 2008-12-27 20:26:44 | es.mad.tutorial.Entidad | INFO | un mensaje desde el constructor |
119 | 2008-12-27 20:26:44 | es.mad.tutorial.Entidad | INFO | un mensaje desde ejecutar 6 |
120 | 2008-12-27 20:46:01 | es.mad.tutorial.Entidad | INFO | un mensaje desde el constructor |
121 | 2008-12-27 20:46:01 | es.mad.tutorial.Entidad | INFO | un mensaje desde ejecutar 6 |
122 | 2008-12-27 20:46:02 | es.mad.tutorial.Entidad | INFO | un mensaje desde el constructor |
123 | 2008-12-27 20:46:02 | es.mad.tutorial.Entidad | INFO | un mensaje desde ejecutar 6 |
124 | 2008-12-27 20:46:02 | es.mad.tutorial.Entidad | INFO | un mensaje desde el constructor |
125 | 2008-12-27 20:46:02 | es.mad.tutorial.Entidad | INFO | un mensaje desde ejecutar 6 |
126 | 2008-12-27 20:46:02 | es.mad.tutorial.Entidad | INFO | un mensaje desde el constructor |
127 | 2008-12-27 20:46:02 | es.mad.tutorial.Entidad | INFO | un mensaje desde ejecutar 6 |
128 | 2008-12-27 20:46:02 | es.mad.tutorial.Entidad | INFO | un mensaje desde el constructor |
129 | 2008-12-27 20:46:02 | es.mad.tutorial.Entidad | INFO | un mensaje desde ejecutar 6 |
130 | 2008-12-27 20:48:17 | es.mad.tutorial.Entidad | INFO | un mensaje desde el constructor |
131 | 2008-12-27 20:48:17 | es.mad.tutorial.Entidad | INFO | un mensaje desde ejecutar 6 |
Espero que la sencillez del ejemplo sirva para ver mejor como trabaja log4j de Apache.
Un saludo.
Francisco López-Sancho Abraham
Francisco, e implementado el codigo pero no me sirvio, podrias dejar un link de descarga del codigo, y no se como va la estructura de Entidad,Escuchar y el archivo xml..