我在使用滚动追加器时遇到了log4net的问题。当我们有多个线程时,我们创建一个RollingAppender来将消息记录到默认日志文件以及特定于作业的日志文件中。我们在RollingAppender中设置了一个PropertyFilter,并使用guid作为正在使用的线程的键。我们还设置了ThreadContext。属性[key]为相同的键
在开始作业时创建Appender,然后在try/catch/finally代码的finally块中删除Appender。
问题是,记录器随机创建包含AppName.log的子文件夹,以及文件夹路径中dateppattern过滤器的第一部分。例如,如果datpattern为yyyyMM'Today''{fileName}.log'"AppName是SampleApp.exe,然后我们随机地以文件夹名称结束,如下所示:
今天SampleApp.log2022 11 AppenderName.log。
执行此操作时,将使用相同的命名约定创建多个文件夹。所以我们最终得到了这样的文件夹结构:
今天SampleApp.log2022 11 SampleApp.log2022 11 今天 SampleApp.log2022 11 SampleApp.log2022 11 今天 SampleApp.log2022 11 AppenderName.log
显然这是个问题。
下面是Appender代码
public void CreateRollingFileAppender
(
string appenderName,
string fileName,
PropertyFilter filter = null,
string logPath = ""
)
{
if (logPath == "") logPath = _logConfiguration.LogPath;
if (Root.GetAppender(appenderName) != null) return;
var patternLayout = new PatternLayout(_logConfiguration.Appender.PatternLayout);
var denyAllFilter = new DenyAllFilter();
var appender = new RollingFileAppender
{
Name = appenderName,
File = logPath,
StaticLogFileName = false,
Layout = patternLayout,
ImmediateFlush = true,
AppendToFile = true,
MaxSizeRollBackups = 5,
MaximumFileSize = _logConfiguration.Appender.MaxSize,
RollingStyle = RollingFileAppender.RollingMode.Date,
DatePattern = $@"yyyy\MM\'Today'\'{fileName}.log'",
LockingModel = new FileAppender.MinimalLock()
};
if (filter != null)
{
appender.AddFilter(filter);
appender.AddFilter(denyAllFilter);
}
appender.ActivateOptions();
BasicConfigurator.Configure(Repository, appender);
}
,下面是生成我们使用的过滤器的代码:
public PropertyFilter CreateThreadFilter()
{
var guid = Guid.NewGuid().ToString();
ThreadContext.Properties[Key] = guid;
return new PropertyFilter
{
Key = Key,
StringToMatch = guid,
AcceptOnMatch = true
};
}
下面是删除附加代码:
public void RemoveAppender(string appenderName)
{
var appender = Root.GetAppender(appenderName);
if (appender != null)
{
appender.Close();
Root.RemoveAppender(appenderName);
}
}
,下面是调用这段代码的一个例子:
CreateRollingFileAppender("Test", "Test", CreateThreadFilter())
try
{
...
logger.Info(message);
}
catch (Exception e)
{
logger.Error(e)
}
finally
{
RemoveAppender("Test")
}
我们定义Repository和Root如下:
var Repository = LogManager.CreateRepository(Assembly.GetEntryAssembly(), typeof(Hierarchy));
var Root is ((Hierarchy)Repository).Root
请建议。
感谢所以这里的问题与代码无关,而是与配置有关。前面的开发人员使用配置文件来存储用于创建任何文件的属性。但是,他在配置文件中保留了File属性为空。所以当第一次启动时,它没有path属性来创建文件。