How to make Log4Net send an Email with the From value set to the current users email address
Asked Answered
N

3

9

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="[email protected]" />
  <from value="[email protected]" />
  <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.

Naldo answered 10/1, 2013 at 10:53 Comment(1)
wouldn't it suffice to include the username in the log? You could use the expression %env{USERNAME} to include the environment variable %USERNAME% either in the subject or in the log message.Witenagemot
N
4

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>
Naldo answered 11/1, 2013 at 8:50 Comment(0)
F
7

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="[email protected]" />

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.

Feline answered 10/1, 2013 at 20:5 Comment(2)
handy. Only 2 lines of code to change. Note I had to set the property before calling log4net.Config.XmlConfigurator.Configure();Animality
This is by far the cleanest solution I've seen for this particular problem. Cheers for this.Pridemore
A
5

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 = "[email protected]";
        smtpAppender.Subject = "My subject";
        smtpAppender.SmtpHost = "[email protected]";
... setup more properties
    }

This is snippet from log4net.config:

<appender name="Global.SmtpAppender" type="log4net.Appender.SMTPAppender">
  <threshold value="WARN" />
</appender>
Airs answered 1/10, 2013 at 14:55 Comment(0)
N
4

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>
Naldo answered 11/1, 2013 at 8:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.