Thursday, August 14, 2008

Error Reporting through E-Mail using Log4j (SMTPAppender Class)

This could be one of the cool thing if you get an intimation through an email when ever your application is facing the problem in production or test environments apart from this you get log file as well so we can decrees the turn around time some what in fixing and issue and making your environment up. A few months back I have implemented the same thing for one of our production application and I have used log4j for logging and emailing the log file when ever log file get populated with error level messages.
In log4j api we have one class called SMTPAppender which will email us our log file when ever log file is populated with error level message. Just needs to configure log4j properties file with all SMTP server details.

Note: Make sure that you should have mail.jar and activation.jar files in your class path.

log4j.properties:

log4j.rootLogger=INFO, filer ,SMTPTest
log4j.appender.filer=org.apache.log4j.RollingFileAppender
log4j.appender.filer.layout=org.apache.log4j.PatternLayout
log4j.appender.filer.layout.ConversionPattern=%d{MMM dd HH:mm:ss} %-5p [%t] %c{2} - %m%n
log4j.appender.filer.File=C:\\COMSProduction.log
log4j.appender.filer.MaxFileSize=1000KB
log4j.appender.filer.MaxBackupIndex=4

#####################
#SMTP appender properties#
#####################

log4j.appender.SMTPTest=org.apache.log4j.net.SMTPAppender
log4j.appender.SMTPTest.Threshold=Error
log4j.appender.SMTPTest.BufferSize=512
log4j.appender.SMTPTest.layout=org.apache.log4j.PatternLayout
log4j.appender.SMTPTest.layout.ConversionPattern=%d %-4r [%t] %-5p (%c:%L)%x - %m%n
log4j.appender.SMTPTest.SMTPHost= smpt.youcompany.com
log4j.appender.SMTPTest.To= me@who.com
log4j.appender.SMTPTest.From= me@who.com,user@who.com
log4j.appender.SMTPTest.Subject=COMSProductionLog - <>

EmailSender.java - Load properties and configure SMTP properties with log4j.
------------------

import org.apache.log4j.Category;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.net.SMTPAppender;

import java.io.InputStream;
import java.util.Properties;

/**
* Created by IntelliJ IDEA.
* User: sirishg
* Date: Apr 5, 2007
* Time: 4:38:45 PM
* To change this template use File | Settings | File Templates.
*/

/**
* This class is responsible to email your application log file to SupportEngineers/Developers when ever application is caught with errors.
* I am using SMPTAppender(from apache log4j) to do this job.
*/

public class EmailSender {
public static Category log = org.apache.log4j.Category.getInstance(EmailSender.class.getName());

public static void postEmail() {

Properties properties = null;
try {
properties = new Properties();
InputStream inStream = LogManager.class.getResourceAsStream("log4j.properties");
properties.load(inStream);

log.info("Trying to load log4j.properties file!!");
PropertyConfigurator.configure(properties);
log.info("Successfuly loaded the property file!!");
} catch (Exception e) {
log.error("OOPS...log4j.property file has not loaded!!");
e.printStackTrace();
}

/**
* Call SMTPAppender and set all required fields to that. you can set directly from here or you can load parameters from you log4j.properties.
* I prefer to load from log4j.properties hence you will get the chance to change perameters dynamically with out recomiling your code.
*/
try {
log.info("Invoking the SMTPAppender class");
SMTPAppender emailAppender = new SMTPAppender();
if (properties != null) {
emailAppender.setSMTPHost(properties.getProperty("log4j.appender.SMTPTest.SMTPHost"));
emailAppender.setFrom(properties.getProperty("log4j.appender.SMTPTest.From"));
emailAppender.setTo(properties.getProperty("log4j.appender.SMTPTest.To"));
emailAppender.setSubject(properties.getProperty("log4j.appender.SMTPTest.Subject"));
}
emailAppender.setLayout(new PatternLayout());
emailAppender.activateOptions();
log.addAppender(emailAppender);
} catch (Exception e) {
log.error("got an error in SMTPAppender, the errors are::" + e.getStackTrace());
e.printStackTrace();
}
}
}

PostEmailTest.java
-- Small test and try to do some mistake and put an error entry into log file now see you will get an email with your log file.
public class PostEmailTest {
public static void main(String[] args) throws Exception {
LogManager manager = new LogManager();
Logger log = manager.getLogger(PostEmailTest.class);
String str = "Sirish";
if (str.equals("SIRISH")) {
log.info("both strings are equal....");
} else {
log.error("Strings are not equal....!");
/**
* Finally we rached to what we are looking for. now we got one error entry into log file and this is the time to email log file to
* SupporEngineer so invoke EmailSender class and send .log file.
*/
EmailSender.postEmail();
}
}
}