9

我正在尝试在我拥有的 log4net.config 文件中配置一个 smtp 附加程序。问题是我已经查看了整个互联网,并且找不到在包含所有其他日志信息(例如信息,调试,错误,致命)的错误发生时如何发送电子邮件。仅在应用程序结束时(不是每次发生错误时)。

所以我只想在以下情况下收到这封电子邮件:应用程序结束+所有日志信息(DEBUG、INFO、ERROR、FATAL)+仅当发生错误时。

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

谢谢。

4

3 回答 3

6

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

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

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

两个附加程序的 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如果ErrorHolderappender 为空,则运行此命令以禁用:

// 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();
    }
}
于 2011-05-06T04:42:23.007 回答
2

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

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

于 2011-05-05T14:42:58.583 回答
0

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

于 2016-02-18T10:24:56.380 回答