在我的应用程序中配置NServiceBus时,我正在设置Log4Net以使用RollingFileAppender
:
.Log4Net<RollingFileAppender>(x=>
{
x.AppendToFile = true;
x.Threshold = Level.Debug;
x.MaxSizeRollBackups = 10;
x.RollingStyle = RollingFileAppender.RollingMode.Size;
x.File = "c:\\Logs\\log.txt";
})
我想删除缓冲以进行测试(通过设置BufferSize = 1
)
使用.Log4Net()
扩展程序时,这是否可行?
答案 0 :(得分:2)
log4net FileAppender
类不提供BufferSize
属性,因此您无法直接在配置中或使用该扩展方法设置它。 (此属性仅由BufferingAppenderSkeleton
基类公开,但不是FileAppender
类的基类。
实际上,在log4net代码库中进行搜索,看起来你可以控制FileAppender
使用的缓冲区大小的唯一方法就是编写自己的LockingModelBase
实现。 log4net附带的那些实现,即ExclusiveLock
或MinimalLock
,在内部使用FileStream
构造函数,它使用默认缓冲区大小0x1000,即4096。
说完了,你可能会做这样的事情:
.Log4Net<RollingFileAppender>(x=>
{
x.AppendToFile = true;
x.Threshold = Level.Debug;
x.MaxSizeRollBackups = 10;
x.RollingStyle = RollingFileAppender.RollingMode.Size;
x.File = "c:\\Logs\\log.txt";
x.LockingModel = new MyUnbufferedLockingModel();
})
使用MyUnbufferedLockingModel
这样的内容:
public class MyUnbufferedLockingModel : log4net.FileAppender.LockingModelBase
{
// This is essentially a rip-off of the default 'ExclusiveLock' class,
// but when creating the "m_stream", using an explicit buffer size of 1.
// Depending on your needs you may want to use the 'MinimalLock' class
// instead.
private Stream m_stream = null;
public override Stream AcquireLock()
{
return m_stream;
}
public override void CloseFile()
{
using (CurrentAppender.SecurityContext.Impersonate(this))
{
m_stream.Close();
}
}
public override void OpenFile(string filename, bool append, Encoding encoding)
{
try
{
using (CurrentAppender.SecurityContext.Impersonate(this))
{
string directoryName = Path.GetDirectoryName(filename);
if (!Directory.Exists(directoryName))
{
Directory.CreateDirectory(directoryName);
}
FileMode mode = append ? FileMode.Append : FileMode.Create;
m_stream = new FileStream(filename, mode, FileAccess.Write,
FileShare.Read,
1 /*BufferSize*/);
}
}
catch (Exception exception)
{
CurrentAppender.ErrorHandler.Error("Unable to acquire lock on file " + filename + ". " + exception.Message);
}
}
public override void ReleaseLock()
{
}
}
答案 1 :(得分:1)
最后,缓冲不是问题,解决方案非常简单。看起来RollingFileAppender默认使用独占锁,因此日志文件在应用程序运行时被锁定。
此实例中的修复是设置:LockingModel = new FileAppender.MinimalLock();
更新的init如下所示:
.Log4Net<RollingFileAppender>(x=>
{
x.LockingModel = new FileAppender.MinimalLock();
x.Threshold = Level.Debug;
x.MaxSizeRollBackups = 10;
x.RollingStyle = RollingFileAppender.RollingMode.Size;
x.File = "c:\\Logs\\log.txt";
})
当我在Log4Net文档中搜索缓冲解决方案时,我偶然发现了BufferingForwardingAppender。这个appender包装非缓冲的appender提供缓冲服务。
如果我想在RollingFileAppender中添加缓冲,那么配置会是什么样子:
.Log4Net<BufferingForwardingAppender>
(x =>
{
x.BufferSize = 50; // number of events to buffer
x.AddAppender(new RollingFileAppender()
{
LockingModel = new FileAppender.MinimalLock(),
Layout = new SimpleLayout(),
Threshold = Level.Debug,
MaxSizeRollBackups = 10,
RollingStyle = RollingFileAppender.RollingMode.Size,
File = "c:\\Logs\\log.txt",
SecurityContext = NullSecurityContext.Instance
});
})
帕特里克。