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

时间:2012-06-07 14:22:26

标签: c# .net vb.net logging log4net

我希望能够指定多个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>

3 个答案:

答案 0 :(得分:42)

有一种更简单的方法

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

答案 1 :(得分:8)

只有在您实施custom SmtpAppender时才有可能。

我已经从Log4net sourcecode Examples.复制了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;
    }
}

答案 2 :(得分:0)

我知道我迟到了,但我遇到了类似的问题,需要我以编程方式解决它,而不是直接将它们硬编码到 app.config 文件中。

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

以下是 app.config 的 log4net appender 设置:

<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;
        }
    }
    
}

另一个example here on overriding the Appenders