Creating custom Logger Factory
I hope that the following sample snippet will give you a better understanding how to create the custom Logger Factory
package com.sample.utility.loggers;
/**
* This is an interface for application logger.It contains methods which
* facilitate the logging.Implementing <code>Logger</code> interface will unify
* most of the logging requirements and result in consistent logging system.
*
*
* @author SUNILG
* @version 1.0, 11 April 2013
*/
public interface Logger {
/**
* Logs the given string as a debug message, provided logging at
* <tt>DEBUG</tt> level is enabled for the current logger.
* <p>
* Any <tt>appendThese</tt> arguments passed will be appended to the
* message.
*
* @param message
* the message that needs to be logged.
*
* @param appendThese
* fragments which will be appended to the message.
*/
void debug(String message, Object... appendThese);
/**
* Logs the given string as an information, provided logging at
* <tt>INFO</tt> level is enabled for the current logger.
* <p>
* Any <tt>appendThese</tt> arguments passed will be appended to the
* message.
*
* @param message
* the message that needs to be logged.
*
* @param appendThese
* fragments which will be appended to the message.
*/
void info(String message, Object... appendThese);
/**
* Logs the given string as a warning message, provided logging at
* <tt>WARN</tt> level is enabled for the current logger.
* <p>
* Any <tt>appendThese</tt> arguments passed will be appended to the
* message.
*
* @param message
* the message that needs to be logged.
*
* @param appendThese
* fragments which will be appended to the message.
*/
void warn(String message, Object... appendThese);
/**
* Logs the given string as an error message.
*
* @param message
* the message that needs to be logged.
*/
void error(String message);
/**
* Logs the given string at the error level with the exception message.
*
* @param message
* the message that needs to be logged.
*
* @param throwable
* the <code>Throwable</code> to be logged.
*/
void error(String message, Throwable throwable);
/**
* Logs the given string at the fatal level.
*
* @param message
* the message that needs to be logged.
*/
void fatal(String message);
/**
* Logs the given string at the fatal level with the exception message.
*
* @param message
* the message that needs to be logged.
* @param throwable
* the <code>Throwable</code> to be logged.
*/
void fatal(String message, Throwable throwable);
/**
* Logs a method entry with the list of its parameters at debug level.
*
* @param methodName
* the string containing method name.
*
* @param params
* an array of the parameters of the method.
*/
void entering(String methodName, Object... params);
/**
* Logs the exit from a method at debug level.
*
* @param methodName
* the string containing method name.
*/
void exiting(String methodName);
/**
* Logs the exit from a method which returns a value at debug level.
*
* @param methodName
* the string containing method name.
*
* @param retVal
* the return value of the method.
*/
void exiting(String methodName, Object retVal);
/**
* Changes the logging level of a current logger.
* With this logging levels for a logger can be controlled dynamically.
*
* @param loggerLevel
* the logging level to be set
*/
void setLoggerLevel(String loggerLevel);
/**
* Returns the <code>Level.DEBUG</code> status of the logger in context.
*
* @return boolean indicating whether debug is turned on or off
*
* @see org.apache.log4j.Level
*/
boolean isDebugEnabled();
/**
* Returns the <code>Level.WARN</code> status of the logger in context.
*
* @return boolean indicating whether warn is turned on or off
*
* @see org.apache.log4j.Level
*/
boolean isWarnEnabled();
/**
* Returns the <code>Level.INFO</code> status of the logger in context.
*
* @return boolean indicating whether info is turned on or off
*
* @see org.apache.log4j.Level
*/
boolean isInfoEnabled();
}
2) LoggerFactory.java
package com.sample.utility.loggers;
import java.util.HashMap;
import java.util.Iterator;
import org.apache.log4j.Logger;
import com.sample.utility.utils.LogUtil;
/**
* This class <code>LoggerFactory</code> provides the entry point to the logging
* layer. On loading caches all the current loggers configured in the runtime
* environment in a <code>Map</code> for later retrieval.
*
* The typical usage in getting a <code>EngineLogger</code> instance to start
* logging is as shown below :
*
* <p>
* <blockquote>
*
* <pre>
* private static EngineLogger logger = LoggerFactory.getInstance().getLogger(
* MyClass.class);
* </pre>
*
* <p>
* It can then use all the methods defined under <code>Logger</code> interface
* appropriately.
* </blockquote>
*
* @author SUNILG
* @version 1.0, 11 April 2013
*/
public final class LoggerFactory {
/**
* Single ton instance for this class
*/
private static LoggerFactory theInstance = new LoggerFactory();
/**
* Cache of loggers.
*/
private HashMap logInstance = new HashMap();
/**
* Default Constructor- Caches all the system and root loggers.
*/
private LoggerFactory() {
try {
// Get the current loggers configured
Iterator i = LogUtil.getCurrentLoggers().iterator();
SampleLogger log = null;
Logger logger = null;
// Loop through and cache the named loggers
while (i.hasNext()) {
logger = (Logger) i.next();
log = new SampleLogger(logger);
logInstance.put(logger.getName(), log);
}
} catch (Exception exception) {
exception.printStackTrace();
throw new RuntimeException("unknown Exception: "
+ exception);
}
}
/**
* Returns the instance of this class.
*
* @return an instance of <code>LoggerFactory</code>
*/
public static LoggerFactory getInstance() {
return theInstance;
}
/**
* Gets the instance of logger which is associated with the given class.
* <p>
* This method searches its cache for the logger instance with the given
* class name.
* <p>
* If an instance of the logger is not found in the cache, then a new
* instance of logger is created and returned.
*
* @param clazz
* a <code>Class</code> object interested in using the logger.
*
* @return an implementation of <code>Logger</code>
*/
public SampleLogger getLogger(Class clazz) {
String name = clazz.getName();
SampleLogger log = (SampleLogger) logInstance.get(name);
if (log == null) {
synchronized (LoggerFactory.class) {
log = new SampleLogger(clazz);
logInstance.put(name, log);
}
}
return log;
}
/**
* Sets the logger with the <code>loggerName</code>
* to the specified level <code>loggerLevel</code>.
*
* @param loggerName
* the name of the logger.This is used to retrieve the named
* logger instance
* @param loggerLevel
* the loggerLevel to change
*/
public void setCurrentLogger(String loggerName, String loggerLevel) {
SampleLogger log = (SampleLogger) logInstance.get(loggerName);
// Set the logger level of the named logger
if (log != null) {
log.setLoggerLevel(loggerLevel);
logInstance.put(loggerName, log);
}
}
}
3) SampleLogger.java
/**
*
*/
package com.sample.utility.loggers;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
/**
* @author SUNILG
* @version 1.0, 11 April 2013
*/
public class SampleLogger implements com.sample.utility.loggers.Logger {
/**
* Enter method prefix.
*/
private static final String ENTER_PREFIX = " ENTERING METHOD : ";
/**
* Exit method prefix.
*/
private static final String EXIT_PREFIX = " EXITING METHOD : ";
/**
* Parameter prefix.
*/
private static final String PARAM_PREFIX = " PARAM";
/**
* Return value prefix.
*/
private static final String RETURN_PREFIX = " RETURN VALUE = ";
/**
* Name of this class.
*/
private static final String LOGGER_NAME = SampleLogger.class.getName();
/**
* Log4j logger for logging.
*/
private final Logger logger;
/**
* Creates a logger for the given class.
*
* @param clazz
* the <code>Class</code> object interested in logging.
*/
public SampleLogger(Class clazz) {
logger = Logger.getLogger(clazz);
}
/**
* Creates a logger with a given logger.This is used to load all the
* predefined system loggers.
*
* @param logger
* a Log4j logger instance
*/
public SampleLogger(Logger logger) {
this.logger = logger;
}
/**
* {@inheritDoc}
*/
public void debug(String message, Object... appendThese) {
if (!this.isDebugEnabled()) {
return;
}
if (appendThese != null) {
StringBuilder msg = new StringBuilder(message);
for (Object appendThis : appendThese) {
msg.append(appendThis);
}
message = msg.toString();
}
logger.log(LOGGER_NAME, Level.DEBUG, message, null);
}
/**
* {@inheritDoc}
*/
public void info(String message, Object... appendThese) {
if (!this.isInfoEnabled()) {
return;
}
if (appendThese != null) {
StringBuilder msg = new StringBuilder(message);
for (Object appendThis : appendThese) {
msg.append(appendThis);
}
message = msg.toString();
}
logger.log(LOGGER_NAME, Level.INFO, message, null);
}
/**
* {@inheritDoc}
*/
public void warn(String message, Object... appendThese) {
if (!this.isWarnEnabled()) {
return;
}
if (appendThese != null) {
StringBuilder msg = new StringBuilder(message);
for (Object appendThis : appendThese) {
msg.append(appendThis);
}
message = msg.toString();
}
logger.log(LOGGER_NAME, Level.WARN, message, null);
}
/**
* {@inheritDoc}
*/
public void error(String message) {
logger.log(LOGGER_NAME, Level.ERROR, message, null);
}
/**
* {@inheritDoc}
*/
public void error(String message, Throwable throwable) {
logger.log(LOGGER_NAME, Level.ERROR, message, throwable);
}
/**
* {@inheritDoc}
*/
public void fatal(String message) {
logger.log(LOGGER_NAME, Level.FATAL, message, null);
}
/**
* {@inheritDoc}
*/
public void fatal(String message, Throwable throwable) {
logger.log(LOGGER_NAME, Level.FATAL, message, throwable);
}
/**
* {@inheritDoc}
*/
public void entering(String methodName, Object... params) {
logger.log(LOGGER_NAME, Level.DEBUG,
this.getEnterMethodLogStr(methodName, params), null);
} // end of method enterMethod
/**
* {@inheritDoc}
*/
public void exiting(String methodName) {
StringBuffer buf = new StringBuffer();
buf.append(EXIT_PREFIX);
buf.append(methodName + "(..)");
logger.log(LOGGER_NAME, Level.DEBUG, buf.toString(), null);
}
/**
* {@inheritDoc}
*/
public void exiting(String methodName, Object retVal) {
StringBuffer buf = new StringBuffer();
buf.append(EXIT_PREFIX);
buf.append(methodName + "(..)");
buf.append(RETURN_PREFIX);
buf.append("[ ");
buf.append(retVal);
buf.append(" ]");
logger.log(LOGGER_NAME, Level.DEBUG, buf.toString(), null);
}
/**
* {@inheritDoc}
*/
public void setLoggerLevel(String loggerLevel) {
if ("DEBUG".equals(loggerLevel)) {
logger.setLevel(Level.DEBUG);
}
if ("INFO".equals(loggerLevel)) {
logger.setLevel(Level.INFO);
}
if ("WARN".equals(loggerLevel)) {
logger.setLevel(Level.WARN);
}
if ("ERROR".equals(loggerLevel)) {
logger.setLevel(Level.ERROR);
}
if ("FATAL".equals(loggerLevel)) {
logger.setLevel(Level.FATAL);
}
}
/**
* {@inheritDoc}
*/
public boolean isDebugEnabled() {
return logger.isDebugEnabled();
}
/**
* {@inheritDoc}
*/
public boolean isInfoEnabled() {
return logger.isInfoEnabled();
}
/**
* {@inheritDoc}
*/
public boolean isWarnEnabled() {
return logger.isEnabledFor(Level.WARN);
}
/**
* Returns the log string for entry of a method.
*
* @param methodName
* a string containing the method name as the parameter.
*
* @param params
* an array of objects containing the parameters to the method.
*
* @return a string to be logged indicating the entry of this method.
*/
private String getEnterMethodLogStr(String methodName, Object[] params) {
StringBuffer buf = new StringBuffer(ENTER_PREFIX);
buf.append(methodName + "(..)");
if (params != null) {
for (int i = 0; i < params.length; i++) {
if (i > 0 && i != params.length) {
buf.append(",");
}
buf.append(PARAM_PREFIX);
buf.append(i + 1);
buf.append(" = [");
buf.append(params[i]);
buf.append("]");
}
}
return buf.toString();
}
}
4) LogUtil
package com.sample.utility.utils;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import com.sample.utility.loggers.LoggerFactory;
/**
* The <code>LogUtil</code> class contains a collection of public
* static utility methods for logger used in the application.
*
*
* @author SUNILG
* @version 1.0, 11 April 2013
*/
public final class LogUtil {
/**
* The private constructor to prevent instantiation.
*/
private LogUtil() {
}
/**
* Sets the level of logging for the given loggerName.
* This method retrieves the named logger instance
* and modifies the Level.
*
* @param loggerName
* the name of the logger to which level has to be modified
* @param loggerLevel
* the new level that has to set to <code>Logger</code>
* identified by the <code>loggerName</code>
* @return a response containing appropriate message
*
* @see org.apache.log4j.Logger#getLogger(java.lang.String)
* @see org.apache.log4j.Category#setLevel(org.apache.log4j.Level)
*
*/
public static String setLoggerLevel(
String loggerName, String loggerLevel) {
LoggerFactory.getInstance().
setCurrentLogger(loggerName, loggerLevel);
// response to the caller
return "Logger verbosity set successfully, logger=" + loggerName
+ ", level=" + loggerLevel
+ ". The change may affect"
+ " subordinate loggers.";
}
/**
* Internal method to Retrieve all the current loggers from the logger
* repository as a <code>Collection</code> instance.
*
* @return a Collection holding the Current Loggers
*/
public static java.util.Collection getCurrentLoggers() {
// Create an empty list to hold CurrentLoggers
java.util.List loggers = new java.util.LinkedList();
// Build the list with logger
for (java.util.Enumeration e =
org.apache.log4j.Logger.getRootLogger()
.getLoggerRepository().getCurrentLoggers();
e.hasMoreElements();) {
Logger loggerImpl = (org.apache.log4j.Logger)
e.nextElement();
loggers.add(loggerImpl);
}
return loggers;
}
/**
* Returns the current logging level of the given logger.
*
* @param logger
* the logger on which current <code>LEVEL</code> will be
* returned
* @return the effective Level of the input <code>Logger</code>
*
* @see org.apache.log4j.Level
*/
public static Level getCurrentLevel(Logger logger) {
org.apache.log4j.Level level = logger.getEffectiveLevel();
if (Level.ALL.equals(level)) {
return Level.DEBUG;
}
if (Level.DEBUG.equals(level)) {
return Level.DEBUG;
}
if (Level.INFO.equals(level)) {
return Level.INFO;
}
if (Level.WARN.equals(level)) {
return Level.WARN;
}
if (Level.ERROR.equals(level)) {
return Level.ERROR;
}
if (Level.FATAL.equals(level)) {
return Level.FATAL;
}
if (Level.OFF.equals(level)) {
return Level.FATAL;
}
return null;
}
}
No comments:
Post a Comment