Sistema de Log básico

PEDRO DELGADO YARZA 2014/03/06 13:44

En cualquier aplicación Fudneweb 2.0, tenemos por defecto inicializado el sistema de Log ya que Seam crea un objeto Log según los parámetros indicados en el fichero de configuración de log4j (log4j.xml). Este fichero se carga automáticamente siempre que se encuentre dentro del classpath de la aplicación.

Un ejemplo del contenido de este fichero es el siguiente:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
 
    <!-- Definicion de appenders -->
    <appender name="consola" class="org.apache.log4j.ConsoleAppender"> 
        <param name="Target" value="System.out"/> 
        <layout class="org.apache.log4j.PatternLayout"> 
            <param name="ConversionPattern" value="%d{DATE} %5p %c{1}:%L - %m%n"/> 
        </layout> 
    </appender> 
 
	<appender name="fichero-local" class="org.apache.log4j.FileAppender">
        <param name="File" value="./log/prototipo_seam_deploy.log" />
        <param name="Append" value="true" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{DATE} %5p %c{1}:%L - %m%n"/>
        </layout>           
    </appender>
 
    <appender name="fichero-sistemas" class="org.apache.log4j.FileAppender">
        <param name="File" value="/var/httpd/oas10g/logs/prototipo_seam_deploy.log" />
        <param name="Append" value="true" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{DATE} %5p %c{1}:%L - %m%n"/>
        </layout>           
    </appender>
 
    <!-- Fin definicion de appenders -->
 
    <!-- Definicion de niveles de log -->
    <logger name="org.apache">
        <level value="WARN"/>
    </logger>
 
    <logger name="javax.faces">
        <level value="WARN"/>
    </logger>
 
    <logger name="org.ajax4jsf">
        <level value="WARN"/>
    </logger>
 
    <logger name="org.richfaces">
        <level value="WARN"/>
    </logger>
 
    <logger name="org.jboss">
        <level value="WARN"/> 
    </logger>
 
    <logger name="org.jboss.seam">
        <level value="WARN"/> 
    </logger>
 
	 <logger name="org.jboss.ejb3">
		<level value="WARN"/>
	</logger>
 
   <logger name="org.jboss.kernel">
      <level value="WARN"/>
   </logger>
 
	<logger name="org.hibernate">
        <level value="WARN"/> 
    </logger>
 
	<logger name="org.quartz.simpl">
		<level value="WARN"/> 
	</logger>
    <!-- Fin definicion de niveles de log -->
 
    <!-- Configuracion despliege -->
    <root> 
        <priority value="DEBUG" />
        <appender-ref ref="consola" />
        <appender-ref ref="fichero-local" />  
    </root>
    <!-- Fin configuracion despliege -->   
 
 
</log4j:configuration>

Como podemos ver en este ejemplo, el fichero está estructurado en varias secciones que comentamos a continuación:

  • Definición de appenders: Un appender es la definición de un generador de log, podemos especificarle el formato que queramos que tenga el log y un conjunto de parámetros de configuración según queramos que se comporte. En esta primera sección definiremos las posibles salidas de las trazas de log que genere nuestra aplicación. En nuestro caso hemos definido las tres siguientes:
    • Conosola: Esta primera salida es para poder ver los mensajes de error por la consola del sistema. Para ello fijamos con el parámetro Target que la salida de ese log va a la salida normal del sistema System.out.
    • Fichero local: Esta salida se configura para que el log de nuestra aplicación vaya a un fichero local, para ello usamos el parámetro File especificándole la ruta destino. Añadimos el parámetro append para que vaya añadiendo al fichero, ya que en caso contrario, si paramos y rearrancamos el servidor sobreescribiría los valores del fichero.
    • Fichero de sistemas: Igual que el anterior salvo que la ruta del fichero de log es la ruta que debe tener en el servidor de desarrollo o explotación.
  • Definición de los niveles de log: En esta sección definimos para los diferentes proveedores de log (indicados en la etiqueta <logger name=…) el nivel de log que queremos que se nos muestre. Los niveles posibles son: INFO, DEBUG, WARN, ERROR, FATAL.
  • Configuración de despliege: Una vez definidos todos la configuración del log, esta sección nos permite establecer cómo se desplegará en el servidor. Seleccionando el nivel de log por defecto, qué appenders usaremos, etc…

Una vez que tenemos definido el mecanismo de log en nuestra aplicación debemos saber cómo recuperarlo e incluirlo para que podamos usarlo en nuestro códugo fuente.

Inyectar log con Seam

Seam proporciona una API de logging que simplifica mucho la manera de gestionar el log. Utilizando la anotación @Logger podemos inyectar una instancia del Log sin necesidad de configurar nada más.

Esta variable de log inyectada, tendrá un método disponible por cada nivel de log que queramos tener. Así pues si la variable es log, tendremos un método info, debug, warn, error, fatal.

public class ManejadorFundeweb {
  @Logger
  private Logger log;
  ....
  ....
 
  public boolean compruebaCantidad(User user, Product product, int quantity) {
    log.debug("Comprobando cantidad para el usuario: #0 producto: #1 cantidad: #2", user.username(), product.name(), quantity);
    ....
  }
}

Nota: Como podemos ver en la llamad anaterior al log, dentro del mensaje de log introducimos los parámetros con #0, #1, … #n. Posteriormente en el mismo método de log obtenemos el valor de cada uno.

Obtener log con Seam pero sin inyectarlo

Si en un componente Seam (lleva la anotación @Name), también lleva la anotación @BypassInterceptors, entonces la inyección de log por Seam no funcionará ya que la anotación @Logger, no inyectara un logger a la clase. Para solventar este problema, utilizaremos la clase Logging de Seam para obtener un logger de manera manual.

@Name("pruebaLog")
@BypassInterceptors
public class ClasePrueba {
   private static final Log LOG = Logging.getLog(ClasePrueba.class);
   ...	
}

Log en aplicaciones no Seam

Cuando estamos fuera de un aplicación Seam no tenemos disponible las clases del paquete org.jboss.seam. Pero sí tenemos unos wrappers hechos en ATICA que nos solventan el problema de incorporar el log, para ello añadir la siguiente dependencia Maven:

<dependency>
	<groupId>org.um.atica</groupId>
	<artifactId>fundeweb-commons-services</artifactId>
	<version>1.2.6-CR-2</version>
</dependency>

Nota: Antes de incluir la dependencia, revise las versiones de la misma. Ha de incluir la versión más actualizada de esta librería.

Una vez incluida la dependencia, la obtención del log se realiza de manera muy similar al apartado anterior

import org.umu.atica.log.Log;
import org.umu.atica.log.Logging;
public class ClasePrueba {
   private static final Log LOG = Logging.getLog(ClasePrueba.class);
   ...
}

Es importante a la hora de gestionar el log, diferenciar el log que utilizaremos para la fase de desarrollo y el que pondremos finalmente en explotación. Esta diferenciación no es trivial ya que la cantidad de log que es necesario para el desarrollo es mayor que el que finalmente se necesita en explotación.

Así pues, cuando estemos desarrollando deberemos fijar el log en DEBUG, en este estado se nos generarán un mayor número de trazas de depuración. A su vez, nosotros en la aplicación anotaremos como DEBUG, aquellas trazas que serán útiles sólo para la fase de desarrollo.

En cuanto a explotación, el nivel adecuado de log será INFO, en este nivel la información que se genera deberá ser la imprescindible para realizar comprobaciones y trazabilidad del uso de la aplicación, pero deberá ser menor que la generada en estado DEBUG. En este punto, además del nivel de debug es imprescindible incofporar el usuario que realiza las diferentes acciones en cada traza (esto nos da la trazabilidad de usuario). Para ello debemos incluir un parámetro en nuestras trazas de log que recupere el usuario que está ejecutando la aplicación, este valor lo podemos obtener de la clase UmuIdentity, que se carga cuando el usuario se loguea en la aplicación.

Al mismo tiempo, en nuestro fichero de configuración de log, debemos asegurarnos, para los diferentes componentes que generan log, asegurar un nivel adecuado para cada entorno. A continuación mostramos un ejemplo de ello.

<logger name="org.apache">
	<level value="WARN"/>
</logger>
 
<logger name="javax.faces">
	<level value="WARN"/>
</logger>
 
<logger name="org.ajax4jsf">
	<level value="WARN"/>
</logger>
 
<logger name="org.richfaces">
	<level value="WARN"/>
</logger>
 
<logger name="org.quartz.simpl">
	<level value="WARN"/> 
</logger>
  • fdw2.0/fundeweb2.0/gt/sistema_de_log_basico_en_fundeweb.txt
  • Última modificación: 07/11/2017 10:46
  • (editor externo)