package tcg.common;
import java.util.Enumeration;
import org.apache.log4j.Appender;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.RollingFileAppender;
public class LoggerManager
{
private static final String DEF_CONFIG_FILE = "logging.properties";
private static final String DEF_LOG_APPENDER = "LogFile";
private static final String DEF_APPENDER_MAXFILESIZE = "10MB";
private static final int DEF_APPENDER_MAXBACKUP = 10;
private static final String DEF_APPENDER_PATTERN = "%d{yyyy/MM/dd hh:mm:ss} %-5p %c{1} %%%x%% - %m [%F:%L]%n";
private static LoggerManager instance_ = null;
private static boolean isConfigured_ = false;
private static String logFile_ = "";
private LoggerManager()
{
}
protected void finalize() throws Throwable
{
instance_ = null;
super.finalize();
}
/**
* configure
*
* Configure the logging system.
*
* This will also be executed during instance creation, if it is not done yet.
*/
@SuppressWarnings("unchecked")
private void configure()
{
if (isConfigured_)
{
get_default_logger().warn("Logging is already configure.");
return;
}
//get the logging configuration file
String configFile = Utilities.getConfigurationFile(DEF_CONFIG_FILE);
//configure the logging
if (configFile.length() > 0)
{
PropertyConfigurator.configure(configFile);
}
else
{
BasicConfigurator.configure();
}
//get path to the current logfile
Enumeration appenders = get_default_logger().getAllAppenders();
while(appenders.hasMoreElements())
{
Appender appender = (Appender) appenders.nextElement();
//try to find the file appender.
if ( FileAppender.class.isAssignableFrom(appender.getClass()) )
{
FileAppender fileAppender = (FileAppender) appender;
logFile_ = fileAppender.getFile();
break;
}
}
}
/**
* Get the only instance of LoggerManager
*
* @return LoggerManager - the only instance of LoggerManager
*/
public static LoggerManager getInstance()
{
if (instance_ == null)
{
instance_ = new LoggerManager();
instance_.configure();
}
return instance_;
}
/**
* Get a specific logger.
*
* This will force the initialization and configuration of the logging system if
* it is not yet done.
*
* @param String - the logger name
* @return Logger - the logger object
*/
public static Logger getLogger(String loggerName)
{
getInstance(); //force to configure
return Logger.getLogger(loggerName);
}
/**
* Get the default logger.
*
* This will force the initialization and configuration of the logging system if
* it is not yet done.
*
* @return Logger - the default logger object
*/
public static Logger getDefaultLogger()
{
getInstance(); //force to configure
return get_default_logger();
}
/**
* Set log level of the default logger, thus affecting the whole logging hierarchy
* unless a log level is set for a specific hierarchy/logger.
*
* This will force the initialization and configuration of the logging system if
* it is not yet done.
*
* @param Level - the new logging level
*/
public static void setLogLevel(Level level)
{
getInstance(); //force to configure
get_default_logger().setLevel(level);
}
/**
* Set log level of a specific logger
* Doing this will prevent this specific logger from being affected by setLogLevel()
*
* This will force the initialization and configuration of the logging system if
* it is not yet done.
*
* @param String - the logger name
* @param Level - the new logging level
*/
public static void setLogLevelDetail(String loggerName, Level level)
{
getInstance(); //force to configure
Logger.getLogger(loggerName).setLevel(level);
}
/**
* Set the log file.
* This will only change/set the first file appender (logging destination) found.
*
* This will force the initialization and configuration of the logging system if
* it is not yet done.
*
* @param String - the new log file
*/
@SuppressWarnings("unchecked")
public static void setLogFile(String filename)
{
//input validation. ignore if the filename is empty
if (filename == null || filename.length() == 0) { return; }
getInstance(); //force to configure
//an optimization. do not reset if the current logfile is already as expected
if (filename.equals(logFile_)) { return; };
boolean hasFileAppender = false;
Logger logger = getDefaultLogger();
Enumeration appenders = logger.getAllAppenders();
while(appenders.hasMoreElements()) {
Appender appender = (Appender) appenders.nextElement();
//try to find the file appender.
if ( FileAppender.class.isAssignableFrom(appender.getClass()) ) {
FileAppender fileAppender = (FileAppender) appender;
//verbose
if (logger.isTraceEnabled()) {
logger.trace("Find a file appender: " + fileAppender.getName());
logger.trace("Logging file: " + fileAppender.getFile());
}
//change the file it writes to
String oldfile = fileAppender.getFile();
logger.info("Log file destination is about to change. New file: " + filename);
fileAppender.setFile(filename);
fileAppender.activateOptions();
logger.info("Log file destination changed. Old file: " + oldfile);
//set flag
hasFileAppender = true;
//there should only be one. but just in case, just change the first file appender
break;
}
}
//we do not have any file appender.
if (!hasFileAppender)
{
//create a new one with default setting!
RollingFileAppender appender = new RollingFileAppender();
appender.setName(DEF_LOG_APPENDER);
appender.setMaxFileSize(DEF_APPENDER_MAXFILESIZE);
appender.setMaxBackupIndex(DEF_APPENDER_MAXBACKUP);
PatternLayout layout = new PatternLayout(DEF_APPENDER_PATTERN);
appender.setLayout(layout);
appender.setFile(filename);
appender.activateOptions();
//add into the logger
logger.addAppender(appender);
}
//keep the logfile name
logFile_ = filename;
}
private static Logger get_default_logger()
{
return Logger.getRootLogger();
}
}