ejemplo coloredconsoleappender c# .net log4net

c# - coloredconsoleappender - log4net database



¿Debo declarar log4net logger una vez por clase o en clase base? (5)

La declaración proporcionada no se refiere a un cuello de botella. La declaración de su registrador en una clase base limita el control que tiene sobre el registro en clases derivadas. Si tiene clases A y B que se derivan de la misma clase base que contiene el registrador, está atascado con la misma configuración de registro para todo el registro realizado en las clases A y B.

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

Agregar una sola línea de un código a cada clase en la que desea iniciar sesión es una carga muy pequeña por la flexibilidad que proporciona.

Parece más limpio declarar un registrador y llamar a LogManager.GetLogger en una clase base para que todos los que lo heredan puedan usarlo. Sin embargo, en el sitio log4net y en otros blogs como en esta publicación de blog, se afirma que es mejor declarar un registrador por clase porque:

Puede usar los registradores de esta manera para aislar los problemas de registro en sus objetos, y le recomiendo que lo haga. Esto le permitirá acelerar y dirigir la salida del registro de registradores individuales utilizando el mecanismo de configuración jerárquica de log4net.

¿Significa esto que si lo pongo en la clase base, hará que el registrador sea un cuello de botella?

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


La práctica común es tener un registrador por clase, NO una clase base. De esta manera puede habilitar / deshabilitar el registro por clase.

También podría sugerir mirar usar 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, para nombrar las más populares. La desventaja de tener una implementación diferente es que no comparten una interfaz común y, por lo tanto, imponen una implementación de registro particular a los usuarios de su biblioteca.

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


La publicación no le indica específicamente que use un registrador diferente en cada clase derivada , sino un registrador diferente por 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 independientes instanciados al mismo tiempo (porque la base seguirá existiendo), especialmente si oculta la base con el mismo nombre de registrador. Los métodos de la clase base (no se anulan) seguirán haciendo referencia al registrador estático base, y los anulados usarán uno diferente.

Además, el artículo crea una instancia del registrador de esta manera:

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

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

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

En primer lugar, está marcado como de readonly , lo que significa que no podrá cambiar el campo accidentalmente, una vez que se haya inicializado. Y el uso del tipo funcionará de la misma manera que con la reflexión, pero un poco más rápido (resuelto en el momento de la compilación). Visual Studio también actualizará el nombre de la clase automáticamente si elige cambiarle el nombre (lo cual no haría si usara la sobrecarga de cadenas).


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

Edit: Hizo que el hilo fuera 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; } }

Espero que esto ayude


Utilizo un diccionario estático en la clase base, tecleado en el nombre de 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]; }

También tengo 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 lo hago) y el método GetLogger podría estar expuesto a las clases derivadas para que puedan hacer su propio registro.