我可以使用 log4net 在 VB 解决方案(Visual Studio 2010)中使用 smtpappender 和 Gmail 帐户将日志信息发送到电子邮件地址。收件人在 log4net 配置文件中配置,但是我希望能够动态更改收件人电子邮件地址。
是否可以不必编写自定义 smtpappender?
不管答案是是还是不是,请给我一个例子,最好是在VB中。
我可以使用 log4net 在 VB 解决方案(Visual Studio 2010)中使用 smtpappender 和 Gmail 帐户将日志信息发送到电子邮件地址。收件人在 log4net 配置文件中配置,但是我希望能够动态更改收件人电子邮件地址。
是否可以不必编写自定义 smtpappender?
不管答案是是还是不是,请给我一个例子,最好是在VB中。
这是不可能的,当前的 SmtpAppender 不允许。但是你很幸运,SendBuffer
SmtpAppender 中的 可以被覆盖,所以你可以很容易地给它添加一些行为。我认为您最好的选择是使用 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
您可以使用 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();
有可能的。请参阅我在这个问题中的答案 - 复制代码如下
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;
}
}
在一定程度上,获得动态接收者是可能的。
在 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 分钟的修复并且收件人的配置在启动后不会更改,那么我发现这已经足够了。