gpt4 book ai didi

c# - 用BufferingTargetWrapper包裹的NLog FileTarget如果有延迟写日志失败

转载 作者:太空宇宙 更新时间:2023-11-03 21:51:42 25 4
gpt4 key购买 nike

我可能偶然发现了 NLog 的问题,但我想我会先在这里查看答案:

为了重现这个问题,我克隆了 NLog 源代码,这样我就可以添加一个延迟来导致这个问题。在 visual studio 中打开后,我添加了一个控制台应用程序,它引用 NLog 源项目并进行一些非常简单的日志调用。 NLog.config 如下:

<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 而不是重新创建问题更容易)。

打开 FileTarget.cs 并找到 Write(AsyncLogEventInfo[] logEvents)方法。在第一行插入 Thread.Sleep(5000)使得该方法如下所示:

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

// ... omitted
}

现在,编译并重新运行。日志没写。

据我所知,当进程退出时刷新所有目标的逻辑使用了一个默认超时为 15 秒的异步方法调用,这可以在 LogFactory.cs Flush() 中找到。方法 - 这显然没有被超过。

但是,NLog 使用了 ThreadPool.QueueUserWorkItem() (在 AsyncHelpers.cs 中找到)以并行编排每个目标的刷新。这是否可以简单地归结为这种形式的方法调用如何响应对 Thread.Sleep() 的调用的问题? ,或任何其他形式的阻止(例如连接到远程服务器,如我原来的问题)?

有什么想法吗?

最佳答案

我终于弄清楚为什么什么都没有记录,不幸的是,对此我们无能为力。

根据 AppDomain.ProcessExit 的 MSDN 文档,这是 NLog 处理的事件:

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()

关于c# - 用BufferingTargetWrapper包裹的NLog FileTarget如果有延迟写日志失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14226353/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com