log4net smtpappender自定义电子邮件收件人

时间:2014-09-26 07:17:55

标签: vb.net log4net smtpappender

我可以使用log4net使用smtpappender和VB解决方案中的Gmail帐户(Visual Studio 2010)将日志记录信息发送到电子邮件地址。收件人在log4net配置文件中配置,但我希望能够动态更改收件人电子邮件地址。

是否可以不必编写自定义smtpappender?

回答是或否,请给我一个例子,最好是在VB中。

4 个答案:

答案 0 :(得分:3)

这是不可能的,目前的SmtpAppender不会允许它。但是你很幸运,可以覆盖SmtpAppender中的SendBuffer,因此你可以轻松地为它添加一些行为。我认为最好的办法是使用LoggingEvent属性来设置收件人:

public class MySmtpAppender : SmtpAppender
{
    protected override void SendBuffer(log4net.Core.LoggingEvent[] events)
    {
        var Recipients = events
            .Where(e => e.Properties.Contains("recipient"))
            .Select(e => e.Properties["recipient"])
            .Distinct();
        var RecipientsAsASingleLine = string.Join(";", Recipients.ToArray()); // or whatever the separator is
        var PreviousTo = To;
        To = RecipientsAsASingleLine;
        base.SendBuffer(events);
        To = PreviousTo;
    }
}

您可能想要更改选择收件人的方式。

编辑 The tool recommended by stuartd效果很好(好吧, 非常简单,但仍然如此):

Public Class MySmtpAppender
    Inherits SmtpAppender
    Protected Overrides Sub SendBuffer(events As log4net.Core.LoggingEvent())
        Dim Recipients = events.Where(Function(e) e.Properties.Contains("recipient")).[Select](Function(e) e.Properties("recipient")).Distinct()
        Dim RecipientsAsASingleLine = String.Join(";", Recipients.ToArray())
        ' or whatever the separator is
        Dim PreviousTo = [To]
        [To] = RecipientsAsASingleLine
        MyBase.SendBuffer(events)
        [To] = PreviousTo
    End Sub
End Class

答案 1 :(得分:1)

有可能。 see my answer in this question -复制了以下代码

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)

您可以使用log4Net.GlobalContext类。

代码:

的App.config

<appender name="SmtpLogAppender" type="log4net.Appender.SmtpAppender"> <to type="log4net.Util.PatternString" value="%property{SenderList}"/>

C#代码

GlobalContext.Properties["SenderList"] = "abc@xyz.com, def@xyz.com";
log4net.Config.XmlConfigurator.Configure();

答案 3 :(得分:0)

在某种程度上,可以获得动态收件人。

在SMTP appender中,在配置期间完成To,CC,From等的替换。不理想(如果要在每次发送时计算值,那将是最好的)但仍然可行。

重新配置日志记录不是免费的,但可以通过编程方式进行。您可以将To字段设置为:

<to type="log4net.Util.PatternString" value="SomeAccountThatReceivesAll@yourCorp.com%property{MailRecipient}" />

然后在您的代码中,您可以设置逗号分隔的收件人列表,如下所示:

log4net.GlobalContext.Properties["MailRecipient"] = "SomeOtherAccount@yourCorp.com,YourCorpSupportForThisApp@yourCorp.com";

重要的一点是,在设置这些值后强制重新配置。确切的语法将取决于您的配置策略,我们使用中央配置文件进行所有日志记录,因此在C#中它将如下所示:

    log4net.Config.XmlConfigurator.ConfigureAndWatch("PathToYourCentralFile.xml");
瞧,瞧!没有任何自定义附加程序的动态收件人!

就我个人而言,我更喜欢自定义appender,因为如果你需要经常更改它们,它不需要不断重新配置。但是,如果您只需要10分钟的修复,并且收件人的配置一旦启动就不会改变,那么我发现这已经足够了。