package jeffaschenk.commons.frameworks.cnxidx.utility.logging;
import jeffaschenk.commons.frameworks.cnxidx.utility.StopWatch;
import jeffaschenk.commons.frameworks.cnxidx.utility.message.MessageUtility;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import org.apache.log4j.PropertyConfigurator;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
/**
* Framework logging abstraction of log4j.
*/
public class FrameworkLogger {
//---------------------------
// Class constants
//---------------------------
private static final String CLASS_NAME = FrameworkLogger.class.getName();
public static final String PROPERTIES_FILENAME = ".framework.logger";
public static String LOG_LAYOUT = "%p: %d{MMdd:HHmmss}: %c{2}: THREAD:%t %m%n";
public static final String NO_CLASS_NAME = "NO_CLASSNAME";
public static final String NO_METHOD_NAME = "NO_METHODNAME";
public static final String CATEGORY_NAME_AUDIT = "AUDIT";
public static final String CATEGORY_NAME_TIMING = "TIMING";
//---------------------------
// attributes
//---------------------------
protected Logger logger = null;
protected String sourceClass = null;
protected String sourceMethod = null;
private static boolean logTimingStats = true;
//---------------------------
// Constructors
//---------------------------
/**
* Construct to use the root logger (protected so nobody really uses this)
*/
protected FrameworkLogger() {
logger = Logger.getRootLogger();
}
/**
* Construct to use the logger for the class name and method name
*
* @param sourceClass The fully qualified name of the class
* @param sourceMethod The name of the method
*/
public FrameworkLogger(String sourceClass, String sourceMethod) {
this.sourceClass = sourceClass;
this.sourceMethod = sourceMethod;
logger = Logger.getLogger(sourceClass + '.' + sourceMethod);
}
/**
* Construct to use the logger for the class name and method name
*
* @param loggerName Logger Name
*/
public FrameworkLogger(String loggerName) {
this.sourceClass = loggerName;
this.sourceMethod = "";
logger = Logger.getLogger(sourceClass);
}
//---------------------------
// class initialization
//---------------------------
static {
try {
// if an existing Framework logger is up and running
// don't override it with this logger
boolean initLogger = true;
java.util.Enumeration loggers = LogManager.getCurrentLoggers();
Logger logger;
String name;
while (loggers.hasMoreElements()) {
logger = (Logger) loggers.nextElement();
name = logger.getName().toLowerCase();
if (name.indexOf("jeffaschenk.commons") >= 0) {
initLogger = false;
break;
}
} // End of While Loop.
// in-code initialization is to log just errors to system out
if (initLogger) {
Properties p = new Properties();
p.setProperty("log4j.rootCategory", "ERROR" + ", stdout");
p.setProperty("log4j.appender.stdout", "org.apache.log4j.ConsoleAppender");
p.setProperty("log4j.appender.stdout.layout", "org.apache.log4j.PatternLayout");
p.setProperty("log4j.appender.stdout.layout.ConversionPattern", LOG_LAYOUT);
LogManager.resetConfiguration();
PropertyConfigurator.configure(p);
// now attempt to load from the real property file
// (if it fails we get the in-code settings from above)
//reloadConfiguration();
}
} catch (Exception e) {
System.out.println("Logging initialization failed.");
e.printStackTrace();
}
}
//---------------------------
// Public Methods
//---------------------------
/**
* Indicate if the Debug Level is Enabled for our current
* Category/Level.
*/
public boolean isDebugEnabled() {
return logger.isDebugEnabled();
} // End of isDebugEnabled public Method.
/**
* Indicate if the Info Level is Enabled for our current
* Category/Level.
*/
public boolean isInfoEnabled() {
return logger.isInfoEnabled();
} // End of isInfoEnabled public Method.
/**
* Audit an entry
*
* @param userID A userID to be logged with the audit entry.
* @param messageKey The message key of the message to log.
*/
public void audit(String userID, String messageKey) {
auditp(userID, messageKey, null);
}
/**
* Audit an entry
*
* @param userID The user that is being auditted.
* @param messageKey The message key of the message to log
* @param arguments The arguments to be used in the message
*/
public void audit(String userID, String messageKey, Object[] arguments) {
auditp(userID, messageKey, arguments);
}
/**
* Get the currently set source class name
*
* @return String for the source class name attribute
*/
public String getSourceClass() {
return (sourceClass);
}
/**
* Get the currently set source method name
*
* @return String for the method name attribute
*/
public String getSourceMethod() {
return (sourceMethod);
}
/**
* Log a message
*
* @param level The level of the message to log
* @param messageKey The message key of the message to log
*/
public void log(FrameworkLoggerLevel level, String messageKey) {
logp(level, sourceClass, sourceMethod, messageKey, null);
}
/**
* Log a message
*
* @param level The level of the message to log
* @param methodName method name
* @param messageKey The message key of the message to log
*/
public void log(FrameworkLoggerLevel level, String methodName, String messageKey) {
logp(level, sourceClass, methodName, messageKey, null);
}
/**
* Log a message
*
* @param level The level of the message to log
* @param messageKey The message key of the message to log
* @param arguments The arguments to be substituted in the message.
*/
public void log(FrameworkLoggerLevel level, String messageKey, Object[] arguments) {
logp(level, sourceClass, sourceMethod, messageKey, arguments);
}
/**
* Log a message
*
* @param level The level of the message to log
* @param methodName method name
* @param messageKey The message key of the message to log
* @param arguments The arguments to be substituted in the message.
*/
public void log(FrameworkLoggerLevel level, String methodName, String messageKey, Object[] arguments) {
logp(level, sourceClass, methodName, messageKey, arguments);
}
/**
* Log a message with an exception
*
* @param level The level of the message to log
* @param messageKey The message key of the message to log
* @param thrown The exception to log
*/
public void log(FrameworkLoggerLevel level, String messageKey, Throwable thrown) {
logp(level, sourceClass, sourceMethod, messageKey, null, thrown);
}
/**
* Log a message with an exception
*
* @param level The level of the message to log
* @param methodName method name
* @param messageKey The message key of the message to log
* @param thrown The exception to log
*/
public void log(FrameworkLoggerLevel level, String methodName, String messageKey, Throwable thrown) {
logp(level, sourceClass, methodName, messageKey, null, thrown);
}
/**
* Log a message with an exception
*
* @param level The level of the message to log
* @param messageKey The message key of the message to log
* @param arguments The arguments to be used in the message
* @param thrown The exception to log
*/
public void log(FrameworkLoggerLevel level, String messageKey, Object[] arguments, Throwable thrown) {
logp(level, sourceClass, sourceMethod, messageKey, arguments, thrown);
}
/**
* Log a message with an exception
*
* @param level The level of the message to log
* @param methodName method name
* @param messageKey The message key of the message to log
* @param arguments The arguments to be used in the message
* @param thrown The exception to log
*/
public void log(FrameworkLoggerLevel level, String methodName, String messageKey, Object[] arguments, Throwable thrown) {
logp(level, sourceClass, methodName, messageKey, arguments, thrown);
}
/**
* Record a timing stats
*
* @param timingCategory The category of the timing log entry.
* @param source The fully qualified name of the class
* @param callingMethod The method this log entry is for
* @param messageKey The message key of the message to log
* @param arguments The arguments to be used in the message
* @param stopWatch An instance of a stop watch that has the recorded time
*/
public static void logTiming(String timingCategory, String source,
String callingMethod, String messageKey,
Object[] arguments, StopWatch stopWatch) {
logTimingp(timingCategory, source, callingMethod, messageKey, arguments, stopWatch);
}
/**
* Record a timing stats
*
* @param timingCategory The category of the timing log entry.
* @param source The fully qualified name of the class
* @param callingMethod The method this log entry is for
* @param messageKey The message key of the message to log
* @param stopWatch An instance of a stop watch that has the recorded time
*/
public static void logTiming(String timingCategory, String source,
String callingMethod, String messageKey,
StopWatch stopWatch) {
logTimingp(timingCategory, source, callingMethod, messageKey, null, stopWatch);
}
/**
* Log an audit method.
*
* @param userID - The id of the user the log event is for.
* @param messageKey - The message key of the message to log.
* @param arguments - The parameters to use in the message.
*/
static public void auditStatic(String userID, String messageKey, Object[] arguments) {
FrameworkLogger iLogger = new FrameworkLogger(NO_CLASS_NAME, NO_METHOD_NAME);
iLogger.audit(userID, messageKey, arguments);
}
/**
* Log an audit method.
*
* @param userID - The id of the user the log event is for.
* @param messageKey - The message key of the message to log.
*/
static public void auditStatic(String userID, String messageKey) {
FrameworkLogger iLogger = new FrameworkLogger(NO_CLASS_NAME, NO_METHOD_NAME);
iLogger.audit(userID, messageKey);
}
/**
* Static version to log a message
*
* @param sourceClass The fully qualified name of the class
* @param sourceMethod The name of the method
* @param level The level of the message to log
* @param messageKey The message key of the message to log
*/
public static void log(String sourceClass, String sourceMethod, FrameworkLoggerLevel level,
String messageKey) {
FrameworkLogger iLogger = new FrameworkLogger(sourceClass, sourceMethod);
iLogger.log(level, messageKey);
}
/**
* Static version to log a message with arguments.
*
* @param sourceClass The fully qualified name of the class
* @param sourceMethod The name of the method
* @param level The level of the message to log
* @param messageKey The message key of the message to log
* @param arguments The arguments to use in the message.
*/
public static void log(String sourceClass, String sourceMethod, FrameworkLoggerLevel level,
String messageKey, Object[] arguments) {
FrameworkLogger iLogger = new FrameworkLogger(sourceClass, sourceMethod);
iLogger.log(level, messageKey, arguments);
}
/**
* Static version to log a message with a throwable exception
*
* @param sourceClass The fully qualified name of the class
* @param sourceMethod The name of the method
* @param level The level of the message to log
* @param messageKey The message key of the message to log
* @param thrown The exception to log
*/
public static void log(String sourceClass, String sourceMethod, FrameworkLoggerLevel level,
String messageKey, Throwable thrown) {
FrameworkLogger iLogger = new FrameworkLogger(sourceClass, sourceMethod);
iLogger.log(level, messageKey, thrown);
}
/**
* Static version to log a message with a throwable exception
*
* @param sourceClass The fully qualified name of the class
* @param sourceMethod The name of the method
* @param level The level of the message to log
* @param messageKey The message key of the message to log
* @param arguments The arguments to use in the message.
* @param thrown The exception to log
*/
public static void log(String sourceClass, String sourceMethod, FrameworkLoggerLevel level,
String messageKey, Object[] arguments, Throwable thrown) {
FrameworkLogger iLogger = new FrameworkLogger(sourceClass, sourceMethod);
iLogger.log(level, messageKey, arguments, thrown);
}
/**
* Static version of logging a timing status message.
*
* @param timingCategory The category of the timing log entry.
* @param sourceClass The calling class for the log entry
* @param sourceMethod The method this log entry is for
* @param messageKey The message key to log.
* @param arguments The arguments to substitute into the message.
* @param stopWatch An instance of a stop watch that has the recorded time
*/
public static void logTiming(String timingCategory, Class sourceClass,
String sourceMethod, String messageKey,
Object[] arguments, StopWatch stopWatch) {
String callingClassName = sourceClass.getName();
logTiming(timingCategory, callingClassName, sourceMethod, messageKey, arguments, stopWatch);
}
/**
* Static version of logging a timing status message.
*
* @param timingCategory The category of the timing log entry.
* @param sourceClass The calling class for the log entry
* @param sourceMethod The method this log entry is for
* @param messageKey The message key to log.
* @param stopWatch An instance of a stop watch that has the recorded time
*/
public static void logTiming(String timingCategory, Class sourceClass,
String sourceMethod, String messageKey,
StopWatch stopWatch) {
logTiming(timingCategory, sourceClass, sourceMethod, messageKey, null, stopWatch);
}
/**
* Set the source class name
*
* @param sourceClass String for the source class name
*/
public void setSourceClass(String sourceClass) {
this.sourceClass = sourceClass;
logger = Logger.getLogger(sourceClass + '.' + sourceMethod);
}
/**
* Set the source method name
*
* @param sourceMethod String for the source method name
*/
public void setSourceMethod(String sourceMethod) {
this.sourceMethod = sourceMethod;
logger = Logger.getLogger(sourceClass + '.' + sourceMethod);
}
//---------------------------
// Internal methods
//---------------------------
/**
* Audit an entry
*
* @param userID The user that is being auditted.
* @param messageKey The message key of the message to log
* @param arguments The arguments to be used in the message
*/
public void auditp(String userID, String messageKey, Object[] arguments) {
String msgText = getMessage(messageKey, arguments);
FrameworkLogger iLogger = new FrameworkLogger(CATEGORY_NAME_AUDIT);
StringBuffer str = new StringBuffer();
str.append(" UserID:");
str.append(userID);
str.append(" MSG:");
str.append(msgText);
iLogger.logger.info(str.toString());
}
/**
* 1.3 version of logp. Remove this when we go to 1.4 logging
*/
protected void logp(FrameworkLoggerLevel level, String source, String method,
String messageKey, Object[] arguments) {
logger.log(MessageUtility.getLevel(messageKey, level), getMessage(messageKey, arguments));
}
/**
* 1.3 version of logp. Remove this when we go to 1.4 logging
*/
protected void logp(FrameworkLoggerLevel level, String source, String method,
String messageKey, Object[] arguments, Throwable thrown) {
logger.log(MessageUtility.getLevel(messageKey, level), getMessage(messageKey, arguments), thrown);
}
/**
* Record a timing stats
*
* @param timingCategory The category of the timing log entry.
* @param sourceClass The fully qualified name of the class
* @param callingMethod The method this log entry is for
* @param messageKey The message key of the message to log
* @param arguments The arguments to be used in the message
* @param stopWatch An instance of a stop watch that has the recorded time
*/
protected static void logTimingp(String timingCategory, String sourceClass,
String callingMethod, String messageKey,
Object[] arguments, StopWatch stopWatch) {
if (logTimingStats) {
String msgText = getMessage(messageKey, arguments);
FrameworkLogger iLogger = new FrameworkLogger(CATEGORY_NAME_TIMING);
msgText = (msgText != null) ? msgText.replace('\t', ' ')
// don't want this tab when we
// import log file into an excel
// spreadsheet
: "";
// Don't allow msgText
// to be NULL.
StringBuffer str = new StringBuffer();
sourceClass = sourceClass.substring(sourceClass.lastIndexOf(".") + 1);
str.append("\t").append(stopWatch.toString());
str.append("\t").append(timingCategory);
str.append("\t").append(sourceClass).append(".").append(callingMethod);
str.append("\tMSG: ").append(msgText);
iLogger.logger.info(str.toString());
}
} // End of logTimingp Protected method.
/*
* set the Log Timing Stats on or Off.
*/
public static void setLogTimingStats(boolean newLogTimingStats) {
logTimingStats = newLogTimingStats;
} // End of setLogTimingStats
/*
* Provides Indicator to determine if Logging Stats are active or not.
*/
public static boolean isLogTimingStatsOn() {
return logTimingStats;
} // End of isLogTimingStatsOn
/**
* Helper method that builds a string that has the current date formatted into a string.
*
* @return the formated string version of the current date.
*/
private static String getDTS() {
SimpleDateFormat formatter = new SimpleDateFormat("MMdd.HHmmss");
String dateTimeStamp = formatter.format(new Date());
return dateTimeStamp;
}
// Helper method to get the message from the Message Utility
private static String getMessage(String messageKey, Object[] arguments) {
// use the arguments if they are provided.
if ((arguments != null) && (arguments.length > 0)) {
return MessageUtility.getMessage(messageKey, arguments);
}
return MessageUtility.getMessage(messageKey);
}
}