编写事件日志条目的最佳方法是什么?

Tre*_*reb 14 .net event-log

我最近在部署Windows服务时遇到了问题.四台计算机没有造成任何问题,但在第五台计算机上由于异常而导致启动服务的任何尝试都失败了.异常堆栈跟踪被写入事件日志,因此我应该很容易确定原因:

protected override void OnStart(string[] args)
{
    EventLog.WriteEntry("Starting service", EventLogEntryType.Information);

    try
    {
        //...
        base.OnStart(args);
    }
    catch (Exception ex)
    {
        EventLog.WriteEntry("Service can not start. Stack trace:" + ex.StackTrace, EventLogEntryType.Error);
        Stop();
        return;
    }

    EventLog.WriteEntry("Service started", EventLogEntryType.Information);           
}
Run Code Online (Sandbox Code Playgroud)

但是,唉,没有任何信息写入日志.我终于将它追溯到正在编写的第一个日志条目.它引发了一个异常,因为应用程序事件日志已满,包含最近的条目,并且配置为仅覆盖超过7天的条目.

考虑到我无法更改应用程序事件日志的配置,写入事件日志的最佳做法是什么?

我应该总是放入EventLog.WriteEntry一个try块,如果是,我应该如何处理异常(将它写入事件日志可能是一个坏主意),我应该检查我的OnStart方法中的事件日志状态,还是你有更好的建议?

小智 11

使用log4net

使用log4net的优点是,您可以检查日志记录并对其进行控制,其灵活性远远超出您在代码中的考虑范围.

如果您正在登录事件日志,并且看到问题而没有事件日志条目,那么您可以始终切换到文件追加器日志并看到它正常工作......然后会告诉您这是与之相关的事情事件日志.

log4net也是防御性的,如果它无法写入日志条目,它不会崩溃你的程序.所以你不会看到这种情况发生(所以你不会有你的日志文件,但你的程序会运行,你可以再次指定第二个日志记录方法来获取日志文件).

log4net文档中的关键位是:

[log4net]是尽力而为的故障停止日志记录系统.

通过故障停止,我们的意思是log4net不会在运行时抛出意外异常,从而可能导致应用程序崩溃.如果由于任何原因,log4net抛出一个未捕获的异常(可能抛出的ArgumentException和ArgumentNullException除外),请发送电子邮件至log4net-user@logging.apache.org邮件列表.未捕获的异常被视为需要立即关注的严重错误.

此外,当指定的输出流未打开,不可写或变满时,log4net将不会还原为System.Console.Out或System.Console.Error.这样可以避免因为日志记录失败而淹没用户终端而破坏其他工作程序.但是,log4net将向System.Console.Error和System.Diagnostics.Trace输出单个消息,指示无法执行日志记录.

(我的重点)

对于大多数事情,有一个图书馆比你做得更好.最好的事情是永远不会重新发明,log4net解决了登录.Net的问题,让你的生活更轻松.

  • 实际上,log4net确实能够导致应用程序崩溃(至少紧凑的框架/ Windows移动应用程序) - 有点.使用log4net的UDP appender会使ActiveSync(将设备连接到PC)崩溃.我在演示中了解到这一点,我们失去了巨大的联系. (3认同)

Men*_*elt 2

我认为记录异常是极少数情况之一,最好吞下异常。在大多数情况下,您不希望您的应用程序在此方面失败。

但你为什么要自己编写日志代码呢?使用 NLog 或 Log4Net 等框架!正如我刚才所说,这些也会吞下异常,但您只需更改配置即可将日志输出重定向到不同的位置(文件、消息框等)。这使得解决此类问题变得更加容易。

  • 写入事件日志并不是“自己编写日志代码”。 (17认同)
  • <讽刺>你为什么要编写自己的服务呢,Windows 预装了大量的 Windows 服务!你所要做的就是启动其中一个!..否则,只需谷歌“服务”,你就会看到数百万个,当然其中一个可以满足你的要求..不要重新发明轮子人</讽刺> (12认同)
  • System.Diagnostics.EventLog 是一个内置的 .NET 类,用于写入 Windows 事件日志,而不是他们自己编写的东西。 (7认同)