NLOG FileTarget包裹着BufferingTargetWrapper未能写入日志,如果有一个延迟 [英] NLog FileTarget wrapped with BufferingTargetWrapper fails to write log if there is a delay

查看:274
本文介绍了NLOG FileTarget包裹着BufferingTargetWrapper未能写入日志,如果有一个延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可能已经跨越与NLOG问题迷迷糊糊的,但想到我会首先检查这里的答案:

I may have stumbled across an issue with NLog, but thought I would check here first for an answer:

要重新创建我克隆NLOG源,所以我的问题可以添加一个延迟造成的问题。一旦在Visual Studio中打开,我添加引用NLOG源项目,并提出了一些非常简单的日志调用控制台应用程序。该NLog.config如下:

To recreate the issue I cloned the NLog source so I could add a delay to cause the problem. Once open in visual studio, I added a console application that references the NLog source projects and makes some very simple log calls. The NLog.config is as follows:

<nlog>
  <targets>
    <target name="buffer" type="BufferingWrapper">
      <target name="logfile" type="File" fileName="log.txt"/>
    </target>
  </targets>
  <rules>
    <logger name="*" minlevel="Debug" writeTo="logfile" />
  </rules>
</nlog>



如预期到这一点,所有的作品。接下来的一步是将延迟插入的 FileTarget 刷新逻辑。 (我发现这是问题的原因是,我本来一起工作的 MailTarget 将挂起的持续时间,同时连接到邮件服务器 - 我已经取代它在 FileTarget 这里,而不是使重现的问题更容易)。

All works as expected up to this point. The next step is to insert a delay into the flush logic of the FileTarget. (The reason I found this to be the problem is that I was originally working with the MailTarget that would hang for a duration whilst connecting to the mail server - I have substituted it for the FileTarget here instead to make recreating the problem easier).

打开FileTarget.cs并找到写(AsyncLogEventInfo [] LOGEVENTS)方法。将在第一行 Thread.sleep代码(5000),以便该方法如下图所示:

Open the FileTarget.cs and locate the Write(AsyncLogEventInfo[] logEvents) method. Insert in the first line Thread.Sleep(5000) so that the method appears as below:

protected override void Write(AsyncLogEventInfo[] logEvents)
{
    Thread.Sleep(5000);

    // ... omitted
}

现在,编译和重新运行。该日志不会被写入。

Now, compile and re-run. The log is not written.

据我所知道的,逻辑刷新所有目标,当进程退出使用具有15个默认的超时异步方法调用可在LogFactory.cs 同花顺()方法找到秒钟 - 这显然是不超出

As far as I can tell, the logic to flush all targets when the process exits uses an asynchronous method call that has a default timeout of 15 seconds which can be found in the LogFactory.cs Flush() method - this is obviously not being exceeded.

然而,NLOG利用 ThreadPool.QueueUserWorkItem的()(在AsyncHelpers.cs找到),以协调各目标的冲洗并行。难道这只是归结到如何这种形式的方法调用的一个呼叫作出反应 Thread.sleep代码(),或阻止任何其他形式(如连接问题到远程服务器,在我原来的问题)?

However, NLog makes use of ThreadPool.QueueUserWorkItem() (found in AsyncHelpers.cs) to orchestrate the flushing of each target in parallel. Could this simply boil down to a question of how does this form of method invocation react to a call to Thread.Sleep(), or any other form of blocking (such as connecting to a remote server, as in my original problem)?

任何想法?

推荐答案

我终于想通了,为什么没有被记录下来,遗憾的是没有太多可以了解这个完成。

I have finally figured out why nothing is being logged, unfortunately there is not much that can be done about this.

根据MSDN文档< A HREF =htt​​p://msdn.microsoft.com/en-us/library/system.appdomain.processexit.aspx相对=nofollow> AppDomain.ProcessExit ,这是NLOG处理该事件:

According to the MSDN documentation for AppDomain.ProcessExit, which is the event handled by NLog:

所有ProcessExit事件处理程序的总执行时间是有限的,
正如所有终结的总执行时间是在限制
进程关闭。默认为两秒钟。一个非托管主机可以通过调用
ICLRPolicyManager :: setTimeout的方法与OPR_ProcessExit
枚举值
改变这个执行时间。

The total execution time of all ProcessExit event handlers is limited, just as the total execution time of all finalizers is limited at process shutdown. The default is two seconds. An unmanaged host can change this execution time by calling the ICLRPolicyManager::SetTimeout method with the OPR_ProcessExit enumeration value.

所以,它似乎从托管代码处理这个问题的唯一办法,就是手动调用 LogManager.Flush()允许应用程序退出之前。

So it seems the only way to handle this from managed code, is to manually call LogManager.Flush() before allowing the application to exit.

这篇关于NLOG FileTarget包裹着BufferingTargetWrapper未能写入日志,如果有一个延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆