以编程方式将NLog目标切换到异步或从异步切换到NLog目标

问题描述 投票:0回答:1

我一直在尝试以编程方式打开和关闭NLog异步开关。我无处可去。我的代码似乎可以执行我想要的操作,但是进行更改后,根本没有任何日志记录。这是到目前为止我发现的内容:

当NLog配置文件包含async=true时,那么在运行时,配置文件中的每个目标都将有两个目标(LogManager.Configuration.AllTargets)。一个是原始目标,最后以“ _wrapped”重命名。另一个是包裹在AsyncTargetWrapper中的原始(现在已重命名)目标,并为其指定了原始目标的名称。

在做任何事情(打开或关闭异步之前,我先清除所有LoggingRules

要关闭异步,我从AsyncTargetWrapper获取包装的目标,将其重命名为原始名称,删除包装目标(似乎也删除了原始目标),然后重新添加原始目标(现在已经再次获得其原始名称)。然后,我创建一个LoggingRule并设置适当的日志记录级别。最后,我叫LogManager.ReconfigExistingLoggers()。在这一点上,有些东西坏了,因为我什么也得不到记录。

打开异步时,我遵循类似的过程,除了这次,我重命名原始目标,为其创建AsyncTargetWrapper,然后添加新的包装目标。再次,我为新目标创建一个LoggingRule并设置日志记录级别。在这一点上,有些东西坏了,因为我什么也得不到记录。

代码如下:

LogManager.Configuration.LoggingRules.Clear();

if (async) // turning async ON
{
    foreach (var target in LogManager.Configuration.AllTargets)
    {
        if (!(target is AsyncTargetWrapper))
        {
            string targetName = target.Name;
            // rename the synchronous target to indicate that it is going to be wrapped by another target (an asynchronous wrapper)
            target.Name = $"{target.Name}_wrapped";

            // create an asynchronous target wrpper and give it the name of the synchronous target's original (non-wrapped) name
            AsyncTargetWrapper asyncTarget = new AsyncTargetWrapper(target) { Name = targetName };

            LogManager.Configuration.AddTarget(asyncTarget);

            LoggingRule asyncRule = new LoggingRule("*", asyncTarget);
            if (_minLevel != null && _maxLevel != null)
            {
                asyncRule.EnableLoggingForLevels(_minLevel, _maxLevel);
            }
            else
            {
                foreach (var level in LogLevel.AllLevels.Except(new List<LogLevel>() { LogLevel.Off }))
                {
                    if (Logger.IsEnabled(level)) asyncRule.EnableLoggingForLevel(level);
                }
            }
        }
    }
}
else // turning async OFF
{
    foreach (var target in LogManager.Configuration.AllTargets)
    {
        if (target is AsyncTargetWrapper)
        {
            // get the wrapped (synchronous) target from the wrapper
            Target syncTarget = ((AsyncTargetWrapper)target).WrappedTarget;

            // rename the synchronous target (remove "_wrapped" from the end of its name)
            syncTarget.Name = target.Name.Replace("_wrapped", "");

            // remove the wrapper target
            LogManager.Configuration.RemoveTarget(target.Name);

            LogManager.Configuration.AddTarget(syncTarget);

            // create a rule for the wrapped (synchronous) target
            LoggingRule syncRule = new LoggingRule("*", syncTarget);

            // set the logging level for the synchronous target
            if (_minLevel != null && _maxLevel != null)
            {
                syncRule.EnableLoggingForLevels(_minLevel, _maxLevel);
            }
            else
            {
                foreach (var level in LogLevel.AllLevels.Except(new List<LogLevel>() { LogLevel.Off }))
                {
                    if (Logger.IsEnabled(level)) syncRule.EnableLoggingForLevel(level);
                }
            }
        }
    }
}

LogManager.Configuration.Reload();
LogManager.ReconfigExistingLoggers();

我认为不需要最后两行,但是我尝试了它们,因为其他任何方法都没有用。

必须有正确的方法来翻转异步标志,但我不知道它是什么。谁能告诉我该怎么做?

c# .net asynchronous nlog
1个回答
0
投票

我发现了问题。过去我有一个可行的实现,所以这一切都让我感到困惑。我的旧实现存在问题,因此我决定对其进行重构,但是在新实现中犯了一个错误。我遗漏了critical行代码!创建新的日志记录规则后,必须将其添加到配置中:

LogManager.Configuration.LoggingRules.Add(syncRule);

现在,它完全可以按照我的意愿工作。哇!

© www.soinside.com 2019 - 2024. All rights reserved.