2009-10-05 7 views
23

Ich habe eine Komponente, die log4net verwendet. Ich möchte Komponententests erstellen, die bestätigen, dass bestimmte Fehlerbedingungen zur korrekten Protokollierung führen.Programmgesteuertes Hinzufügen und Entfernen von Protokollapplikatoren in log4net

Ich dachte, dass der beste Weg dies zu tun ist, eine ILogAppender-Implementierung zu erstellen, zum Beispiel ein Mock. Ich würde dann den Protokollappender Log4net während der Testeinrichtung hinzufügen, inspizieren, was während der Testvalidierung geschrieben wurde, und es während des Testabbaus wieder entfernen.

Ist das möglich?

Antwort

11

ich verwendet haben the BasicConfigurator mit einem MemoryAppender konfiguriert lösen. Mit diesem Appender können Sie zu den speicherinternen Nachrichten gelangen, die während des Tests protokolliert wurden.

+0

Endlich habe ich das implementiert, und es löst das Problem sehr schön – Pete

+0

+1; rettete mich davor, eine Stub-Implementierung von 'ILog' zu machen und es in alle meine Klassen zu injizieren :-) –

3

Der folgende Code wurde ursprünglich auf dem apache mailing list archives gefunden und sollte das Problem der das Hinzufügen und Entfernen log4net Appender in Code

/// <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

Beachten Sie, dass Sie, wenn Sie den BasicConfigurator oder XmlConfigurator nirgendwo verwenden, Hierarchie.Configured auf true setzen müssen, damit log4net überhaupt etwas unternimmt. – Vivelin

19

Die Verwendung des BasicConfigurator eignet sich gut für Komponententests (was das OP angefordert hat, aber nicht, was in der Betreffzeile steht). Die anderen Antworten greifen auf die Ausgabe für einen bestimmten Logger zu.

Ich wollte es alle (dies war eine "Selbsttest" -Seite innerhalb einer Website). Am Ende habe ich im Grunde folgenden:

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); 

... aber verpackt als Einweg per @ Pawel Ansatz

UPDATE: Antwort des Pawel wurde gelöscht, so dass ich das Hinzufügen seines Link hier: Programmatically check Log4Net log.

1

Wie wäre:

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

gleiche gilt für zus.

+0

Wissen Sie, wie man das Addieren wirklich funktioniert? Ich habe einen Komponententest geschrieben, um die Implementierung eines benutzerdefinierten Appenders zu testen, den ich erstellt habe, aber leider ist die Add-Methode von Logger eine Lüge, weil die ILog-Implementierung, die LogManager.GetLogger (String) zurückgibt, eine schreibgeschützte Sammlung von Appendern enthält. Es endet stillschweigend die Ausnahme, die es intern auslöst, und fügt nie wirklich den Appender hinzu. –

Verwandte Themen