代码之家  ›  专栏  ›  技术社区  ›  awj

为什么登录到log4网络.ILog附加到多个日志?

  •  3
  • awj  · 技术社区  · 7 年前

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

    我已经建立了下面的类。

    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 参数。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Iridium    7 年前

    假设你创造了 _repository 使用 LogManager.CreateRepository() ,这实际上创建了一个 Hierarchy ,当您使用新的appender通过 BasicConfigurator.Configure(_repository, appender); Root 追加器集合。

    然后从存储库中创建的所有记录器都是“根”的子记录器,并且配置为“加法”,因为它们附加到直接针对它们定义的所有附加器上, 全部的 追加者。因此,所有消息都会记录到每个文件中。

    您要做的是将appender附加到其特定的记录器,并禁用additivity,这样它就不会再记录到层次结构中更高的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);