gpt4 book ai didi

c# - 为什么将日志记录到 log4net.ILog 附加到多个日志?

转载 作者:行者123 更新时间:2023-11-30 16:39:58 26 4
gpt4 key购买 nike

我正在为第三方应用程序开发一个插件,对于这个插件的每次“运行”,我都想要一个独占的日志文件。

我构建了以下类。

public class LogFileRepository
{
private readonly Common.Configuration.Settings _configSettings;
private const string InstanceName = "AutomationPlugin.Logging";
private readonly ILoggerRepository _repository;


public LogFileRepository (Common.Configuration.Settings configSettings)
{
_configSettings = configSettings;

var repositoryName = $"{InstanceName}.Repository";
_repository = LoggerManager.CreateRepository(repositoryName);
}


public ILog GetLog(string name)
{
var logger = LogManager.Exists(_repository.Name, name);
if (logger != null)
{
return logger;
}

var filter = new LevelMatchFilter {LevelToMatch = Level.All};
filter.ActivateOptions();
var appender = new RollingFileAppender
{
AppendToFile = false,
DatePattern = "yyyy-MM-dd",
File = String.Format(_configSettings.Paths.LogFileTemplate, name),
ImmediateFlush = true,
Layout = new PatternLayout("%n%date{ABSOLUTE} | %-7p | %m"),
LockingModel = new FileAppender.MinimalLock(),
MaxSizeRollBackups = 1,
Name = $"{InstanceName}.{name}.Appender",
PreserveLogFileNameExtension = false,
RollingStyle = RollingFileAppender.RollingMode.Once
};
appender.AddFilter(filter);
appender.ActivateOptions();

BasicConfigurator.Configure(_repository, appender);

return LogManager.GetLogger(_repository.Name, name);
}
}

打算这个函数做的是让 GetLog 方法返回一个日志文件(具有指定的名称),如果 LogManager 已经有的话;如果没有现有的日志文件,那么它应该实例化并返回它。

确实发生了。在第一次运行插件时,会创建并写入一个日志文件;在插件的第二次运行中,一个新的日志文件被创建并写入,但是所有消息也被写入第一个日志文件。在第三次运行时,所有消息都写入两个现有日志文件以及新的第三个日志文件。

为什么? RollingFileAppender 中是否有我似乎误解/配置错误的内容?我想要每个 name 参数的独占日志文件。

最佳答案

假设您已经使用 LogManager.CreateRepository() 创建了 _repository,这实际上创建了一个 Hierarchy,当您使用您的new appender via BasicConfigurator.Configure(_repository, appender); 这会将 appender 添加到层次结构的 Root appender 集合。

然后从存储库创建的所有记录器都是“根”的子记录器,并且被配置为“附加的”,因为它们附加到直接针对它们定义的所有附加程序,它们的任何父项记录器,一直到根。在您的情况下,记录器本身没有自己的 appender,因此只是从 Root 中获取 appender,在您的情况下,它包含 所有 appender。结果,所有消息都记录到每个文件中。

您要做的是将 appender 附加到它的特定记录器,并禁用可加性,这样它就不会记录到层次结构中更高的 appender。似乎没有一种“好的”方法可以做到这一点,但以下方法在我的测试中起作用:

...
appender.AddFilter(filter);
appender.ActivateOptions();

// Add the appender directly to the logger and prevent it picking up parent appenders
if (LoggerManager.GetLogger(_repository.Name, name) is Logger loggerImpl)
{
loggerImpl.Additivity = false;
loggerImpl.AddAppender(appender);
}

BasicConfigurator.Configure(_repository, appender);
return LogManager.GetLogger(_repository.Name, name);

关于c# - 为什么将日志记录到 log4net.ILog 附加到多个日志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52184534/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com