Search code examples
vb.netlog4netsmtpappender

log4net smtpappender custom email recipients


I am able to use log4net to send logging information to an email address using the smtpappender and a Gmail account in a VB solution (Visual Studio 2010). The recipient is configured in the log4net config file, however I would like to be able to change the recipient email address dynamically.

Is it possible without having to write a custom smtpappender?

Wether the answer is yes or no, please give me an example, preferably in VB.


Solution

  • It's not possible, the current SmtpAppender won't allow it. But you're lucky, the SendBuffer in the SmtpAppender can be overridden, so you can easily add some behavior to it. I think your best bet is to use the LoggingEvent properties to set the recipient:

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

    You may want to change the way to select recipients, your call.

    edit The tool recommended by stuartd works quite well (well, it is quite a simple class, but still):

    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