NLog AsyncWrapper和FallbackTarget无法一起使用

时间:2015-02-27 10:10:00

标签: c# nlog

我的自定义目标定义如下。

namespace TargetLib
{
    [NLog.Targets.Target("TestTarget")]
    public class TestTarget : TargetWithLayout
    {
        protected override void Write(AsyncLogEventInfo[] logEvents)
        {
            throw new ApplicationException("Test");
            foreach (AsyncLogEventInfo info in logEvents)
            {
                DoNothing(info.LogEvent);
            }
        }

        protected override void Write(LogEventInfo logEvent)
        {
            DoNothing(logEvent);
        }


        private void DoNothing(LogEventInfo logEvent)
        {
            Console.WriteLine(logEvent.Message);
        }
    }
}

我的NLog.config文件如下所示。我定义了一个回退组,然后为每个目标定义了异步包装器。

<extensions>
  <add assembly="TargetLib" />
</extensions>
<targets>
  <target name="defaultTarget" xsi:type="FallbackGroup"
returnToFirstOnSuccess="true">

    <target name="inMemoryTargetAsync" xsi:type="AsyncWrapper" timeToSleepBetweenBatches="1000" overflowAction="Grow">
      <target name="inMemoryTarget" xsi:type ="TestTarget"  />
    </target>

    <target name="fileTargetAsync" xsi:type="AsyncWrapper" timeToSleepBetweenBatches="1000" overflowAction="Grow">
      <target name="file" xsi:type="File"
          layout="${longdate} ${logger} ${message}"
          fileName="${basedir}/logs/logfile.txt"
          keepFileOpen="false"
          encoding="iso-8859-2" />
    </target>
  </target>
</targets>

<rules>
  <!-- add your logging rules here -->
  <logger name="*" minlevel="Info" writeTo="defaultTarget" />
</rules>

我有一个简单的控制台应用程序来测试它,如下所示:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Press enter to start logging:");
        Console.ReadLine();
        Logger logger = LogManager.GetLogger("Default");
        for (int i = 0; i < 200; i++)
        {
            logger.Log(LogLevel.Warn, "Test warning" + i.ToString());
        }
        Console.WriteLine("Logging complete. Press enter to exit.");
        Console.ReadLine();
    }
}

我面临的问题是,因为我的自定义目标会抛出异常。所以我希望我的所有日​​志消息都在FileTarget中。但是所有日志消息都不会进入文件。日志消息正在丢失。

另外,我尝试使用以下NLog.config。首先,我定义了AsyncWrapper,然后按如下方式回退目标。但在这种情况下,文件中不会出现任何内容,因为每次都会调用我的TestTarget同步LogEventInfo方法。因此没有异常发生,因此它不会后退。但我希望调用我的自定义目标的异步方法。虽然这是虚拟目标,但在实际目标中我想优化批量写入。请帮忙。

<extensions>
  <add assembly="TargetLib" />
</extensions>
<targets>
  <target name="defaultTarget" xsi:type="AsyncWrapper" timeToSleepBetweenBatches="1000" overflowAction="Grow">
    <target name="fallbackGrp" xsi:type="FallbackGroup" returnToFirstOnSuccess="true">
      <target name="inMemoryTarget" xsi:type ="TestTarget"  />
      <target name="file" xsi:type="File"
            layout="${longdate} ${logger} ${message}"
            fileName="${basedir}/logs/logfile.txt"
            keepFileOpen="false"
            encoding="iso-8859-2" />
    </target>
  </target>
</targets>

<rules>
  <!-- add your logging rules here -->
  <logger name="*" minlevel="Info" writeTo="defaultTarget" />
</rules>

1 个答案:

答案 0 :(得分:2)

我不知道AsyncWrapper和FallbackTarget之间的关系,我试图找到自己哪个应该包装哪个,但我可以告诉你需要调用LogManager.Flush()让AsyncWrapper写日志,你也可以将整个事物包装到AutoFlushTargetWrapper中,我认为它与通过XML conf autoFlush="true"一样:

...
<target name="logfile" xsi:type="File" fileName="${basedir}/logs.txt" autoFlush="true"> 

这包含AutoFlushTargetWrapper中的FileTarget。

不幸的是,我无法告知正确的包装顺序是什么。 我希望这个答案至少能指出你正确的方向。