NLog 多文件目标问题

NLog multiple file target issue

我正在尝试在 WPF 应用程序中实现 NLog。

我们需要有两个文件日志目标,

1) 用于调试或开发人员目的,这会有些 "Infologs" 文件夹
2) 用于某些错误或异常目的 "Errorlogs" 个文件夹在

基本目录。下面是我在 nlog.config 中的代码和配置。

<variable name="ErrorLayout" value="${longdate} | ${logger} | ${level} | 
${message} ${exception:format=message,stacktrace:separator=/}" />
<variable name="InfoLayout" value="${longdate} | ${logger} | ${level} | 
${message}"/>

<variable name="ErrorDir" value="${basedir}/Errorlogs/${longdate}">
</variable>
<variable name="InfoDir" value="${basedir}/Infologs/${longdate}"></variable>

<target xsi:type="File" name="fileLogException" archiveEvery="Month" 
createDirs="true" lineEnding="Default" layout="${ErrorLayout}" 
fileName="${ErrorDir}.log"/>

<target xsi:type="File" name="fileLogInfo" archiveEvery="Month" 
createDirs="true" lineEnding="Default" layout="${InfoLayout}" 
fileName="${InfoDir}.log"/>


<logger name="*"  minlevel="Error" writeTo="fileLogException"/>
<logger name="*"  minlevel="Info" writeTo="fileLogInfo"/>

预期结果:

_logger.Info("Sample informational message");//This should  write to only fileLogInfo

_logger.Error("Sample error message"); //this  should write to only fileLogException

_logger.Fatal("Sample fatal error message"); //this  should write to only fileLogException

当前结果:

_logger.Info() write to --> fileLogInfo

_logger.Error() & _logger.Fatal() both  write to --> fileLogInfo and fileLogException

任何帮助,谢谢

第一个 <logger> 规则需要 final 属性

<logger name="*"  minlevel="Error" writeTo="fileLogException" final="true"/>
<logger name="*"  minlevel="Info" writeTo="fileLogInfo"/>

默认情况下规则是非最终的,因此事件将写入所有记录器(从上到下),满足名称和(最小)级别要求。

欲了解更多信息,see the docs

这里有多种方法。在我看来,选项 3. 是您当前案例的最佳解决方案。

1。 final 属性

(这与 Julian 的答案相同)

<logger name="*"  minlevel="Error" writeTo="fileLogException" final="true"/>
<logger name="*"  minlevel="Info" writeTo="fileLogInfo"/>

将属性添加到fileLogException意味着当消息被写入fileLogException时,NLog不会在之后寻找任何其他日志。
请注意,NLog 从上到下评估记录器。 final 只会阻止 较低的 记录器接收相同的日志消息。

这是一个解决方案,但将来可能会导致问题。如果删除 fileLogException(或更改记录器的顺序),则 fileLogInfo 的内容将更改(因为 fileLogException 不再停止任何消息)。

When should you use this option?
When you want to intercept messages and prevent them from being added to other logs.
For your current example, this seems usable at first sight. This is mainly because you are not separating loggers based on their name. But when you start considering loggers with name requirements and not just level requirements, e.g.

<logger name="MyApplication.Repositories.*" final="true" writeTo="fileLogRepository" />
<logger name="MyApplication.Importers.*" final="true" writeTo="fileLogImport" />
<logger name="*" writeTo="fileLogAllUnloggedMessages" />

it becomes more obvious when you should and shouldn't use this. In the above example, the bottom log will catch all messages except messages which have already been logged by any previous logger (which was marked as final, of course).

2。 maxLevel 属性

就像您使用 minLevel 一样,还有一个 maxLevel 属性。

<logger name="*"  minlevel="Error" writeTo="fileLogException"/>
<logger name="*"  minlevel="Trace" maxLevel="Info" writeTo="fileLogInfo"/>

fileLogException 记录级别为 Error 及以上的所有消息,而 fileLogInfo 记录级别为 TraceInfo(=TraceDebugInfo)。

When should you use this option?
When you want to strictly define your logger to only ever include messages between a range of accepted log levels.

我更改了级别值以证明一个观点,即它会选择级别在上限 (maxLevel) 和下限 (minLevel) 之间的所有消息.

3。 level 属性

您的 fileLogException 只对 一个 级别的消息感兴趣,Info。因此,您可以将其缩短为

<logger name="*" level="Info" writeTo="fileLogInfo"/>

When should you use this option?
When you want to strictly define your logger to only ever include messages from a single log level.

4。 levels 属性

levels 属性允许您明确指定多个级别(以逗号分隔)。

    <logger name="*" levels="Trace,Info,Fatal" writeTo="fileLogException"/>

When should you use this option?
When you want to strictly define your logger to only ever include messages from multiple log levels that cannot be described with a range.

E.g. If you want to log Info and Error messages, and you would use maxLevel and minLevel, then Nlog would also include all Warning messages (as that falls between Info and Error in the ordered list of log levels). However, you can exclude Warning messages by using levels="Info,Error".


All information is based on the NLog documentation