c# - NLog AsyncWrapper 和 FallbackTarget 不能一起工作

标签 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>

最佳答案

我不知道 AsyncWrapper 和 FallbackTarget 之间的关系,我试图找到自己应该包装哪个,但我可以告诉你,你需要调用 LogManager.Flush() AsyncWrapper 来写入日志,您也可以将整个内容包装到 AutoFlushTargetWrapper 中,我认为这与通过 XML conf autoFlush="true" 相同,例如:

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

这将 FileTarget 包装在 AutoFlushTargetWrapper 中。

不幸的是,我无法建议正确的包装顺序。 我希望这个答案至少能为您指明正确的方向。

关于c# - NLog AsyncWrapper 和 FallbackTarget 不能一起工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28762476/

相关文章:

c# - 如何使用仅替换 www 的第一次出现

c# - C# 中带有 char 键的不区分大小写的字典

c# - 为什么递减一个变量会修改 C# Parallel.ForEach 循环中另一个变量的递增?

nlog - 仅当数据库失败时才登录文件?

asp.net - 如何使用身份验证通过 NLog 或 SeriLog 登录到 Elastic Search

c# windows 服务配置文件

c# - 是否可以使用 FluentNHibernate 将具有空格的 varchar 映射到枚举

C# NLog 性能类变量

c# - 通过WCF向服务器发送NLog日志

c# - 根据方法参数使用不同的日志文件