Question

On the Log4Net Config Examples webpage it shows examples on how to setup a SmtpAppender.

So I added the following settings into my app.config file, and it successfully sends an Email when a Warning or higher is logged (which is good).

<appender name="EmailAppender" type="log4net.Appender.SmtpAppender">
  <to value="me@mycompany.com" />
  <from value="me@mycompany.com" />
  <subject value="test logging message" />
  <smtpHost value="smtpserver.mycompany.com" />
  <lossy value="true" />
  <evaluator type="log4net.Core.LevelEvaluator">
    <threshold value="WARN"/>
  </evaluator>
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
  </layout>
</appender>

But the From value is hard coded with my Email address.

My application is a WinForms app and it's going to be deployed to users PC's, so it would be very handy to know which user encountered the warning / error.

Is is possible to set up a Log4Net SmtpAppender so that the From value uses the current users Email Address?

Thank you for your help.

Was it helpful?

Solution 3

After lots of Google'ing I finially found this great CodeProject article that shows how to create a new custom Smtp Appender using the AppenderSkeleton abstract class as a base.

It's simple, and can be changed so that the From property is set dynamically at runtime. And it also shows how to pass a pattern in for the Subject property, so your Email Subject can contain the logged event level and other information.

e.g.

<subject type="HHR.log4net.Layout.PatternLayout, HHR.log4net">
   <conversionPattern value="%date %level %exceptType at [%logger] on %property{log4net:HostName} by %username" />
</subject>

OTHER TIPS

There are two issues

1) Determining the user's email address. If they are part of a domain, then you could try

  System.DirectoryServices.AccountManagement.UserPrincipal.Current.EmailAddress

2). Using it in Log4net. It should be possible to do this using a property , eg

if you change your app.config from

<from value="me@mycompany.com" />

to

<from type="log4net.Util.PatternString" value="%property{From}" />

and add a line in your program to set the property eg

log4net.GlobalContext.Properties["From"] = 
   System.DirectoryServices.AccountManagement.UserPrincipal.Current.EmailAddress ;

You might also need to set your buffer size to 1.

It probably would be advisable to include the username as part of the error message as well, just to be safe.

Once downside to this approach is it is possible that emails may get lost if the from address is missing or incorrect.

Here is simple example how to setup SMTP appender in runtime. You can set any property of Smtp appender. Set appender name parameter in FindAppenderByName to same name as is appender name in your config.

    public static IAppender FindAppenderByName(string name)
    {
        ILoggerRepository rootRep = LogManager.GetRepository();
        foreach (IAppender iApp in rootRep.GetAppenders())
        {
            if (string.Compare(name, iApp.Name, true) == 0)
            {
                return iApp;
            }
        }
        return null;
    }

    private void SetupSmtpAppender()
    {
        IAppender appender = FindAppenderByName("Global.SmtpAppender");
        SmtpAppender smtpAppender = (SmtpAppender)appender;
        smtpAppender.From = "me@domain.com";
        smtpAppender.Subject = "My subject";
        smtpAppender.SmtpHost = "smtp@mydomain.com";
... setup more properties
    }

This is snippet from log4net.config:

<appender name="Global.SmtpAppender" type="log4net.Appender.SMTPAppender">
  <threshold value="WARN" />
</appender>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top