以编程方式在log4net中添加和删除日志追加器

时间:2009-10-05 12:14:39

标签: .net nunit log4net

我有一个使用log4net的组件。我想创建单元测试,验证某些错误条件会导致正确的日志记录。

我认为最好的方法是创建一个ILogAppender实现,例如mock。然后,我会在测试设置期间将log appender添加到log4net,检查测试验证期间写入的内容,并在测试拆解期间再次删除它。

这可能吗?

4 个答案:

答案 0 :(得分:19)

使用BasicConfigurator可以进行单元测试(OP要求的内容,但不是主题行中的内容)。另一个答案是获取特定记录器的输出。

我想要所有(这是一个网站内的'自测'页面)。最后我基本上做了以下几点:

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

......但按照@ Pawel的方法包装成Disposable

更新:Pawel的答案已被删除,所以我在这里添加他的链接: Programmatically check Log4Net log

答案 1 :(得分:11)

我一直在使用配置了the BasicConfiguratorMemoryAppender。此附加程序允许您访问测试期间记录的内存中消息。

答案 2 :(得分:3)

最初在apache mailing list archives上找到以下代码,并且应解决在代码中添加和删除log4net appender的问题

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

答案 3 :(得分:1)

怎么样:

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

添加相同。