【发布时间】:2020-05-21 23:02:36
【问题描述】:
长期以来,我一直在尝试以编程方式打开和关闭 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