【问题标题】:NLog multiple file target issueNLog 多文件目标问题
【发布时间】:2017-09-01 06:18:49
【问题描述】:

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

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

1) 用于调试或开发目的,其中包含一些“信息日志” 文件夹
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

请帮忙,谢谢

【问题讨论】:

    标签: c# wpf nlog


    【解决方案1】:

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

    1。 final 属性

    (这与朱利安的答案相同)

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

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

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

    什么时候应该使用这个选项?
    当您想要拦截消息并防止它们被添加到其他日志时。
    对于您当前的示例,乍一看似乎很有用。这主要是因为您没有根据它们的名称来分隔记录器。但是当您开始考虑具有name 要求而不仅仅是级别要求的记录器时,例如

    &lt;logger name="MyApplication.Repositories.*" final="true" writeTo="fileLogRepository" /&gt;
    &lt;logger name="MyApplication.Importers.*" final="true" writeTo="fileLogImport" /&gt;
    &lt;logger name="*" writeTo="fileLogAllUnloggedMessages" /&gt;

    什么时候应该和不应该使用它变得更加明显。在上面的示例中,底部日志将捕获所有消息除了已被任何先前记录器记录的消息(当然标记为final)。

    2。 maxLevel 属性

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

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

    fileLogException 记录所有级别为Error 及以上的消息,而fileLogInfo 记录所有级别介于TraceInfo 之间的消息 (= Trace, DebugInfo)。

    什么时候应该使用这个选项?
    当您想严格定义您的记录器以仅包含一系列可接受的日志级别之间的消息时。

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

    3。 level 属性

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

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

    什么时候应该使用这个选项?
    当您想严格定义您的记录器以仅包含来自单个日志级别的消息时。

    4。 levels 属性

    levels 属性允许您显式指定多个级别(逗号分隔)。

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

    什么时候应该使用这个选项?
    当您想严格定义您的记录器以仅包含来自多个日志级别的消息无法用范围描述

    例如如果您想记录InfoError 消息,并且您将使用maxLevelminLevel,那么Nlog 还将包括所有Warning 消息(因为它介于InfoError 之间日志级别的有序列表)。但是,您可以使用levels="Info,Error" 排除Warning 消息。


    All information is based on the NLog documentation

    【讨论】:

      【解决方案2】:

      第一个&lt;logger&gt; 规则需要final 属性

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

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

      欲了解更多信息,see the docs

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多