NLog-正确的缓冲方式

时间:2019-07-09 16:25:25

标签: c# nlog buffering

问题

我们如何在NLog中读取日志缓冲区的内容?

详细信息

我在我的应用程序中配置了普通FileTargetBufferingTargetWrapper。每隔几分钟,我的应用程序就会运行一组步骤,并在此过程中记录一些消息。我想继续缓冲这些消息并在过程结束时刷新它们。在刷新时,我还想通过电子邮件发送当前批次中的所有消息。然后将缓冲区刷新到主日志文件,并为下一批做好准备。

我已经通过编程方式配置了记录器:

/// <summary>
/// Initializes global logging service
/// </summary>
private void InitLogger()
{
  var config = new LoggingConfiguration();

  var fileTarget = new FileTarget("MyService")
  {
    FileName = "${basedir}/myservice.log",
    Layout = "${longdate} ${level} ${message}  ${exception}"
  };
  config.AddTarget(fileTarget);

  var bufferTarget = new BufferingTargetWrapper("BufferLog", fileTarget);

  config.AddRuleForAllLevels(bufferTarget);

  LogManager.Configuration = config;
}

这是一个示例测试方法,可以准确显示我要实现的目标:

public static Logger Log => LogManager.GetLogger("BufferLog");

[TestMethod]
public void BufferedLogTest()
{
  InitLogger();

  Log.Info("Message 1");
  Log.Info("Message 2");
  Log.Info("Message 3");
  LogManager.Configuration.FindTargetByName<BufferingTargetWrapper>("BufferLog").Flush(new NLog.Common.AsyncContinuation((s) =>
  {
    //I want to send these 3 buffered messages through email and
    //flush them to the main log file, but s is null unfortunately
  }));
  Log.Info("Message 4");
  Log.Info("Message 5");
  Log.Info("Message 6");
  LogManager.Configuration.FindTargetByName<BufferingTargetWrapper>("BufferLog").Flush((s) =>
  {
    //I want to send next 3 buffered messages through email and
    //flush them to the main log file, but s is null again
  });
}

我期望BufferingTargetWrapper将其缓冲区的内容移交给目标函数,但事实并非如此。还有没有其他直接/间接访问缓冲区的方法。

1 个答案:

答案 0 :(得分:1)

在@RolfKristensen的评论(谢谢你)之后,事实证明它比我想象的要容易。我现在在我的NLog配置中创建两个Target。一个继续缓冲日志消息,直到我在每批处理结束时手动刷新它们为止,而另一个继续将它们写到主日志文件中。

万一这可以帮助任何人,这是我通过编程的方式进行此操作(您也可以通过配置文件来完成此操作):

/// <summary>
/// Initializes global logging service
/// </summary>
private void InitLogger()
{
  // Create configuration object 
  var Config = new LoggingConfiguration();

  // Create main target that continuously writes to the log file
  var FileTarget = new FileTarget("FileTarget")
  {
    FileName = "${basedir}/myservice.log",
    Layout = "${longdate} ${level} ${message}  ${exception}"
  };
  Config.AddTarget(FileTarget);

  //Create memory target that buffers log messages
  var MemTarget = new MemoryTarget("MemTarget");

  // Define rules
  Config.AddRuleForAllLevels(MemTarget);
  Config.AddRuleForAllLevels(FileTarget);

  // Activate the configuration
  LogManager.Configuration = Config;    
}

我现在可以像这样在每个批处理的末尾调用提取缓冲的消息:

var MemTarget = LogManager.Configuration.FindTargetByName<MemoryTarget>("MemTarget");
//Do whatever you want with buffered messages in MemTarget.Logs
MemTarget.Logs.Clear();