log4net: A Custom Subject SmtpPickupDirAppender With Emails Containing All Referenced Assemblies

The more information you have in your error notification emails the better. Here’s a way you can get all the referenced assemblies into a log4net generated email that has a custom subject line.

First, in your application start-up, add the C# code to get the referenced assemblies and put them in a place that log4net appenders can get to:

 
var assembly = Assembly.GetExecutingAssembly();
var assemblyPath = Path.GetDirectoryName(assembly.Location) ?? @".\";
var configPath = Path.Combine(assemblyPath, "log4net.config");
GlobalContext.Properties["AssemblyVersion"] = assembly.GetName().Version.ToString();
GlobalContext.Properties["ReferencedAssemblies"] = string.Join(Environment.NewLine, assembly.GetReferencedAssemblies().Select(a => a.FullName));
// NOTE: you must set properties before calling the configurator
XmlConfigurator.ConfigureAndWatch(new FileInfo(configPath));

Next, add a “custom subject” SMTP pickup directory appender class that sets the log message as the email subject, trimming it if it is too long:

 
public class MySmtpPickupDirAppender : SmtpPickupDirAppender
{
  public MySmtpPickupDirAppender()
  {
    MaxSubjectLength = 100;
  }
 
  public int MaxSubjectLength { get; set; }
 
  public ILayout SubjectLayout { get; set; }
 
  protected override void Append(LoggingEvent loggingEvent)
  {
    if (BufferSize <= 1 && SubjectLayout != null)
    {
      var subjectWriter = new StringWriter(CultureInfo.InvariantCulture);
      SubjectLayout.Format(subjectWriter, loggingEvent);
      var subject = subjectWriter.ToString();
      Subject = subject.Length > MaxSubjectLength ? subject.Substring(0, MaxSubjectLength) + "..." : subject;
    }
 
    base.Append(loggingEvent);
  }
}

Then, add to your log4net configuration section a references to both the custom SMTP pickup dir appender and the global properties which include the referenced assemblies:

[cc lang=”xml”]















Finally, when your application encounters an error, here’s example output:

[cc]

Subject: My App Event – ERROR Argument Exception

Uh-oh, we may have a problem…

12-Dec-2012 14:22:10
Argument Exception

———–Debug Information————
Hostname: MYSERVER01
User: MYDOMAIN\user_account
App Version: 1.1.2345.2432
Assembly References:
log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.ServiceProcess, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
My.Namespace.Application, Version=1.2.1.0, Culture=neutral, PublicKeyToken=null
My.Namespace.Data, Version=2.3.1.0, Culture=neutral, PublicKeyToken=null

Of course if you are using this pattern, you will want to ensure that your application doesn’t spam you out of existence by using some sort of “only email on first error” type logic. 🙂

Hope this helps!

This entry was posted in C#, log4net. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *