2012-01-30 4 views
20

Parece más limpio declarar un registrador y llamar al LogManager.GetLogger en una clase base para que todos los herederos puedan usarlo. Sin embargo, en el sitio log4net y otros blogs como en this blog post se afirma que es mejor declarar un registrador por clase porque:¿Debo declarar log4net logger una vez por clase o en la clase base?

Puede utilizar los registradores de esta manera para aislar problemas de registro a través de sus objetos, y estoy totalmente de recomendar hazlo. Esto le permitirá acelerar y dirigir la salida de registro de los registradores individuales utilizando el mecanismo de configuración jerárquica de log4net.

Esto significa que si lo pongo en la clase base, ¿hará que ese registrador sea un cuello de botella?

Si es así, ¿hay otras soluciones o solo tengo que crear un registrador por clase?

Respuesta

0

Por lo general, debe tener una única clase de registrador, puede usar el patrón de singleton y asegurarse de tener solo una instancia de registrador para su aplicación.

Editar: Hecho seguro ahora, gracias por los comentarios.

public class Logger 
    { 
     private static object syncRoot = new Object(); 
     private static Logger instance=null; 
     // private constructor 
     private Logger() 
     { 
     } 
     /// <summary> 
    /// Gets an instance with default parameters based upon the caller 
    /// </summary> 
    /// <returns></returns> 
    public static Logger GetInstance() 
    { 
     // make sure you return single instance 
     if (instance == null) 
     { 
      lock (syncRoot) 
      { 
      instance=new Logger(); 
      } 
     } 
     return instance; 
    } 
    } 

Esperanza esto ayuda

+0

OP está utilizando log4net. Aunque una clase de registrador es una de las pocas ocasiones en que el patrón singleton es útil, el uso de un registrador diferente por clase mejora tremendamente la resolución de problemas: puede configurar detalladamente qué nivel de mensajes registrar para cada clase por separado. También puede enviar mensajes desde diferentes registradores a diferentes destinos (archivo de texto, registro de eventos, correo electrónico). Recomiendo usar una biblioteca así. Si un registrador se instancia de forma estática (una vez por tipo), la diferencia de rendimiento es insignificante. (no mi voto a la baja, sin embargo) – Groo

+0

Su singleton no es seguro para subprocesos, por lo que podría terminar con diferentes instancias de Logger (en el caso de un registrador probablemente no sea un problema importante, pero vale la pena señalarlo). Además, para iniciar sesión probablemente no le interese este patrón ya que es un poco más lento (ya que tiene que hacer un control nulo adicional ... de nuevo probablemente no sea un gran problema, pero vale la pena señalarlo). –

+0

¿No estás familiarizado con log4net? –

1

La declaración proporcionada no se refiere a un cuello de botella. Declarar su registrador en una clase base limita el control que tiene sobre el registro en las clases derivadas. Si tiene las clases A y B derivadas de la misma clase base que contiene el registrador, tiene la misma configuración de registro para todos los registros hechos en las clases A y B.

log4net le permite configurar sus registradores según la clase o el espacio de nombres para el que están creados, lo que le da un control muy estricto de lo que se registra. Por ejemplo, tener un registro de clase A en el nivel de información y un registro de clase B en el nivel de depuración.

Agregar una sola línea de un código a cada clase que desea registrar cosas es una carga muy pequeña para la flexibilidad que proporciona.

20

El puesto no está específicamente le indica que utilice un registrador diferente en cada deriva clase, pero en su lugar un registrador diferente para cada tipo de clase en general. Puede, pero no tiene que usar una nueva instancia de registrador en cada clase derivada.

Una forma de verlo es que puede ser confuso tener dos registradores separados al mismo tiempo (porque la base seguirá existiendo), especialmente si oculta la base con el mismo nombre de registrador. Sus métodos de clase base (no anulados) seguirán haciendo referencia al registrador estático básico, y los reemplazados utilizarán uno diferente.

Además, el artículo instancia el registrador de la siguiente manera:

static ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 

mientras que una forma un poco más simple podría ser utilizar:

static readonly ILog Log = LogManager.GetLogger(typeof(YourClass)); 

En primer lugar, éste se crea readonly, lo que significa que usted ganó' t podrá cambiar el campo accidentalmente, una vez inicializado. Y usar el tipo funcionará de la misma manera que con la reflexión, pero un poco más rápido (resuelto en tiempo de compilación).Visual Studio también actualizará el nombre de la clase automáticamente si elige cambiarle el nombre (que si no fuera porque usó la sobrecarga de la cadena).

+0

También puede usar el reflejo en lugar de 'typeof (YourClass)'. Con la reflexión, puede copiar y pegar el código repetitivo, y no tiene que enfrentar una situación en la que alguien haya copiado y pegado el registrador y haya olvidado cambiar 'typeof (YourClass)'. La llamada se vería así: 'LogManager.GetLogger (System.Reflection.MethodBase.GetCurrentMethod(). DeclaringType);' –

3

La práctica común es tener un registrador por clase, NO clase base. De esta forma puede activar/desactivar el registro por clase.

También podría sugerir mirar el uso de Common Logging 2.0, http://netcommon.sourceforge.net/.

Hay una variedad de implementaciones de registro para .NET actualmente en uso, log4net, Enterprise Library Logging, NLog, por nombrar las más populares. La desventaja de tener diferentes implementaciones es que no comparten una interfaz común y, por lo tanto, imponen una implementación de registro particular en los usuarios de su biblioteca.

Common.Logging library presenta una abstracción simple que le permite seleccionar una implementación de registro específica en tiempo de ejecución. Por lo tanto, puede diferir la decisión de qué biblioteca de registro en particular usar hasta la implementación. Los adaptadores se utilizan para conectar un sistema de registro particular en Common.Logging.

0

Puedo usar un diccionario estático en la clase base, enchavetado en nombre del tipo:

private static readonly Dictionary<string, ILog> _loggers = new Dictionary<string, ILog>(); 

Con un método (en la clase base) para devolver un registrador:

private ILog GetLogger(){ 
     var tn = this.GetType().FullName; 
     if (!_loggers.ContainsKey(tn)) { 
      _loggers.Add(tn,LogManager.GetLogger(this.GetType())); 
     } 
     return _loggers[tn]; 
    } 

I también tiene los métodos de registro en la clase base:

public void Log(string msg, params object[] args) { 
     GetLogger().InfoFormat(msg, args); 
    } 

Supongo que esto me permitiría configurar el registro por tipo (aunque no hago eso) y que el método GetLogger podría estar expuesto a clases derivadas para que puedan hacer su propio registro.

+0

Parece que está reenviando a su clase base ciertos comportamientos del registrador que ya existen. –

Cuestiones relacionadas