Log4Net smtp appender只在错误时发送电子邮件与完整的日志(调试&信息,错误).仅在应用程序结束时使用

本文关键字:错误 信息 调试 应用程序 结束 appender smtp 电子邮件 Log4Net 日志 | 更新日期: 2023-09-27 17:54:44

我正在尝试在log4net中配置smtp附加程序。配置文件,我有。问题是,我已经看遍了互联网,找不到如何发送电子邮件时,错误发生与所有其他日志信息,如信息,调试,错误,致命。只在应用程序结束时(不是每次发生错误时)。

所以我只想在以下情况下收到这封邮件:应用程序结束+带有所有日志信息(DEBUG, INFO, ERROR, FATAL) +

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

谢谢。

Log4Net smtp appender只在错误时发送电子邮件与完整的日志(调试&信息,错误).仅在应用程序结束时使用

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

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

在程序结束时,我检查内存附加程序,看看它的GetEvents()是否包含任何事件。如果是,I 阻止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>

在应用程序结束时,如果ErrorHolder appender为空,运行此命令来禁用SmtpAppender:

// 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();
    }
}

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

第三种选择是使用log4net将错误发送到第二个日志文件(这样它们就会出现在两个地方)。然后,当您的应用程序关闭并且您正在检查是否应该通过电子邮件发送日志时,只需检查是否存在仅限错误的文件。如果它存在,删除它(这样下次就不存在了),并通过电子邮件发送完整的日志。

将阈值更改为错误。此外,log4net只在应用程序关闭时发送电子邮件。你可以早点寄过来。但是你首先需要复制它(因为org文件仍在使用中),然后你可以通过电子邮件发送副本。