#c# #nlog
#c# #nlog
Вопрос:
У нас есть конфигурационный файл, который редактируется нашим графическим интерфейсом для динамического изменения уровня журнала нашего целевого файла.
Наше имя файла выглядит следующим образом: fileName=»${logDir}${var:subLogDir}/${var:RegionName}${logName}.dlog» Все переменные находятся в файле base .config программы, а RegionName задается динамически при запуске программы путем установки переменнойнепосредственно в конфигурации через NLog.LogManager.Конфигурация.Переменные [«RegionName»] = строка.Concat(RegionName, «/»);.
Наша проблема в том, что когда мы изменяем уровень журнала, пока программа генерирует журналы, наступает момент, когда журналы попадают в $ {var:subLogDir} напрямую, как если бы $ {var:RegionName} не был установлен, даже если мы знаем, что это так.
Похоже, что есть момент времени, когда динамические переменные еще не разрешены. Можем ли мы что-нибудь сделать, чтобы предотвратить это? Буферизация журналов при перезагрузке?
Версия NLog: 4.7.4
файл .config
<nlog keepVariablesOnReload="true">
<variable name="subLogDir" value="/Regions" />
<include file="..CommonLogsBaseVariables.xml" />
<include file="..CommonLogsBaseTargets.xml" />
<include file="..CommonLogsBaseRules.xml" />
</nlog>
BaseVariables.xml
<nlog>
<!-- Default variables values -->
<variable name="logLevel" value="LogLevel.Info"/>
<variable name="callstackLogLevel" value="LogLevel.Debug"/>
<variable name="keepFileOpen" value="true"/>
<variable name="autoFlush" value="true"/>
<variable name="concurrentWrites" value="false"/>
<variable name="hasAudit" value="false"/>
<variable name="archiveAboveSize" value="52428800"/>
<variable name="maxArchiveDays" value="365"/>
<variable name="archiveNumbering" value="DateAndSequence"/>
</nlog>
BaseTargets.xml
<nlog>
<targets async="true">
<target Type="File" name="LogFile" createDirs="true" keepFileOpen="${keepFileOpen}" autoFlush="${autoFlush}"
fileName="${logDir}${var:subLogDir}/${var:regionName}${logName}.dlog"
concurrentWrites="${concurrentWrites}"
cleanupFileName="false"
archiveFileName="${archiveLogDir}${var:subLogDir}/${var:regionName}${archiveLogName}.dlog"
archiveEvery="${archiveEvery}" archiveAboveSize="${archiveAboveSize}"
archiveNumbering="${archiveNumbering}" archiveDateFormat="${archiveDateFormat}" maxArchiveDays="${maxArchiveDays}">
<layout Type="CSVLayout" delimiter="Tab" >
<column name="date" layout="${longdate}" />
<column name="level" layout="${uppercase:${level}}" />
<column name="source,keywords" layout="${logger}" />
<column name="message" layout="${message}" />
</layout>
</target>
</targets>
</nlog>
Спасибо
Комментарии:
1. Думаю, ваш пример настолько сложен, что вам придется создать проблему для NLog-проекта и включить пример приложения, демонстрирующий проблему. github.com/NLog/NLog/issues/new/choose
Ответ №1:
Вы хотите, чтобы переменные конфигурации NLog вели себя двумя способами:
-
При редактировании файла NLog.config он должен отбросить существующие переменные конфигурации NLog и использовать их при перезагрузке обновленного NLog.config.
-
Для этого требуется, чтобы вы настроили
KeepVariablesOnReload=false
(по умолчанию)- Было бы проще, если бы вы включили NLog.config в свой вопрос. Вместо того, чтобы угадывать.
-
-
После перезагрузки NLog.config остается одна переменная конфигурации NLog (
${var:regionName}
), которую вы хотели бы сохранить.-
Поскольку вы настроили
KeepVariablesOnReload=false
(по умолчанию), я предполагаю, что вы подключились кLogManager.ConfigurationReloaded
-event и переназначили его вручную.- Было бы проще, если бы вы включили в свой вопрос логику динамического присвоения переменной конфигурации NLog. Вместо того, чтобы угадывать.
-
Событие LogManager.ConfigurationReloaded
-event вызывается после назначения и инициализации перезагруженной конфигурации NLog. Таким образом, любое ведение журнала происходит до тех пор, пока динамически переназначенное значение ${var:regionName}
не получит пустое значение. Смотрите также https://github.com/NLog/NLog/pull/3954 и https://github.com/NLog/NLog/pull/3952
Текущий обходной путь — прекратить использование LogManager.ConfigurationReloaded
-event и вместо этого просто использовать глобальный диагностический контекст NLog (GDC) для единственной переменной конфигурации NLog, которую необходимо восстанавливать при каждой перезагрузке. Таким образом, это становится ${gdc:regionName}
, и вы назначаете его так (один раз при запуске):
NLog.GlobalDiagnosticsContext.Set("regionName", "Europe");
Смотрите также: https://github.com/NLog/NLog/wiki/Gdc-layout-renderer
Комментарии:
1. Мы устанавливаем для keepVariablesOnReload значение true, чтобы избежать необходимости устанавливать его каждый раз, когда config.xml файл перезагружается. Вот почему я смущен поведением.
2. @cakeby Тогда я также не понимаю, как вы на самом деле меняете другие переменные NLog-config 🙂
3. @cakeby Рад, что мой ответ может помочь вам включить более подробную информацию в ваш вопрос. Вам все еще не хватает, какую версию NLog вы используете, и как / когда вы динамически обновляете
regionName
config-переменную.4. @cakeby Думаю, что ваш пример настолько сложный, что вам придется создать проблему для NLog-проекта и включить пример приложения, демонстрирующий проблему. github.com/NLog/NLog/issues/new/choose
5. Использование GDC в любом случае устранило нашу проблему. Спасибо.