Entradas con la etiqueta ‘logging’

log4j: nivel de prioridad personalizado

Martes, 17 de febrero de 2009

Por defecto, Log4j tiene 6 niveles de prioridad para las trazas. Por orden de detalle de mayor a menor se definen:

  • trace: Permite mayor nivel de detalle.
  • debug: Trazas que permiten la depuración de errores. Normalmente este nivel solo se usa en las fases de desarrollo de la aplicación.
  • info: Se usa para trazas meramente informativas.
  • warn: Se usa para trazas de alerta. No tienen por que afectar al correcto funcionamiento de la aplicación.
  • error: Se usa para guardar trazas de errores de los que la aplicación puede recuperarse.
  • fatal: se usa para guardar trazas antes de que la aplicación aborte la ejecución. Son errores de los que la aplicación no puede recuperarse.

Además se definen 2 niveles especiales:

  • all: habilita todos niveles de detalle
  • off: inhabilita el envío de trazas.

Es importante tener en cuenta que al habilitar un nivel de detalle mayor, se habilitan todos los niveles que contiene.

ALL>TRACE>DEBUG>INFO>WARN>ERROR>FATAL>OFF

Antes de crear un nuevo nivel de prioridad hay que cuestionarse si es realmente necesaro. En muchas ocasiones se confunden los niveles de prioridad con categorías en las trazas.

Por ejemplo, si se quieren diferenciar las trazas que se producen cuando un usuario inicia sesión de otras que se producen cuando el usuario realiza ciertos accesos a determinados sistemas, se pueden usar un log con un determinado nombre.

Logger logSesion = Logger.getLogger("sesion");
Logger logAcceso = Logger.getLogger("acceso");

El parámetro que se pasa al crear el logger no tiene por que ser estrictamente el nombre de la clase, sino cualquier otro nombre que nos pueda ser descriptivo.

Si aun sabiendo esto decides a crear un nuevo nivel, esto se realiza heredando de la clase Level.

package es.excelsit.blog.log;
import org.apache.log4j.Level;
/**
* My own {@link org.apache.log4j.Level} for logging.
*
* @author fernando
*
*/
public class MiNivel extends Level {
   /**
    * El valor para este nivel.
    */
   public static final int MI_NIVEL_INT = DEBUG_INT - 10;
 
   /**
    * Texto identificativo para el nivel.
    */
   public static final String MI_NIVEL_STR = "MI_NIVEL";
 
   /**
    * {@link Level} representa a este nivel
    */
   public static final Level MI_NIVEL = new MiNivel(MI_NIVEL_INT, MI_NIVEL_STR, 7);
 
   /**
    * Constructor
    *
    * @param arg0 entero que indica el nivel
    * @param arg1 cadena identificativa de este nivel
    * @param arg2 nivel de syslog asociado
    */
   protected MiNivel(int arg0, String arg1, int arg2) {
      super(arg0, arg1, arg2);
   }
 
   /**
    * Comprueba si s es "MI_NIVEL". Si es afirmativo devuelve
    * {@link MiNivel#MI_NIVEL}, sino se llama a
    * {@link MiNivel#toLevel(String, Level)} con el nivel por defecto.
    * {@link Level#DEBUG}
    *
    * @see Level#toLevel(java.lang.String)
    * @see Level#toLevel(java.lang.String, org.apache.log4j.Level)
    *
    */
   public static Level toLevel(String s) {
      if ( s != null && s.toUpperCase().equals("MY_TRACE")) {
         return MI_NIVEL;
      }
      return (Level) toLevel(s, Level.DEBUG);
   }
 
   /**
    * Comprueba que val es igual a {@link MiNivel#MI_NIVEL_INT}. Si es afirmativo devuelve
    * {@link MiNivel#MI_NIVEL}, sino se llama a {@link MiNivel#toLevel(int, Level)}
    * pasando como argumento el nivel por defecto {@link Level#DEBUG}
    *
    * @see Level#toLevel(int)
    * @see Level#toLevel(int, org.apache.log4j.Level)
    *
    */
   public static Level toLevel(int val) {
      if (val == MI_NIVEL_INT) {
         return MI_NIVEL;
      }
      return (Level) toLevel(val, Level.DEBUG);
   }
 
   /**
    * Comprueba que val es igual a {@link MiNivel#MI_NIVEL_INT}. Si es
    * afirmativo devuelve
    * {@link MiNivel#MI_NIVEL}, sino se llama a
    * {@link Level#toLevel(int, org.apache.log4j.Level)}
    *
    * @see Level#toLevel(int, org.apache.log4j.Level)
    */
   public static Level toLevel(int val, Level defaultLevel) {
      if (val == MI_NIVEL_INT) {
         return MI_NIVEL;
      }
      return Level.toLevel(val, defaultLevel);
   }
 
   /**
    * Comprueba si s es "MI_NIVEL". Si es afirmativo devuelve
    * {@link MiNivel#MI_NIVEL}, sino se llama a
    * {@link Level#toLevel(java.lang.String, org.apache.log4j.Level)}
    *
    * @see Level#toLevel(java.lang.String, org.apache.log4j.Level)
    */
   public static Level toLevel(String sArg, Level defaultLevel) {
      if (sArg != null && sArg.toUpperCase().equals("MI_NIVEL")) {
         return MI_NIVEL;
      }
      return Level.toLevel(sArg, defaultLevel);
   }
}

En el constructor vemos que se necesitan 3 parámetros:

  • El primero es un número que indica la posicion en la que se encuentra este nuevo nivel. Podemos usar cualquier numero a nuestra elección entre los predefinidos para los niveles por defecto:
    • ALL = -2147483648
    • DEBUG = 10000
    • ERROR = 40000
    • FATAL  = 50000
    • INFO = 20000
    • OFF = 2147483647
    • WARN = 30000
  • El segundo es una cadena que identifica este nivel.
  • El tercero es el nivel equivalente para Syslog de UNIX
    #define LOG_EMERG       0       /* system is unusable */
    #define LOG_ALERT       1       /* action must be taken immediately */
    #define LOG_CRIT        2       /* critical conditions */
    #define LOG_ERR         3       /* error conditions */
    #define LOG_WARNING     4       /* warning conditions */
    #define LOG_NOTICE      5       /* normal but significant condition */
    #define LOG_INFO        6       /* informational */
    #define LOG_DEBUG       7       /* debug-level messages */

Etiquetas: , ,