2010-11-05 9 views
5

Tengo una serie de paquetes en mi aplicación web Java. En algunos de ellos utilizo este constructo:¿Dónde se define un registrador estático de toda la aplicación?

public class Foo { 
    private static Logger logger = LoggerFactory.getLogger("com.XXX"); 
    public void bar() { 
    Foo.logger.debug("Method bar() was just called"); 
    } 
} 

Por supuesto, es solo un ejemplo. Todo funciona bien, pero no me gusta la idea de la inicialización del registrador en muchas clases. Es una duplicación de código obvia. Me gustaría moverlo a alguna clase de ayuda y permitir que todas las otras clases accedan a él. ¿Es una idea correcta? ¿O tal vez hay alguna otra "mejor práctica" o un patrón?

Respuesta

3

Puede escribir su propia clase de utilidad que envuelve el registrador global e implementa delegados estáticos en los métodos del registrador. A continuación, sólo hacer una importación estática de esta clase:

public class MyLogger { 
    private static Logger logger = LoggerFactory.getLogger("application"); 

    public static void debug(String s) {logger.debug(s));} 

    public static void debug(Class<?> caller, String s) { 
    LoggerFactory.getLogger(caller.getName()).debug(s); 
    } 

    // ... 
} 

Uso:

import static MyLogger.*; 

public class Foo { 
    public void bar() { 
    // makes use of static import! 
    debug("Method bar() was just called"); 
    debug(this.getClass(), "Method bar() was just called"); 
    } 
} 

añadido una versión sobrecargada del ejemplo debug delegado que toma un objeto de clase y utiliza el registrador apropiado.

+1

Sí se pudo. Pero la captura está en la parte '" com.XXX "', que normalmente se utiliza para indicar de qué clase proviene la entrada de registro. Si no necesita esto, puede usar su enfoque. –

+0

como la importación estática! – dogbane

+0

@Andreas_D Estoy de acuerdo con Peter Knego. ¿Es posible obtener el nombre de la clase de llamada ('com.XXX.Foo' en el ejemplo) dentro de su método' debug() '? – yegor256

0

Se puede crear un Adapter pattern de registrador. En mi caso, extendí el registrador para incluir toda la funcionalidad del registrador. Esto se convierte en Singleton.

public class LoggerAdapter extends Logger { 
    private LoggerAdapter instance; 
    private Logger logger; 

    private LoggerAdapter() { 

    } 

    public static LoggerAdapter getInstance(Clazz<?> clazz) { 
     if (instance == null) { 
      instance = new LoggerAdapter(); 
     } 
     instance.logger = logger = LoggerFactory.getLogger(clazz.getName()); 

     return instance; 
    } 

    @Override 
    public void trace(Object object) { 
     logger.trace(object); 
    } 

    //Other overridden methods here... 
}; 

Básicamente, un registrador dinámica cambiante ....

5

no creo que va a ganar nada si utiliza centralizado registrador estático mundial constrcut que no sea el Log4J común llama/INIT.

Si se escribe

private static Logger logger = LoggerFactory.getLogger("com.XXX"); 
logger.info("Hello World"); 

o algo así

GlobalLogger.info(this, "LogMessage"); //Singleton... 

... no hará que su código sea más "legible".

1

Esto no se recomienda ya que perderá las capacidades de registro jerárquico de Log4j (si eso es lo que está usando), donde es muy beneficioso agregar diferentes appenders en diferentes niveles de su árbol de paquetes. No haría esto ya que perdería información sobre qué clase creó el mensaje de registro.

8

Decir que esto es duplicación de código es como decir que tener import java.util.* en el 75% de las clases es una duplicación de código. O que te encuentres escribiendo public class ... con demasiada frecuencia. No está duplicando lógica. Está duplicando el código repetitivo.

La duplicación de código es solo cuando huele a lógica de duplicación. Si hay demasiado código repetitivo, es el diseño del lenguaje huele realmente. Nada de lo que realmente deberías estar preocupado.

En el lado negativo, pierde la capacidad de ajustar su registro si abandona la estructura jerárquica.

1

El encapsulado de una dependencia tercera parte (es decir, Log4J) con una clase de logger utilidad tiene sentido.

Por ejemplo, si un equipo decide cambiar de Log4j a NextBigThingLogger, simplemente actualiza su clase MyLogger y ninguna de las otras clases de aplicaciones.

limpiador y un mantenimiento más fácil.

API Apache, e incluso el propio lenguaje Java, están llenos de "diseño huele", pero eso no quiere decir que no debemos responder a ellos.

Cuestiones relacionadas