简体   繁体   English

Log4Net smtp appender 仅在出现完整日志错误时发送 email(调试 & 信息 & 错误)。 仅当应用程序结束时

[英]Log4Net smtp appender only send email when error with full log(debug & info & error). Only when the application ends

I am trying to configure a smtp appender in the log4net.config file that I have.我正在尝试在我拥有的 log4net.config 文件中配置 smtp 附加程序。 The problem is that I have looked all over the internet and cannot find how to send an email when an error occurs with all the other log information included such as info, debug, error, fatal.问题是,当所有其他日志信息(如信息、调试、错误、致命)发生错误时,我已经查看了整个互联网,但找不到如何发送 email。 Only when the application ends (NOT every time an ERROR occurs).仅在应用程序结束时(不是每次发生错误时)。

So I only want to receive this email when: The application ends + With all the log information (DEBUG, INFO, ERROR, FATAL) + Only if an ERROR has occured.因此,我只想在以下情况下收到此 email:应用程序结束 + 包含所有日志信息(DEBUG、INFO、ERROR、FATAL)+ 仅当发生错误时。

Elaborating some more this is because of the way I handle my exceptions in c sharp, with multiple level handling all over the place and so if an error occurs no matter how many times I only want to receive one email.详细说明这是因为我在 c 中处理我的异常的方式尖锐,在整个地方都有多级处理,所以如果发生错误,无论多少次我只想收到一个 email。 Also I do not want to use multiple logs, but rather just one in root.此外,我不想使用多个日志,而只想使用根中的一个。

Thanks.谢谢。

SmtpAppender cannot accomplish this on its own. SmtpAppender无法自行完成此操作。 So what I did was create another appender that to an appender of type MemoryAppender .所以我所做的是为MemoryAppender类型的 appender 创建另一个 appender。 I set a threshold on this logger to only include messages that should trigger the SmtpAppender , eg Error .我在这个记录器上设置了一个阈值,只包含应该触发SmtpAppender的消息,例如Error We use this to later determine if we want to send the email which has more levels logged.我们稍后使用它来确定是否要发送记录了更多级别的 email。

We don't actually care about the messages in the MemoryAppender --we just care that it contains messages at the end.我们实际上并不关心MemoryAppender中的消息——我们只关心它最后是否包含消息。 The messages we get via email actually come from the SmtpAppender .我们通过 email 获得的消息实际上来自SmtpAppender

At the end of my program I check the memory appender to see if its GetEvents() contains any events.在我的程序结束时,我检查 memory 附加程序以查看其 GetEvents() 是否包含任何事件。 If so, I do not stop the SmtpAppender from running normally.如果是这样,我不会阻止SmtpAppender正常运行。

Log4Net configs for both appenders:两个附加程序的 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>

At the end of the app run this to disable the SmtpAppender if the ErrorHolder appender is empty:如果ErrorHolder附加程序为空,则在应用程序结束时运行此命令以禁用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();
    }
}

This sounds like an application configuration issue rather than a log4net configuration issue.这听起来像是应用程序配置问题,而不是 log4net 配置问题。 I would suggest putting a method in at the close of your application that emails you the log file if it detects that there is an error inside it.我建议在您的应用程序关闭时放置一个方法,如果它检测到其中存在错误,则通过电子邮件向您发送日志文件。 You could either detect this error by flipping a global variable from false to true in every place where you log errors or you could wait until the end of your application and then read the log file to see if it contains errors.您可以通过在记录错误的每个位置将全局变量从 false 翻转为 true 来检测此错误,或者您可以等到应用程序结束,然后读取日志文件以查看它是否包含错误。 The first method would be quicker at shutdown but it means modifying your code in multiple places.第一种方法在关机时会更快,但这意味着在多个地方修改你的代码。 The latter would allow you to just add one method but it might take longer in a large file.后者将允许您只添加一种方法,但在大文件中可能需要更长的时间。

A third option would be to send errors to a second log file (so they go two places) using log4net.第三种选择是使用 log4net 将错误发送到第二个日志文件(因此它们 go 两个地方)。 Then, when your application is closing and you are checking to see if you should email the log, just check for the existence of the error-only file.然后,当您的应用程序正在关闭并且您正在检查是否应该 email 日志时,只需检查仅错误文件是否存在。 If it exists, delete it (so it isn't there next time) and email the full log.如果存在,请将其删除(以便下次不再存在)和 email 完整日志。

change treshold to Error.将阈值更改为错误。 Also log 4net only sends the email when the app is clodes.you can send it earlier.另外log 4net只在应用程序是clodes时发送email。你可以提前发送。 but than you first need to copy it ( because the org file is still in use) and than you can email the copy.但是您首先需要复制它(因为 org 文件仍在使用中),然后您可以复制 email。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM