2009-10-05 14 views
23

Tengo un componente que usa log4net. Quiero crear pruebas unitarias, que validen que ciertas condiciones de error den como resultado el registro correcto.Agregando y quitando programáticamente agregados de registro en log4net

Estaba pensando que la mejor manera de hacerlo es crear una implementación de ILogAppender, por ejemplo, un simulacro. Luego agregaría el apéndice del registro a log4net durante la configuración de la prueba, inspeccionaré lo que se escribió durante la validación de la prueba y lo eliminaré nuevamente durante la eliminación de la prueba.

¿Esto es posible?

Respuesta

11

He estado usando the BasicConfigurator configurado con un MemoryAppender. Este appender le permite acceder a los mensajes en la memoria registrados durante su prueba.

+0

Finalmente llegué a implementar esto, y resuelve el problema muy bien – Pete

+0

+1; me salvó de hacer una implementación de stub de 'ILog' e inyectarlo en todas mis clases :-) –

3

El siguiente código se encontró originalmente en el apache mailing list archives y debe resolver el problema de la adición y eliminación de appenders log4net en el código

/// <summary> 
/// dataLog 
/// </summary> 
protected static readonly IDeviceCommunicationsLog dataLog = 
DeviceCommunicationsLogManager.GetLogger("LIS3.Data"); 


Each connection adds and removes a file appender programmatically: 

/// <summary> 
/// add connection specific appender 
/// </summary> 
void AddAppender() 
{ 
    // check if logging is endabled 
    if(this.IsLoggingEnabled()) 
    { 
     try 
     { 
      // get the interface 
      IAppenderAttachable connectionAppender = (IAppenderAttachable)this.DataLog.Logger; 
      // need some application configuration settings 
      NameValueCollection appSettings = ConfigurationSettings.AppSettings; 
      // get the layout string 
      string log4netLayoutString = appSettings["log4net.LIS3.LayoutString"]; 
      if(log4netLayoutString == null) 
      { 
       // use default setting 
       log4netLayoutString = "%d [%x]%n %m%n %P MessageData}%n%n"; 
      } 
      // get logging path 
      string log4netPath = appSettings["log4net.Path"]; 
      if(log4netPath == null) 
      { 
       // use default path 
       log4netPath = ".\\"; 
      } 
      // create the appender 
      this.rollingFileAppender = new RollingFileAppender(); 
      // setup the appender 
      this.rollingFileAppender.MaxFileSize = 10000000; 
      this.rollingFileAppender.MaxSizeRollBackups = 2; 
      this.rollingFileAppender.RollingStyle = RollingFileAppender.RollingMode.Size; 
      this.rollingFileAppender.StaticLogFileName = true; 
      string appenderPath = LogSourceName + ".log"; 
      // log source name may have a colon - if soreplace with underscore 
      appenderPath = appenderPath.Replace(':', '_'); 
      // now add to log4net path 
      appenderPath = Path.Combine(log4netPath, appenderPath); 
      // update file property of appender 
      this.rollingFileAppender.File = appenderPath; 
      // add the layout 
      PatternLayout patternLayout = new PatternLayout( log4netLayoutString); 
      this.rollingFileAppender.Layout = patternLayout; 
      // add the filter for the log source 
      NDCFilter sourceFilter = new NDCFilter(); 
      sourceFilter.StringToMatch = this.LogSourceName; 
      this.rollingFileAppender.AddFilter(sourceFilter); 
      // now add the deny all filter to end of the chain 
      DenyAllFilter denyAllFilter = new DenyAllFilter(); 
      this.rollingFileAppender.AddFilter(denyAllFilter); 
      // activate the options 
      this.rollingFileAppender.ActivateOptions(); 
      // add the appender 
      connectionAppender.AddAppender(this.rollingFileAppender); 
     } 
     catch(Exception x) 
     { 
      this.ErrorLog.Error("Error creating LIS3 data log appender for " + LogSourceName, x); 
     } 
    } 
} 
/// <summary> 
/// remove connection specific appender 
/// </summary> 
void RemoveAppender() 
{ 
    // check if we have one 
    if(this.rollingFileAppender != null) 
    { 
     // cast to required interface 
     IAppenderAttachable connectionAppender = (IAppenderAttachable)this.DataLog.Logger; 
     // remove the appendier 
     connectionAppender.RemoveAppender(rollingFileAppender); 
     // set to null 
     this.rollingFileAppender = null; 
    } 
} 
+0

Tenga en cuenta que si no utiliza BasicConfigurator o XmlConfigurator en cualquier lugar, debe configurar la jerarquía. Configurado en true para hacer que log4net haga cualquier cosa. – Vivelin

19

El uso del BasicConfigurator está bien para las pruebas unitarias (lo que solicitó OP, pero no lo que está en la línea de asunto). Las otras respuestas toman salida para un registrador específico.

Lo quería todo (esta era una página de "autocomprobación" en un sitio web). Al final lo hice básicamente los siguientes:

var root = ((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root; 
var attachable = root as IAppenderAttachable; 

var appender = new log4net.Appender.MemoryAppender(); 
if(attachable!=null) 
    attachable.AddAppender(appender); 
// do stuff 
var loggingEvents = appender.GetEvents(); 
foreach (var loggingEvent in loggingEvents) 
    loggingEvent.WriteRenderedMessage(writer); 
if(attachable!=null) 
    attachable.RemoveAppender(appender); 

... pero envuelto como un desechable de acuerdo con @ enfoque de Pawel

ACTUALIZACIÓN: ha sido eliminada la respuesta de Pawel, así que estoy añadiendo su enlace aquí: Programmatically check Log4Net log.

1

¿Qué tal:

((log4net.Repository.Hierarchy.Logger) theLogger.Logger).RemoveAppender("SomeAppender"); 

mismo para add.

+0

¿Sabes cómo hacer que el complemento realmente funcione? He escrito una prueba unitaria para probar la implementación de un appender personalizado que creé, pero desafortunadamente el método Add de Logger es falso, porque la implementación de ILog que LogManager.GetLogger (string) devuelve tiene una colección de solo lectura de appenders. Termina consumiendo silenciosamente la excepción que arroja internamente, y nunca agrega realmente el appender. –

Cuestiones relacionadas