NLog:重新加载时登录错误的文件
NLog: Logs in wrong file on reload
我们有一个配置文件,由我们的 GUI 编辑以动态更改我们的文件目标的日志级别。
我们的文件名如下所示:fileName="${logDir}${var:subLogDir}/${var:regionName}${logName}.dlog"
所有变量都在程序的基本 .config 文件中,并且在程序启动时通过设置动态设置 regionName
通过 NLog.LogManager.Configuration.Variables["regionName"] = string.Concat(RegionName, "/");.
直接在配置中变量
我们的问题是当我们在程序生成日志的时候修改日志级别,会有一个时刻日志会直接落到${var:subLogDir}中,就好像${var:regionName}是即使我们知道它也没有设置。
似乎有一段时间动态变量还没有解决。我们可以做些什么来防止这种情况发生吗?重新加载时缓冲日志?
NLog 版本:4.7.4
.config 文件
<nlog keepVariablesOnReload="true">
<variable name="subLogDir" value="/Regions" />
<include file="..\Common\Logs\BaseVariables.xml" />
<include file="..\Common\Logs\BaseTargets.xml" />
<include file="..\Common\Logs\BaseRules.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>
谢谢
您希望 NLog 配置变量以两种方式运行:
当编辑 NLog.config 文件时,它应该丢弃现有的 NLog 配置变量并在重新加载更新的 NLog.config.
时使用这些变量
这需要您配置KeepVariablesOnReload=false
(默认)
- 如果您在问题中包含 NLog.config 会更容易。而不是猜测。
重新加载 NLog.config 后,有一个 NLog 配置变量 (${var:regionName}
) 您想要保留。
因为您已经配置了 KeepVariablesOnReload=false
(默认),所以我猜您已经连接到 LogManager.ConfigurationReloaded
-事件并手动重新分配它。
- 如果您在问题中包含了动态分配 NLog 配置变量的逻辑,那就更容易了。而不是猜测。
LogManager.ConfigurationReloaded
-事件在重新加载的 NLog 配置被分配和初始化后被调用。因此,在动态重新分配 ${var:regionName}
之前发生的任何日志记录都将获得空值。另见 https://github.com/NLog/NLog/pull/3954 and https://github.com/NLog/NLog/pull/3952
当前的解决方法是停止使用 LogManager.ConfigurationReloaded
-event,而只是将 NLog 全局诊断上下文 (GDC) 用于需要在每次重新加载时恢复的单个 NLog 配置变量。所以它变成 ${gdc:regionName}
并且你像这样分配它(在启动时一次):
NLog.GlobalDiagnosticsContext.Set("regionName", "Europe");
我们有一个配置文件,由我们的 GUI 编辑以动态更改我们的文件目标的日志级别。
我们的文件名如下所示:fileName="${logDir}${var:subLogDir}/${var:regionName}${logName}.dlog" 所有变量都在程序的基本 .config 文件中,并且在程序启动时通过设置动态设置 regionName 通过 NLog.LogManager.Configuration.Variables["regionName"] = string.Concat(RegionName, "/");.
直接在配置中变量我们的问题是当我们在程序生成日志的时候修改日志级别,会有一个时刻日志会直接落到${var:subLogDir}中,就好像${var:regionName}是即使我们知道它也没有设置。
似乎有一段时间动态变量还没有解决。我们可以做些什么来防止这种情况发生吗?重新加载时缓冲日志?
NLog 版本:4.7.4
.config 文件
<nlog keepVariablesOnReload="true">
<variable name="subLogDir" value="/Regions" />
<include file="..\Common\Logs\BaseVariables.xml" />
<include file="..\Common\Logs\BaseTargets.xml" />
<include file="..\Common\Logs\BaseRules.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>
谢谢
您希望 NLog 配置变量以两种方式运行:
当编辑 NLog.config 文件时,它应该丢弃现有的 NLog 配置变量并在重新加载更新的 NLog.config.
时使用这些变量这需要您配置
KeepVariablesOnReload=false
(默认)- 如果您在问题中包含 NLog.config 会更容易。而不是猜测。
重新加载 NLog.config 后,有一个 NLog 配置变量 (
${var:regionName}
) 您想要保留。因为您已经配置了
KeepVariablesOnReload=false
(默认),所以我猜您已经连接到LogManager.ConfigurationReloaded
-事件并手动重新分配它。- 如果您在问题中包含了动态分配 NLog 配置变量的逻辑,那就更容易了。而不是猜测。
LogManager.ConfigurationReloaded
-事件在重新加载的 NLog 配置被分配和初始化后被调用。因此,在动态重新分配 ${var:regionName}
之前发生的任何日志记录都将获得空值。另见 https://github.com/NLog/NLog/pull/3954 and https://github.com/NLog/NLog/pull/3952
当前的解决方法是停止使用 LogManager.ConfigurationReloaded
-event,而只是将 NLog 全局诊断上下文 (GDC) 用于需要在每次重新加载时恢复的单个 NLog 配置变量。所以它变成 ${gdc:regionName}
并且你像这样分配它(在启动时一次):
NLog.GlobalDiagnosticsContext.Set("regionName", "Europe");