2

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

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

不管答案是是还是不是,请给我一个例子,最好是在VB中。

4

4 回答 4

3

这是不可能的,当前的 SmtpAppender 不允许。但是你很幸运,SendBufferSmtpAppender 中的 可以被覆盖,所以你可以很容易地给它添加一些行为。我认为您最好的选择是使用 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;
    }
}

您可能希望更改选择收件人的方式,即您的呼叫。

编辑 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
于 2014-09-26T07:54:38.913 回答
1

您可以使用 log4Net.GlobalContext 类。

代码:

应用程序配置

<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();
于 2015-01-27T20:45:02.880 回答
1

有可能的。请参阅我在这个问题中的答案 - 复制代码如下

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;
    }
}
于 2014-09-26T13:33:54.223 回答
0

在一定程度上,获得动态接收者是可能的。

在 SMTP 附加程序中,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");

瞧!没有任何自定义附加程序的动态收件人!

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

于 2015-03-09T16:45:41.443 回答