在 log4net 中以编程方式添加和删除日志附加程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1519728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 13:24:56  来源:igfitidea点击:

Programmatically adding and removing log appenders in log4net

.netnunitlog4net

提问by Pete

I have a component that uses log4net. I want to create unit tests, that validate that certain error conditions result in the correct logging.

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

I was thinking that the best way to do this is to create an ILogAppender implementation, for example a mock. I would then add the log appender to log4net during test setup, inspect what was written during test validation, and remove it again during test teardown.

我认为最好的方法是创建一个 ILogAppender 实现,例如模拟。然后,我会在测试设置期间将日志追加器添加到 log4net,检查测试验证期间写入的内容,并在测试拆卸期间再次将其删除。

Is this possible?

这可能吗?

采纳答案by Peter Lillevold

I have been using the BasicConfiguratorconfigured with a MemoryAppender. This appender lets you get to the in-memory messages logged during your test.

我一直在使用配置了MemoryAppender的 BasicConfigurator。此 appender 可让您访问测试期间记录的内存中消息。

回答by piers7

Using the BasicConfigurator is fine for unit testing (what the OP asked for, but not what's in the subject line). The other answers grab output for a specific logger.

使用 BasicConfigurator 可以很好地进行单元测试(OP 要求的是什么,但不是主题行中的内容)。其他答案抓取特定记录器的输出。

I wanted it all(this was a 'self test' page within a website). In the end I did basically the following:

我想要这一切(这是网站内的“自我测试”页面)。最后我基本上做了以下几件事:

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

...but wrapped up as a Disposable as per @Pawel's approach

...但按照@Pawel 的方法包装为一次性

UPDATE: Pawel's answer was deleted, so I am adding his link here: Programmatically check Log4Net log.

更新:Pawel 的回答被删除,所以我在这里添加他的链接:以 编程方式检查 Log4Net 日志

回答by armannvg

The following code was originally found on the apache mailing list archivesand should solve the problem of adding and removing log4net appenders in code

以下代码最初是在apache邮件列表存档中找到的,应该可以解决代码中添加和删除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;
    }
}

回答by Denis

How about:

怎么样:

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

same for add.

添加相同。