在log4net中使用smtpAppender的多个smtphost地址

本文关键字:smtphost 地址 smtpAppender log4net | 更新日期: 2023-09-27 18:36:25

我希望能够指定多个smtp服务器主机地址并实现一个逻辑,即如果使用一个smtp服务器的电子邮件失败,它会尝试使用下一个smtp服务器地址发送。是否可以使用 log4net。我们可以覆盖log4net的某些功能并在其中实现我们自己的逻辑来发送电子邮件吗?

<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
  <to value="group@ivp.in" />
  <from value="uname@ivp.in" />
  <subject>Error Notification</subject>
  **<smtpHost value="10.0.0.12, 10.0.0.13" />**
  <authentication value="None" />
  <port value="25" />
  <bufferSize value="1" />
  <EnableSsl value="false"/>
  <lossy value="true" />
  <evaluator type="log4net.Core.LevelEvaluator">
    <threshold value="ERROR"/>
  </evaluator>
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%newline%date [%thread] %level %logger - %message%newline%newline%exception" />
  </layout>
</appender>

在log4net中使用smtpAppender的多个smtphost地址

有一个更简单的方法

<to value="group@ivp.in,group2@ivp.in,group3@ivp.in,group4@ivp.in" />

只有实现custom SmtpAppender才有可能。

我已经从 Log4net 源代码示例中复制了CustomSmtpAppender代码。 希望这会对您有所帮助。

不要忘记在应用配置中引用CustomSmtpAppender

using System;
using System.IO;
using System.Web.Mail;
using log4net.Layout;
using log4net.Core;
using log4net.Appender;
namespace SampleAppendersApp.Appender
{
    /// <summary>
    /// Simple mail appender that sends individual messages
    /// </summary>
    /// <remarks>
    /// This SimpleSmtpAppender sends each LoggingEvent received as a
    /// separate mail message.
    /// The mail subject line can be specified using a pattern layout.
    /// </remarks>
    public class SimpleSmtpAppender : AppenderSkeleton
    {
        public SimpleSmtpAppender()
        {   
        }
        public string To 
        {
            get { return m_to; }
            set { m_to = value; }
        }
        public string From 
        {
            get { return m_from; }
            set { m_from = value; }
        }
        public PatternLayout Subject 
        {
            get { return m_subjectLayout; }
            set { m_subjectLayout = value; }
        }
        public string SmtpHost
        {
            get { return m_smtpHost; }
            set { m_smtpHost = value; }
        }
        #region Override implementation of AppenderSkeleton
        override protected void Append(LoggingEvent loggingEvent) 
        {
            try 
            {     
                StringWriter writer = new StringWriter(System.Globalization.CultureInfo.InvariantCulture);
                string t = Layout.Header;
                if (t != null)
                {
                    writer.Write(t);
                }
                // Render the event and append the text to the buffer
                RenderLoggingEvent(writer, loggingEvent);
                t = Layout.Footer;
                if (t != null)
                {
                    writer.Write(t);
                }
                MailMessage mailMessage = new MailMessage();
                mailMessage.Body = writer.ToString();
                mailMessage.From = m_from;
                mailMessage.To = m_to;
                if (m_subjectLayout == null)
                {
                    mailMessage.Subject = "Missing Subject Layout";
                }
                else
                {
                    StringWriter subjectWriter = new StringWriter(System.Globalization.CultureInfo.InvariantCulture);
                    m_subjectLayout.Format(subjectWriter, loggingEvent);
                    mailMessage.Subject = subjectWriter.ToString();
                }
                if (m_smtpHost != null && m_smtpHost.Length > 0)
                {
                    SmtpMail.SmtpServer = m_smtpHost;
                }
                SmtpMail.Send(mailMessage);
            } 
            catch(Exception e) 
            {
                ErrorHandler.Error("Error occurred while sending e-mail notification.", e);
            }       
        }
        override protected bool RequiresLayout
        {
            get { return true; }
        }
        #endregion // Override implementation of AppenderSkeleton
        private string m_to;
        private string m_from;
        private PatternLayout m_subjectLayout;
        private string m_smtpHost;
    }
}
我知道

我参加聚会迟到了,但我有一个类似的问题,需要我以编程方式解决它,而不是将它们直接硬编码到app.config文件中。

当您不想通过配置文件公开电子邮件凭据时,这是您希望使用的方法。如果您出于任何原因想要覆盖 SmtpAppender,它也很有用。

以下是app.config的 log4net 追加器设置:

<appender name="SmtpAppender" type="MyNameSpace.SmtpAppenderHelper">
    <to value="sendto@company.com" />
    <cc value="sendccto@company.com" />
    <subject value="An Error Occured" />
    <bufferSize value="1" />
    <EnableSsl value="true" />
    <lossy value="true" />
    <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%level %date - %message%newline" />
    </layout>
    <evaluator type="log4net.Core.LevelEvaluator">
    <threshold value="ERROR" />
    </evaluator>
</appender>

我的帮助程序类:

namespace MyNameSpace
{
    public class SmtpAppenderHelper : SmtpAppender
    {
        protected override void SendBuffer(LoggingEvent[] events)
        {
            // overriding the SmtpAppender so that I can add some sensitive information
            this.Username = "myemailaddress@gmail.com";
            this.Password = "NotSafePassword";
            this.SmtpHost = "smtp.gmail.com";
            this.Port = 587;
            this.Authentication = SmtpAuthentication.Basic;
            this.From = "myemailaddress@gmail.com";
            base.SendBuffer(events);
        }
    }
}

您还可以创建一个 SmtpAppenderHelper 类的方法,以帮助您修改电子邮件主题,并在修改主题的base.SendBuffer(events)方法之前触发它,如下所示:

protected virtual void prepareSubject(ICollection<LoggingEvent> events)
{
    Subject = null;
    foreach (LoggingEvent _event in events)
    {
        if (Evaluator.IsTriggeringEvent(_event))
        {
            string msg = _event.ExceptionObject == null ? _event.RenderedMessage : _event.ExceptionObject.Message;
            Subject = string.Format("[{0}] {1}", _event.Level, msg);
            break;
        }
    }
    
}

这里关于覆盖Appenders的另一个示例