/*
* LoggerManager.java
*
* created: 3.8.2011
* charset: UTF-8
* license: MIT (X11) (See LICENSE file for full license)
*/
package cz.mp.k3bg.log;
import cz.mp.k3bg.Application;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Třída {@code LoggerManager} je správce logování.
* Pro jednotný způsob práce s logováním.
*
* @author Martin Pokorný
* @version 0.1
*/
public class LoggerManager {
/** */
public static final Level DEFAULT_NORMAL_LEVEL = Level.FINE;
/** */
public static final Level DEFAULT_DEBUG_LEVEL = Level.FINE;
/** Maximální velikost logovacího souboru. */
private static final int LOG_FILE_MAX_LEN = 10*1024*1024;
/**
* Handler pro ladění, který posílá detailní zprávy na
* <code>stderr</code>.
*/
private static ConsoleHandler debugHandler = null;
/** Handler posílající zprávy do souboru. */
private static FileHandler logFileHandler = null;
/** Jméno souboru, do kterého se má logovat. */
private static String logFileName = Application.DEFAULT_LOG_FILE_NAME;
/**
* Jméno kořenového, hlavního Loggeru.
* viz {@linkplain #getClassLogger(java.lang.Class)}
*/
static final String MAIN_LOGGER_NAME =
Application.NAME_SHORT.replaceAll("\\s", "-");
/**
* Hlavní, rodičovský Logger pro tento projekt.
*/
@SuppressWarnings("NonConstantLogger")
private static Logger MAIN_LOGGER = null;
// -----
/** Žádný konstruktor. */
private LoggerManager() {
}
/**
* Inicializace hlavního loggeru a inicializace handlerů.
*
* @see #initMainLogger()
* @see #reInitDebugHandler()
* @see #reInitLogFileHandler()
*/
private static void init() {
initMainLogger();
if (debugHandler == null) {
reInitDebugHandler();
}
if (logFileHandler == null) {
reInitLogFileHandler();
}
}
/**
* Inicializuje hlavní Logger ({@linkplain #MAIN_LOGGER}).
*/
private static void initMainLogger() {
if (MAIN_LOGGER == null) {
MAIN_LOGGER = Logger.getLogger(MAIN_LOGGER_NAME);
MAIN_LOGGER.setLevel(Level.ALL);
MAIN_LOGGER.setUseParentHandlers(false);
}
}
/**
* @throws IllegalStateException pokud se nepodaří inicializovat hlavní log
*/
private static void reInitDebugHandler() {
try {
debugHandler = new ConsoleHandler();
debugHandler.setEncoding(Application.CONSOLE_DEFAULT_CHARSET);
debugHandler.setLevel(Level.FINEST);
debugHandler.setFormatter(new DetailFormatter());
} catch (SecurityException ex) {
throw new IllegalStateException(ex.getMessage());
} catch (UnsupportedEncodingException ex) {
throw new IllegalStateException(ex.getMessage());
}
}
/**
*
* @throws IllegalStateException pokud není inicializovaný hlavní logger
*/
private static void reInitLogFileHandler() {
removeLogFileHandler();
try {
logFileHandler = new FileHandler(
LoggerManager.logFileName, LOG_FILE_MAX_LEN, 1, false);
logFileHandler.setLevel(Level.FINEST);
logFileHandler.setEncoding(Application.DEFAULT_CHARSET);
logFileHandler.setFormatter(new DetailFormatter());
} catch (IOException ex) {
throw new IllegalStateException(ex.getMessage());
} catch (SecurityException ex) {
throw new IllegalStateException(ex.getMessage());
}
addLogFileHandler();
}
/**
*
*/
private static void removeLogFileHandler() {
if (logFileHandler != null) {
if (MAIN_LOGGER == null) {
throw new IllegalStateException("MAIN_LOGGER=null");
}
MAIN_LOGGER.removeHandler(logFileHandler);
logFileHandler.close();
logFileHandler = null;
}
}
/**
* Přidá {@linkplain #logFileHandler} do hlavního Loggeru.
*/
private static void addLogFileHandler() {
if (MAIN_LOGGER == null) {
throw new IllegalStateException("MAIN_LOGGER=null");
}
MAIN_LOGGER.addHandler(logFileHandler);
}
/**
* Nastaví jméno souboru, kam se má logovat a inicilizuje obsluhu
* zápisu logů do souboru.
*
* @param logFileName
* @see #reInitLogFileHandler()
*/
public static void setLogFileName(String logFileName) {
if (logFileName == null || logFileName.isEmpty()) {
throw new IllegalArgumentException("logFileName is blank");
}
LoggerManager.logFileName = logFileName;
reInitLogFileHandler();
}
/**
* Získá jméno souboru, kam se má logovat.
*
* @return
*/
public static String getLogFileName() {
return LoggerManager.logFileName;
}
/**
* Získá Logger, který je ve stejné cestě jako je cesta jeho balíku,
* pouze navíc s kořenem: {@linkplain #MAIN_LOGGER_NAME}.
* <p>
* např: balík je {@literal cz.pokus.Trida},
* log je v: {@literal MAIN_LOGGER_NAME.cz.pokus.Trida}.
*
* @param clazz
* @return
*/
private static Logger getClassLogger(Class clazz) {
Logger log = Logger.getLogger(
MAIN_LOGGER_NAME + "." +
clazz.getName()); // cz.pokus.Trida
log.setUseParentHandlers(true);
return log;
}
/**
* Získá logger k zadané třídě.
*
* @param clazz
* @param debugClazz zda se má provádět ladící protokolování zadané třídy
* @return
*/
public static Logger getLogger(Class clazz, boolean debugClazz) {
return getLogger(clazz, debugClazz, DEFAULT_DEBUG_LEVEL);
}
/**
* Získá logger k zadané třídě.
*
* @param clazz
* @param debugClazz zda se má provádět ladící protokolování zadané třídy
* @param debugLogLevel od jaké úrovně se má provádět ladící
* protokolování zadané třídy.
* @return
*/
public static Logger getLogger(Class clazz, boolean debugClazz,
Level debugLogLevel) {
if (clazz == null || clazz.getName().isEmpty()) {
throw new IllegalArgumentException("clazz is blank");
}
if (debugLogLevel == null) {
throw new IllegalArgumentException("debugLogLevel=null");
}
Level debugLogLevelCopy = debugLogLevel;
// Application.isDebug() je jen pro podrobný log;
if (Application.isDebug()) {
debugLogLevelCopy = Level.FINEST;
}
// inicializace hlavního loggeru a inicializace handlerů
init();
Logger clazzLog = getClassLogger(clazz);
clazzLog.setLevel(debugLogLevelCopy);
// debugClazz je pro ladící logování na stderr
if (debugClazz) {
if (debugHandler != null) {
clazzLog.removeHandler(debugHandler);
clazzLog.addHandler(debugHandler);
}
}
if (!Application.isDebug() && !debugClazz) {
clazzLog.setLevel(DEFAULT_NORMAL_LEVEL);
}
return clazzLog;
}
} // LoggerManager