我正在尝试在WPF应用程序中实现NLog。
我们需要有两个文件日志目标
1)用于调试或开发目的,这是一些“Infologs”
文件夹
2)出于错误或异常目的,这将是一些
基目录。下面是我在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
请帮忙,谢谢
答案 0 :(得分:2)
这里有多种方法。在我看来,选项 3。是您当前案例的最佳解决方案。
final
属性(这与朱利安的答案相同)
<logger name="*" minlevel="Error" writeTo="fileLogException" final="true"/>
<logger name="*" minlevel="Info" writeTo="fileLogInfo"/>
将属性添加到fileLogException
意味着当消息写入fileLogException
时,NLog将不会在之后查找任何其他日志。
请注意,NLog从上到下评估记录器。 final
只会阻止较低记录器接收相同的日志消息。
这是一个解决方案,但它可能会在将来引发问题。如果您删除fileLogException
(或更改记录器的顺序),则fileLogInfo
的内容将会更改(因为fileLogException
不再阻止任何消息)。
什么时候应该使用此选项?
当您想拦截消息并阻止它们被添加到其他日志时 对于您当前的示例,这看起来似乎很有用。这主要是因为您没有根据名称分离记录器。但是,当您开始考虑具有name
要求的记录器而不仅仅是级别要求时,例如
<logger name="MyApplication.Repositories.*" final="true" writeTo="fileLogRepository" />
<logger name="MyApplication.Importers.*" final="true" writeTo="fileLogImport" />
<logger name="*" writeTo="fileLogAllUnloggedMessages" />
当你应该而且不应该使用它时,它会变得更加明显。在上面的示例中,底部日志将捕获所有消息除了消息,这些消息已被任何先前的记录器记录(当然,标记为
final
)。
maxLevel
属性就像您使用minLevel
一样,还有一个maxLevel
属性。
<logger name="*" minlevel="Error" writeTo="fileLogException"/>
<logger name="*" minlevel="Trace" maxLevel="Info" writeTo="fileLogInfo"/>
fileLogException
会记录级别为Error
及以上的所有邮件,而fileLogInfo
会记录级别在Trace
和Info
之间的所有邮件(= Trace
,Debug
和Info
)。
什么时候应该使用此选项?
如果您想严格定义记录器,只能在一系列可接受的日志级别中包含消息。
我更改了级别值以证明某一点,它选择了级别在上限(maxLevel
)和下限(minLevel
)之间的所有邮件的
level
属性您的fileLogException
仅对一个级别的邮件Info
感兴趣。因此,您可以将其缩短为
<logger name="*" level="Info" writeTo="fileLogInfo"/>
什么时候应该使用此选项?
如果您想严格定义记录器,只能在单个日志级别中包含消息。
levels
属性 levels
属性允许您明确指定多个级别(以逗号分隔)。
<logger name="*" levels="Trace,Info,Fatal" writeTo="fileLogException"/>
什么时候应该使用此选项?
如果您希望严格定义记录器,只能包含来自多个日志级别的消息,而这些消息无法用范围来描述。E.g。如果您要记录
Info
和Error
消息,并且您将使用maxLevel
和minLevel
,则Nlog还会包含所有Warning
消息(因为在有序的日志级别列表中的Info
和Error
之间)。但是,您可以使用Warning
排除levels="Info,Error"
条消息。
答案 1 :(得分:0)
您需要第一个final
规则
<logger>
属性
<logger name="*" minlevel="Error" writeTo="fileLogException" final="true"/>
<logger name="*" minlevel="Info" writeTo="fileLogInfo"/>
默认情况下,规则是非最终的,因此事件将写入所有记录器(从上到下),这些记录器符合名称和(最小)级别要求。
有关详细信息,请see the docs