Java Logger Utility

Here is a utility that will help you to better use java.util.logging.Logger class. In this utility, I have tried provide the most commonly used features in this utility. In this article, few important features of Java logger framework are also explained in brief while going through the code. I am not going into deep to explain all features of Java logger technology, instead focusing on what this utility will help you with. You can use it as is or customize it according to your advanced needs.

Let us start with the list of elements of this utility and what is responsibility of those elements.

1. LogWrapper.java: This is the heart of this utility. It wraps up the java.util.logging.Logger class.

2. CustomMessageFormatter.java: Used to format the message getting logged.

3. UseExample.java: An example showing how to use this utility.

4. logger.properties: Configuration properties of logger.

Features:

1.       Wrapper to standard Java logging framework to facilitate customizable message construction.

2.       Better exception logging.

3.       Easy to integrate and enhance.

4.       Using features of Java 5.

Integration:

1. Standalone Java Application: Directly copy the classes in appropriate package (may be util or common package, but no restriction). Second is the property file, it should be kept directly in classpath. If you are placing it in any other folder then ensure that there is correct path in LogWrapper.java. Change the log file path in properties to appropriate location. This can be absolute as well as relative path with respect to classpath root.

2. Java Web Application: The only change you would require to make is placing the property file in WEB-INF directory/folder. Change the log path as required (and explained above).

Elements in Detail:

LogWrapper.java: This class is the main class. Below are the silent features of the code in this class.

Here is the code of this class.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Properties;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

public class LogWrapper{
    private static Logger logger = null;
    public static final String SPACE = " ";
    public static final String TAB = "\t";
    private static final String END_OF_LINE = System.getProperty("line.separator");
    public static final String LOGGER_PROPERTY_FILE = "logger.properties";
    public static final String LOG_FILE_NAME = "log.file.name";
    public static final String LOG_LEVEL = "logger.level";
    public static final String LOG_FILE_SIZE = "logger.file.size";
    public static final String LOG_NUMBER_OF_FILES = "logger.numberof.files";
    public static final String LOGGER_NAME = "logger.name";
    public static final String MESSAGE_FORMAT = "logger.message.format";
    public String className = "";

    private void init(Class clazz, URL logPropertiesFile)
    {
    	InputStream is = null;
		try{
            is = new FileInputStream(logPropertiesFile.getFile());
            Properties prop = new Properties();
            prop.load(is);
            if(logger == null){

                logger= Logger.getLogger(prop.getProperty(LOGGER_NAME));
    	        String fileName = prop.getProperty(LOG_FILE_NAME);
    	        FileHandler fh = new FileHandler(fileName.concat("%g.log"),
    	        		Integer.parseInt(prop.getProperty(LOG_FILE_SIZE)),
    	        		Integer.parseInt(prop.getProperty(LOG_NUMBER_OF_FILES)),true);
    	        fh.setFormatter(new CustomMessageFormatter(new MessageFormat(prop.getProperty(MESSAGE_FORMAT))));
    	        logger.setLevel(Level.parse(prop.getProperty(LOG_LEVEL)));
    	        logger.addHandler(fh);
            }
            this.className = clazz.getName();
        }catch(FileNotFoundException fnfe){
        	fnfe.printStackTrace();
        }catch(IOException ioe){
        	ioe.printStackTrace();
        }
    }

    public LogWrapper(Class clazz){
		URL logPropertiesFile = this.getClass().getClassLoader().getResource(LOGGER_PROPERTY_FILE);
		init(clazz, logPropertiesFile);
    }

    public LogWrapper(Class clazz, URL logPropertiesFile){
    	init(clazz, logPropertiesFile);
    }
    public LogWrapper(){

    }
    public void info(String...strings  ){
        logger.info(constructMessage(strings));
    }

    public void debug(String...strings  ){
        logger.fine(constructMessage(strings));
    }

    public void warn(String...strings  ){
        logger.warning(constructMessage(strings));

    }

    public void entering(String className, String methodName, Object[] data){

        logger.entering(className, methodName, data);

    }
    public void entering(String className, String methodName){

        logger.entering(className, methodName);

    }
    public void entering(String className, String methodName, Object data){

        logger.entering(className, methodName, data);

    }
    public void exiting(String className, String methodName, Object data){

        logger.exiting(className, methodName, data);

    }
    public void exiting(String className, String methodName){

        logger.exiting(className, methodName);

    }

    public void error(Exception trw, String...strings  ){
        logger.severe(constructMessage(strings)+ constructStackTrace(trw));
    }

    private String constructMessage(String[] strings){
        StringBuilder sbl = new StringBuilder();
        sbl.append(SPACE);
        sbl.append(className);
        if(strings != null || strings.length >0){
            for(int count=0; count< strings.length; count++){
                sbl.append(SPACE);
                sbl.append(strings[count]);
            }
        }

        return sbl.toString();
    }
    private String constructStackTrace(Exception exe){
        StringBuilder sbl = new StringBuilder();
    	sbl.append(END_OF_LINE);
        sbl.append(exe.toString());
        for(StackTraceElement ste:exe.getStackTrace()){
        	sbl.append(END_OF_LINE);
        	sbl.append(TAB);
        	sbl.append(ste.toString());
        }

        return sbl.toString();
    }

}

CustomMessageFormatter.java: This class is used to format a log message. LogWrapper reads the message formatter and uses this formatter instance to format the log message.

import java.text.MessageFormat;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
public class CustomMessageFormatter extends Formatter {

	private MessageFormat messageFormat = new MessageFormat("{0}\t{1}\t{2,date,dd:MM:yy:h:mm:ss.SSS}:\t\t{3}\n");

	@Override
	public String format(LogRecord record) {
		Object[] arguments = new Object[4];
		arguments[0] = record.getLevel();
		arguments[1] = Thread.currentThread().getName();
		arguments[2] = new Date(record.getMillis());
		arguments[3] = record.getMessage();
		return messageFormat.format(arguments);
	}

	public CustomMessageFormatter( MessageFormat mf) {
		super();
		messageFormat = mf;
	}

}

UseExample.java: In this class, this utility is used in standalone way. Entry, exit, info, error logging examples are explained here.

public class UseExample {
    private static LogWrapper logger = new LogWrapper(UseExample.class);

    public static void main (String[] strs){
    	logger.entering(UseExample.class.getName(), "main");
    	try{
        	logger.info("This","is", "sample", "logging." );
        	String str = null;
        	str.length();
    	}catch(Exception exc){
    		logger.error(exc, "Exception","occurred" ,"in" , "main" ,"method");
    	}
    	logger.exiting(UseExample.class.getName(), "main");
    }
}

logger.properties: Controls the logger behavior. Below are the property details.

  • Share/Bookmark
Java, Tech Notes

If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.

Leave Comment

(required)

(required)