7

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

3 回答 3

47

有一种更简单的方法

<to value="group@ivp.in,group2@ivp.in,group3@ivp.in,group4@ivp.in" />
于 2012-07-17T08:02:21.990 回答
8

只有实施custom SmtpAppender.

CustomSmtpAppenderLog4net 源代码示例中复制了代码。希望这会对你有所帮助。

不要忘记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;
    }
}
于 2012-06-07T14:24:56.333 回答
0

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

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

这是 log4net appender 的设置app.config

<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

于 2021-05-07T11:03:23.163 回答