NLog多文件目标问题

时间:2017-09-01 06:18:49

标签: c# wpf nlog

我正在尝试在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

请帮忙,谢谢

2 个答案:

答案 0 :(得分:2)

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

1。 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)。

2。 maxLevel属性

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

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

fileLogException会记录级别为Error及以上的所有邮件,而fileLogInfo会记录级别TraceInfo之间的所有邮件(= TraceDebugInfo)。

  

什么时候应该使用此选项?
  如果您想严格定义记录器,只能在一系列可接受的日志级别中包含消息。

我更改了级别值以证明某一点,它选择了级别在上限(maxLevel)和下限(minLevel)之间的所有邮件

3。 level属性

您的fileLogException仅对一个级别的邮件Info感兴趣。因此,您可以将其缩短为

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

什么时候应该使用此选项?
  如果您想严格定义记录器,只能在单个日志级别
中包含消息

4。 levels属性

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

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

什么时候应该使用此选项?
  如果您希望严格定义记录器,只能包含来自多个日志级别的消息,而这些消息无法用范围来描述。

     

E.g。如果您要记录InfoError消息,并且您将使用maxLevelminLevel,则Nlog还会包含所有Warning消息(因为在有序的日志级别列表中的InfoError之间)。但是,您可以使用Warning排除levels="Info,Error"条消息。

All information is based on the NLog documentation

答案 1 :(得分:0)

您需要第一个final规则

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

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

有关详细信息,请see the docs