2011-01-16 17 views
5

Estoy en proceso de implementar el soporte de registro en una biblioteca de código abierto en la que estoy trabajando. La mayoría de las bibliotecas de terceros parecen elegir explícitamente una biblioteca de registro "preferida" como Log4Net o NLog etc. y luego requieren que el consumidor de su biblioteca "se ocupe de ello". Afortunadamente, tenemos una biblioteca como Common.Logging para abordar este problema en nuestra (s) aplicación (es) consumidora (s) que unifica estas implementaciones de registro de bibliotecas de terceros.Implementación de biblioteca de código abierto: cómo manejar el registro?

Iba a tratar de evitar hacer referencia a otra biblioteca de terceros de mi propia biblioteca de código abierto para evitar incluir otra referencia de ensamblaje en la aplicación de otra persona. Tal vez esto no es una preocupación, ¿y debería detenerme allí?

Suponiendo que algunas personas acepten que las referencias de ensamblaje excesivas son molestas (y como alguien lo mencionará), personalmente, no me gusta usar ILMerge para este tipo de situaciones, ya que puede tener varias bibliotecas que usan Log4Net y si cada uno de ellos está ILMerged en el ensamblaje, en mi opinión, está hinchando el tamaño de una aplicación.

Para ese fin, estaba pensando en implementar y exponer un LogBridge para permitir que el consumidor de mi biblioteca se conecte a mis llamadas de registro si así lo desea (estaría desactivado por defecto). También permítanme enfatizar que no estoy hablando de implementar mi propio marco de trabajo de registro, solo asegurándome de que expongo el registro si a alguien le preocupa consultarlo. que estaba pensando la puesta en práctica de consumir parecería algo como:

public class SomeSetupClass 
{ 
    private void SomeSetupMethod() 
    { 
    var log = LogManager.GetLogger("LogSourceName"); 
    var logBridge = new LogBridge() 
         { 
         DebugEnabled = log.IsDebugEnabled, 
         InformationEnabled = log.IsInfoEnabled, 
         WarningEnabled = log.IsWarnEnabled, 
         ErrorEnabled = log.IsErrorEnabled, 
         CriticalEnabled = log.IsFatalEnabled 
         }; 

    logBridge.DebugMessageReceived += (sender, e) => log.Debug(e.Message); 
    logBridge.InformationMessageReceived += (sender, e) => log.Info(e.Message); 
    logBridge.WarningMessageReceived += (sender, e) => log.Warn(e.Message); 
    logBridge.ErrorMessageReceived += (sender, e) => log.Error(e.Message); 
    logBridge.CrticalMessageReceived += (sender, e) => log.Fatal(e.Message);  } 
    } 
} 

¿Este enfoque tiene sentido? ¿Estoy pensando en esto después de estar de vacaciones por mucho tiempo y solo debería hacer referencia a Log4Net o NLog etc. y terminar con esto? ¿Me estoy perdiendo los principales contras de este enfoque? ¿La API aproximada tiene sentido?

Como siempre, curiosidad por lo que todo el mundo piensa ...

actualización

curioso si la gente piensa que la solución jgauffin es el mejor camino a seguir? Lo había pensado un poco antes de esta publicación; pensé que el LogBridge sería más fácil de conectar para los consumidores en lugar de requerir una interfaz personalizada para implementarse en un proyecto consumidor. ¿Pensamientos?

+0

Algo así tiene sentido. Existen numerosos marcos de registro, algunos mejores que otros. Todos tienen su favorito. Al proporcionar un buen gancho a medida que lo hace, no está empujando nada en la garganta de nadie, y está proporcionando una excelente flexibilidad. – Pedro

Respuesta

1

Buscar en el sistema.Diagnósticos y solo use las clases Trace o Debug. Productos como Log4Net pueden recogerlos cuando sea necesario.

+0

Sí, también había considerado esto. Miré cómo implementar CustomTraceListener, y aunque puedes anular el manejo de TraceEvent; la API parecía esperar que anulara Write/WriteLine, en cuyo punto pierde TraveEventLevel. ¿Problema/no problema? –

+0

No hay problema: hereda del oyente de seguimiento de base y, por lo tanto, puede construir su método WriteLine() para tenerlo en cuenta (si lo desea). –

+0

Lo suficientemente justo ... ese fue mi plan original de todos modos ... solo comencé a considerar una alternativa cuando vi que Write/WriteLine era abstracto y tuvo que ser anulado ... gracias por la entrada. –

1

que suelo hacer esto:

  1. proporcionan una interfaz para el registro: ILogger
  2. Crear una fábrica registrador usado para obtener un registrador: ILogger _logger = LogManager.GetLogger(typeof(ClassBeingLogged));
  3. proporcionar una implementación básica como ConsoleLogger.

También puede proporcionar ejemplos en la wiki de su proyecto que muestran cómo implementar nlog o log4net. Eso es usualmente suficiente.

la LogManager toma un ILogFactory que es responsable de la creación de la implementación real:

public class LogManager 
{ 
    ILogFactory _factory; 

    public static void Assign(ILogFactory factory); 
    public static ILogger GetLogger(Type typeBeingLogged); 
} 

public interface ILogFactory 
{ 
    ILogger GetLogger(Type typeBeingLogged); 
} 

Esto hace que sea muy fácil de poner en práctica un adaptador para cualquier marco de registro.

+0

Había reflexionado sobre este enfoque; mi pensamiento es que el principal inconveniente es que un usuario debe implementar e inyectar una implementación de su interfaz de registro. Mi impresión inicial es que sería más trabajo para el consumidor que simplemente vincular su marco de trabajo existente a una API LogBridge muy simple. Dicho esto, los ejemplos en el Wiki del proyecto son una obligación, como usted señala. ¿Pensamientos? –

+0

Por lo general, solo dos clases deben implementarse para que funcione. También puede realizar una implementación de nlog o log4net que ilmerge (no me refiero a que deba usar log4net/nlog, sino los adaptadores para los marcos) y proporcione descargas por separado en su sitio. Los usuarios aún pueden usar su marco de trabajo de registro favorito ya que la descarga principal solo tiene interfaces definidas. – jgauffin

Cuestiones relacionadas