Log4Net smtp appender仅在出现完整日志错误时发送电子邮件(debug& info& error)。仅在申请结束时

时间:2011-05-05 08:43:19

标签: c# .net smtp log4net log4net-configuration

我正在尝试在log4net.config文件中配置smtp appender。问题是我已经浏览了整个互联网,并且无法找到如何在包含所有其他日志信息(如info,debug,error,fatal)发生错误时发送电子邮件。仅在应用程序结束时(不是每次发生错误时)。

所以我只希望在以下情况下收到此电子邮件:   申请结束+   包含所有日志信息(DEBUG,INFO,ERROR,FATAL)+   只有发生了错误。

详细说明这是因为我在c sharp中处理异常的方式,在整个地方进行多级处理,因此如果发生错误,无论多少次我只想接收一封电子邮件。此外,我不想使用多个日志,而是 只有一个在根。

感谢。

3 个答案:

答案 0 :(得分:6)

SmtpAppender无法独立完成此任务。所以我所做的是为MemoryAppender类型的追加器创建另一个追加器。我在此记录器上设置了一个阈值,仅包含应触发SmtpAppender的消息,例如Error。我们使用它来确定是否要发送记录了更多级别的电子邮件。

我们实际上并不关心MemoryAppender中的消息 - 我们只关心它最后包含消息。我们通过电子邮件收到的邮件实际上来自SmtpAppender

在我的程序结束时,我检查内存appender以查看它的GetEvents()是否包含任何事件。如果是这样,我阻止SmtpAppender正常运行。

两个appender的Log4Net配置:

<appender name="ErrorHolder" type="log4net.Appender.MemoryAppender" >
    <onlyFixPartialEventData value="true" />
    <!-- if *any* message is logged with this level, the email appender will 
         be used with its own level -->
    <threshold value="ERROR" />
</appender>

<appender name="Email" type="log4net.Appender.SmtpAppender">    
    <!-- the level you want to see in the email IF ErrorHolder finds anything -->
    <threshold value="INFO"/> 
    <bufferSize value="512" />
    <lossy value="false" /> <!-- important! -->   
    <to value="name@domain.com" />
    <from value="name@domain.com" />
    <subject value="ERROR: subject" />
    <smtpHost value="smtpserver" />    
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
    </layout>    
</appender>

<root>
  <level value="ALL" />
  <appender-ref ref="ErrorHolder" />
  <appender-ref ref="Email" />
</root>

在应用程序结束时,如果SmtpAppender appender为空,则运行此选项以禁用ErrorHolder

// trigger loggers if errors occurred:
var memoryAppender = ((Hierarchy)LogManager.GetRepository())
    .Root.Appenders.OfType<MemoryAppender>().FirstOrDefault();

if (memoryAppender != null && memoryAppender.GetEvents().Length == 0)
{
    // there was no error so don't email anything
    var smtpAppender = ((Hierarchy)LogManager.GetRepository())
        .Root.Appenders.OfType<SmtpAppender>().FirstOrDefault();

    if (smtpAppender != null)
    {
        smtpAppender.Threshold = Level.Off;
        smtpAppender.ActivateOptions();
    }
}

答案 1 :(得分:2)

这听起来像应用程序配置问题而不是log4net配置问题。我建议在应用程序结束时放入一个方法,如果它检测到其中有错误,则会通过电子邮件发送给您日志文件。您可以通过在记录错误的每个位置将全局变量从false翻转为true来检测此错误,或者可以等到应用程序结束,然后读取日志文件以查看它是否包含错误。关闭时第一种方法会更快,但这意味着在多个位置修改代码。后者允许您只添加一个方法,但在大文件中可能需要更长时间。

第三种选择是使用log4net将错误发送到第二个日志文件(因此它们会转到两个位置)。然后,当您的应用程序关闭并且您正在检查是否应该通过电子邮件发送日志时,只需检查是否存在仅错误文件。如果存在,请将其删除(以便下次不存在)并通过电子邮件发送完整日志。

答案 2 :(得分:0)

将阈值更改为错误。此外,log 4net仅在应用程序为clodes时发送电子邮件。您可以提前发送。但是你首先需要复制它(因为org文件仍在使用中),而且你可以通过电子邮件发送副本。