B Z
B Z

Reputation: 9463

Log4net Email Whole Log

.Net 4

I am using log4net in a windows service. The service has an internal timer and is scheduled to runs every 30 minutes. I would like to receive an email with all the logging activity every time the processing is complete. The only examples I found are with the smtp appender, but that sends an email everytime something is logged which is not what I need.

I would think this is a normal use case, but can't find any relevant examples...

Thanks for any help!

Upvotes: 3

Views: 1231

Answers (3)

Larry Dukek
Larry Dukek

Reputation: 2199

You can use as separate logger; assuming your log4net.config looks something like this:

<log4net xmlns="urn:log4net">
  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <threshold value="All" />
    <file value="../Logs/MyApp/myapp.log" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <datePattern value="yyyy-MM-dd.'log'" />
    <maxSizeRollBackups value="5" />
    <maximumFileSize value="10MB" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%d{HH':'mm':'ss'.'fff} [%4t] %-5p %M - %m %15property{ipAddress} - %property{orderId}%n" />
    </layout>
  </appender>
  <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
    <to value="<your to address>" />
    <from value="<your from address>" />
    <subject value="<your subject line>" />
    <smtpHost value="<your smtp host>"/>
    <username value="<your username>" />
    <password value="<your password>" />
    <port value="25" />
    <authentication value="Basic" />
    <evaluator type="log4net.Core.LevelEvaluator">
      <threshold value="Error" />
    </evaluator>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%newline[%property{log4net:HostName}] [%date] [%-5level] [%logger] - [%message]%newlineIp[%property{IpAddress}] Session[%property{SessionId}] OrderId[%property{OrderId}] UserAgent[%property{UserAgent}]%newline%newline%exception" />
    </layout>
  </appender>

  <root>
    <level value="ALL" />
    <appender-ref ref="RollingLogFileAppender" />
    <appender-ref ref="SmtpAppender" />
  </root>
</log4net>

Then you could modify it to look like this:

<log4net xmlns="urn:log4net">
  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <threshold value="All" />
    <file value="../Logs/MyApp/myapp.log" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <datePattern value="yyyy-MM-dd.'log'" />
    <maxSizeRollBackups value="5" />
    <maximumFileSize value="10MB" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%d{HH':'mm':'ss'.'fff} [%4t] %-5p %M - %m %15property{ipAddress} - %property{orderId}%n" />
    </layout>
  </appender>
  <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
    <to value="<your to address>" />
    <from value="<your from address>" />
    <subject value="<your subject line>" />
    <smtpHost value="<your smtp host>"/>
    <username value="<your username>" />
    <password value="<your password>" />
    <port value="25" />
    <authentication value="Basic" />
    <evaluator type="log4net.Core.LevelEvaluator">
      <threshold value="Error" />
    </evaluator>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%newline[%property{log4net:HostName}] [%date] [%-5level] [%logger] - [%message]%newlineIp[%property{IpAddress}] Session[%property{SessionId}] OrderId[%property{OrderId}] UserAgent[%property{UserAgent}]%newline%newline%exception" />
    </layout>
  </appender>
  <appender name="SmtpJobAppender" type="log4net.Appender.SmtpAppender">
    <to value="<job to address>" />
    <from value="<job from address>" />
    <subject value="<job subject line>" />
    <smtpHost value="<your smtp host>"/>
    <username value="<your username>" />
    <password value="<your password>" />
    <port value="25" />
    <authentication value="Basic" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%newline[%property{log4net:HostName}] [%date] [%-5level] [%logger] - [%message]%newlineIp[%property{IpAddress}] Session[%property{SessionId}] OrderId[%property{OrderId}] UserAgent[%property{UserAgent}]%newline%newline%exception" />
    </layout>
  </appender>
  <logger name="Any.Name.You.Want.To.Indicate.This.Is.Your.Job.Completed.Log">
    <level value="ALL"/>
    <appender-ref ref="SmtpJobAppender"/>
  </logger>
  <root>
    <level value="INFO" />
    <appender-ref ref="RollingLogFileAppender" />
    <appender-ref ref="SmtpAppender" />
  </root>
</log4net>

And in the class you have your job complete function you would declare your job logger:

private static readonly ILog JobLogger = LogManager.GetLogger("Any.Name.You.Want.To.Indicate.This.Is.Your.Job.Completed.Log");

And in your complete method use your job logger:

JobLogger.Info("Job complete - process time was " + process.Time);

This will allow you to have different subject lines in your job complete emails and your error emails. They can even have different from addresses, making your email client rules easy to set up.

Upvotes: 1

Merlyn Morgan-Graham
Merlyn Morgan-Graham

Reputation: 59131

I don't think this is a standard use of it, as the SMTPAppender is mostly designed to be used to trigger on errors (which should be rare). Here's the description of the appender:

Send an e-mail when a specific logging event occurs, typically on errors or fatal errors.

Looking at the documentation for SMTPAppender, I see that one of the properties is a class which evaluates the input message, and decides whether to trigger the e-mail to be sent.

You could create a custom class that will send the e-mail when a specific message is sent, specific source, etc.

I'm not sure if you could set it from the config with a custom class. You could programatically add the appender and set that property.

You may need to increase the BufferSize property in order to get the history of logs that you want.

Or you could roll your own appender. I can't think of how you'd design it that would be much different than the SMTPAppender, though, except possibly making your buffer unlimited (which is a bit dangerous).

Alternately you could simply log to a rolling log file appender, and have a service/scheduled task start up every thirty minutes, e-mail off the log file, clean up, and die. I've done this on a production web app before, using scheduled tasks and batch files, deployed via an MSI we created in WIX, with a custom action to deploy the scheduled task.

Upvotes: 2

Vladimir
Vladimir

Reputation: 3689

I suppose you can either create your own custom appender that buffers logs, and then flush it when you need to (every 30min in your case), or set a very high buffer size in the existing appender (and hope it does not get reached within those 30min) and flush it every 30min.

Upvotes: 1

Related Questions