I'm trying to use log4j to send emailable reports that contain the logging statements from a background process. I want one email sent for each process run, not one email for each logging statement. I've looked at the SMTPAppender
, but don't see a way to manually send the report when the process completes. I believe the TriggeringEventEvaluator
may be the key, but one issue I'm running into is how to get a handle to the TriggeringEventEvaluator
instance. I'm stuck using log4j 1.2.14 and the SMTPAppender.getEvaluator()
method was introduced in 1.2.15. Any thoughts? Am I even on the right track? Does the SMTPAppender.close()
method come into play here?
I want to be able to do this:
log.info(message1);
log.info(message2);
log.info(message3);
log.sendMail();
After thinking about this some more, I think I need to clarify what I'm hoping to accomplish. I'm trying to capture the logging from running a quartz job and send the resulting log as an email. The quartz job makes a bunch of service method calls into various services. I want the to include any logging those service methods perform as well as the logging of the quartz jobs itself. I was thinking I could do something like the following for capturing all the logging, but it isn't working.
// at the beginning of quartz job
Logger logger = Logger.getRootLogger();
StringWriter sw = new StringWriter();
WriterAppender wa = new WriterAppender(new SimpleLayout(), sw);
logger.addAppender(wa);
// at the end of the quartz job
String report = sw.toString();
You shouldn't use any of log4j's methods, you should configure it properly instead.
First of all, define in your log4j.properties
file your appender properly:
#CONFIGURE SMTP
log4j.appender.email=org.apache.log4j.net.SMTPAppender
log4j.appender.email.SMTPHost=mail.mydomain.com
log4j.appender.email.SMTPUsername=myuser@mydomain.com
log4j.appender.email.SMTPPassword=mypw
log4j.appender.email.From=myuser@mydomain.com
log4j.appender.email.To=myuser@mydomain.com
log4j.appender.email.Subject=Log of messages
log4j.appender.email.BufferSize=1
log4j.appender.email.EvaluatorClass=TriggerLogEvent
log4j.appender.email.layout=org.apache.log4j.PatternLayout
log4j.appender.email.layout.ConversionPattern=%m
Note: code taken from this post. More information can be obtained in SMTPAppender API.
Next, make a special class that will be used just for sending email. Example:
package com.foo.mailer;
import org.apache.log4j.Logger;
public class Mailer {
private static final Logger logger = Logger.getLogger(Mailer.class);
public void logMail(String mailString) {
logger.info(mailString);
}
}
Next, put in log4j.properties
configuration for this class:
# INFO level will be logged
log4j.logger.com.foo.mailer = INFO, email
# turn off additivity
log4j.additivity.com.foo.mailer = false
Now, whenever you want to send an email using log4j, put this in your code:
new Mailer().logMail("This mail should be sent");
Disclaimer: I haven't tested any of this code.
If you are using an XML configuration file, the following should be helpful.
<appender name="ErrorEmailAppender" class="org.apache.log4j.net.SMTPAppender">
<param name="SMTPHost" value="mail.mydomain.com" />
<param name="SMTPUsername" value="myuser@mydomain.com" />
<param name="SMTPPassword" value="password" />
<param name="From" value="myuser@mydomain.com" />
<param name="To" value="myuser@mydomain.com" />
<param name="Subject" value="Log of messages" />
<param name="BufferSize" value="1" />
<param name="EvaluatorClass" value="TriggerLogEvent" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%t %m%n"/>
</layout>
</appender>
<logger name="com.foo.mailer">
<level value="INFO" />
<appender-ref ref="ErrorEmailAppender"/>
</logger>