在 nlog 上添加临时附加内存记录器

Add temporary additonal Memory Logger on nlog

我的 nlog 配置在 C# 程序上运行良好。 nlog 配置是通过独立文件完成的 nlog.config 然而,在代码的特定部分,我想创建一个额外的内存记录器目标,以便将日志的这个特定部分保存在缓冲区中(稍后我会将这个缓冲区附加到数据库中的特定对象)。

为此,我尝试以编程方式添加记录器及其配置。 我检查是否添加了记录器并添加了规则,但是新创建的记录器什么也没有。 我想我想念一些要告诉 nlog 实际考虑新记录器的东西。 一旦执行了目标函数,我想停止记录这段代码,仍然使用其他记录器,并在下一个项目上做同样的事情。

我用这行代码添加内存记录器:

                MemoryTarget memoryLogger = new MemoryTarget("memoryTarget");
                memoryLogger.Layout = "${message}";
                LogManager.Configuration.AddTarget(memoryLogger);
                LogManager.Configuration.AddRule(LogLevel.Trace, LogLevel.Fatal, memoryLogger);

下面是我添加新记录器之前的 nlog 配置:

添加新记录器后配置如下:

我不想重新初始化所有 nlog,因为它会重置我的日志文件,我希望在每次进程启动时都有一个新的日志文件。

谢谢@Rolf Kristensen,

的确如此,

LogManager.ReconfigExistingLoggers();

允许初始化内存记录器而不重置我在文件上的其他记录器。 通过这样做,甚至不会触发 LogManager 的 ConfigurationChanged/ConfigurationReloaded 静态事件,而且效果很好!太棒了!

临时激活和停用内存中日志的最终代码:

                MemoryTarget memoryTarget = new MemoryTarget("memoryTarget");
                memoryTarget.Layout = "${message}";
                LogManager.Configuration.AddTarget(memoryTarget);
                var memoryRule = new LoggingRule("memoryRule");
                memoryRule.EnableLoggingForLevels(LogLevel.Trace, LogLevel.Fatal);
                memoryRule.Targets.Add(memoryTarget);
                memoryRule.LoggerNamePattern = "*";
                LogManager.Configuration.LoggingRules.Add(memoryRule);
                LogManager.ReconfigExistingLoggers();
                _log.Debug("this is dumped in memory");
                foreach (string s in memoryTarget.Logs)
                {
                    Console.Write("---------mem dumped: {0}", s);
                }
                LogManager.Configuration.RemoveTarget(memoryTarget.Name);
                bool removed = LogManager.Configuration.LoggingRules.Remove(memoryRule);
                LogManager.ReconfigExistingLoggers();
                _log.Debug("no more in memory");

如果你阅读这篇文章 post,你可能有兴趣获取这段代码:

    public class MemoryLogger
    {
        static Logger _log = LogManager.GetCurrentClassLogger();
        MemoryTarget _memoryTarget;
        LoggingRule _memoryRule;

        public void Start()
        {
            _memoryTarget = new MemoryTarget("memoryTarget");
            _memoryTarget.Layout = "${message}";
            LogManager.Configuration.AddTarget(_memoryTarget);
            _memoryRule = new LoggingRule("memoryRule");
            _memoryRule.EnableLoggingForLevels(LogLevel.Trace, LogLevel.Fatal);
            _memoryRule.Targets.Add(_memoryTarget);
            _memoryRule.LoggerNamePattern = "*";
            LogManager.Configuration.LoggingRules.Add(_memoryRule);
            LogManager.ReconfigExistingLoggers();
        }

        public StringBuilder Stop()
        {
            LogManager.Configuration.RemoveTarget(_memoryTarget.Name);
            bool removed = LogManager.Configuration.LoggingRules.Remove(_memoryRule);
            if (!removed)
                _log.Error("cannot remove rule "+_memoryRule.RuleName);
            LogManager.ReconfigExistingLoggers();
            var ret = new StringBuilder();
            foreach (string s in _memoryTarget.Logs)
            {
                ret.AppendLine(s);
            }
            return ret;
        }
    }