Я пытался программным образом включить и выключить NLog asyn c в течение длительного времени. Я никуда не денусь. У меня есть код, который, кажется, делает то, что я хочу, но после внесения изменений я вообще не получаю логи. Вот что я нашел до сих пор:
Когда файл конфигурации NLog содержит async=true
, тогда во время выполнения у меня будет две цели (LogManager.Configuration.AllTargets
) для каждой цели в файле конфигурации. Одним из них является исходная цель, переименованная с «_wrapped» в конце. Другая - это исходная (теперь переименованная) цель, завернутая в AsyncTargetWrapper
и получившая имя моей исходной цели.
Прежде чем что-либо делать (чтобы включить или отключить asyn c), сначала я очищаю все LoggingRules
.
Чтобы отключить асин c, я получаю обернутую цель от AsyncTargetWrapper
, переименовываю ее в исходное имя, удаляю цель обертки (которая, кажется, удаляет оригинал тоже), затем повторно добавьте исходную цель (которой теперь снова было дано ее первоначальное имя). Затем я создаю LoggingRule
и устанавливаю соответствующие уровни ведения журнала. Наконец, я звоню LogManager.ReconfigExistingLoggers()
. На этом этапе что-то сломано, так как я не буду ничего регистрировать.
Я следую аналогичному процессу при включении asyn c, за исключением того, что я переименую исходную цель, создаю 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();
Я не думаю, что эти последние две строки нужны, но я попробовал их, потому что больше ничего не работало.
Должен быть правильный способ перевернуть флаг asyn c, но я не знаю, что это такое. Может кто-нибудь сказать мне, как это сделать?