|
|
|
@ -50,35 +50,35 @@ import java.lang.reflect.InvocationTargetException;
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* A logging framework wrapper that supports java.util.logging and log4j. |
|
|
|
|
* <P/> |
|
|
|
|
* <p/> |
|
|
|
|
* Logger hierarchies are stored at the Class level. |
|
|
|
|
* Log4j will be used if the Log4j system (not necessarily config files) are |
|
|
|
|
* found in the runtime classpath. |
|
|
|
|
* Otherwise, java.util.logging will be used. |
|
|
|
|
* <P/> |
|
|
|
|
* <p/> |
|
|
|
|
* This is pretty safe because for use cases where multiple hierarchies |
|
|
|
|
* are desired, classloader hierarchies will effectively isolate multiple |
|
|
|
|
* class-level Logger hierarchies. |
|
|
|
|
* <P/> |
|
|
|
|
* <p/> |
|
|
|
|
* Sad as it is, the java.util.logging facility lacks the most basic |
|
|
|
|
* developer-side and configuration-side capabilities. |
|
|
|
|
* Besides having a non-scalable discovery system, the designers didn't |
|
|
|
|
* comprehend the need for a level between WARNING and SEVERE! |
|
|
|
|
* Since we don't want to require log4j in Classpath, we have to live |
|
|
|
|
* with these constraints. |
|
|
|
|
* <P/> |
|
|
|
|
* <p/> |
|
|
|
|
* As with all the popular logging frameworks, if you want to capture a |
|
|
|
|
* stack trace, you must use the two-parameters logging methods. |
|
|
|
|
* I.e., you must also pass a String, or only toString() from your |
|
|
|
|
* throwable will be captured. |
|
|
|
|
* <P/> |
|
|
|
|
* <p/> |
|
|
|
|
* Usage example:<CODE><PRE> |
|
|
|
|
* private static FrameworkLogger logger = |
|
|
|
|
* FrameworkLogger.getLog(SqlTool.class); |
|
|
|
|
* FrameworkLogger.getLog(SqlTool.class); |
|
|
|
|
* ... |
|
|
|
|
* logger.finer("Doing something log-worthy"); |
|
|
|
|
* logger.finer("Doing something log-worthy"); |
|
|
|
|
* </PRE> </CODE> |
|
|
|
|
* |
|
|
|
|
* <p> |
|
|
|
|
* <p/> |
|
|
|
|
* The system level property <code>hsqldb.reconfig_logging=false</code> is |
|
|
|
|
* required to avoid configuration of java.util.logging. Otherwise |
|
|
|
@ -113,17 +113,17 @@ public class FrameworkLogger {
|
|
|
|
|
public static synchronized String report() { |
|
|
|
|
|
|
|
|
|
return new StringBuilder().append(loggerInstances.size()).append( |
|
|
|
|
" logger instances: ").append( |
|
|
|
|
loggerInstances.keySet()).toString(); |
|
|
|
|
" logger instances: ").append( |
|
|
|
|
loggerInstances.keySet()).toString(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static private Map loggerInstances = new HashMap(); |
|
|
|
|
static private Map jdkToLog4jLevels = new HashMap(); |
|
|
|
|
static private Method log4jGetLogger; |
|
|
|
|
static private Method log4jLogMethod; |
|
|
|
|
static private Map loggerInstances = new HashMap(); |
|
|
|
|
static private Map jdkToLog4jLevels = new HashMap(); |
|
|
|
|
static private Method log4jGetLogger; |
|
|
|
|
static private Method log4jLogMethod; |
|
|
|
|
static private boolean callerFqcnAvailable = false; |
|
|
|
|
private Object log4jLogger; |
|
|
|
|
private Logger jdkLogger; |
|
|
|
|
private Object log4jLogger; |
|
|
|
|
private Logger jdkLogger; |
|
|
|
|
|
|
|
|
|
// No need for more than one static, since we have only one console
|
|
|
|
|
static private boolean noopMode; // If true, then logging calls do nothing
|
|
|
|
@ -131,7 +131,8 @@ public class FrameworkLogger {
|
|
|
|
|
static { |
|
|
|
|
try { |
|
|
|
|
reconfigure(); |
|
|
|
|
} catch (SecurityException e) {} |
|
|
|
|
} catch (SecurityException e) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -148,10 +149,10 @@ public class FrameworkLogger {
|
|
|
|
|
*/ |
|
|
|
|
public static synchronized void clearLoggers(String prefixToZap) { |
|
|
|
|
|
|
|
|
|
Set targetKeys = new HashSet(); |
|
|
|
|
java.util.Iterator it = loggerInstances.keySet().iterator(); |
|
|
|
|
String k; |
|
|
|
|
String dottedPrefix = prefixToZap + '.'; |
|
|
|
|
Set targetKeys = new HashSet(); |
|
|
|
|
java.util.Iterator it = loggerInstances.keySet().iterator(); |
|
|
|
|
String k; |
|
|
|
|
String dottedPrefix = prefixToZap + '.'; |
|
|
|
|
|
|
|
|
|
while (it.hasNext()) { |
|
|
|
|
k = (String) it.next(); |
|
|
|
@ -165,36 +166,36 @@ public class FrameworkLogger {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static synchronized void |
|
|
|
|
populateJdkToLog4jLevels(String classString) |
|
|
|
|
populateJdkToLog4jLevels(String classString) |
|
|
|
|
throws ClassNotFoundException, IllegalAccessException, |
|
|
|
|
NoSuchMethodException, InvocationTargetException { |
|
|
|
|
Method log4jToLevel = Class.forName(classString).getMethod( |
|
|
|
|
"toLevel", new Class[]{ String.class }); |
|
|
|
|
"toLevel", new Class[]{String.class}); |
|
|
|
|
|
|
|
|
|
jdkToLog4jLevels.put(Level.ALL, |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{ "ALL" })); |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{"ALL"})); |
|
|
|
|
jdkToLog4jLevels.put(Level.FINER, |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{ "DEBUG" })); |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{"DEBUG"})); |
|
|
|
|
jdkToLog4jLevels.put(Level.WARNING, |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{ "ERROR" })); |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{"ERROR"})); |
|
|
|
|
jdkToLog4jLevels.put(Level.SEVERE, |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{ "FATAL" })); |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{"FATAL"})); |
|
|
|
|
jdkToLog4jLevels.put(Level.INFO, |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{ "INFO" })); |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{"INFO"})); |
|
|
|
|
jdkToLog4jLevels.put(Level.OFF, |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{ "OFF" })); |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{"OFF"})); |
|
|
|
|
jdkToLog4jLevels.put(Level.FINEST, |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{ "TRACE" })); |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{"TRACE"})); |
|
|
|
|
jdkToLog4jLevels.put(Level.WARNING, |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{ "WARN" })); |
|
|
|
|
log4jToLevel.invoke(null, |
|
|
|
|
new Object[]{"WARN"})); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void reconfigure() { |
|
|
|
@ -207,8 +208,8 @@ public class FrameworkLogger {
|
|
|
|
|
loggerInstances.clear(); |
|
|
|
|
jdkToLog4jLevels.clear(); |
|
|
|
|
|
|
|
|
|
log4jGetLogger = null; |
|
|
|
|
log4jLogMethod = null; |
|
|
|
|
log4jGetLogger = null; |
|
|
|
|
log4jLogMethod = null; |
|
|
|
|
callerFqcnAvailable = false; |
|
|
|
|
|
|
|
|
|
// Precedence:
|
|
|
|
@ -235,12 +236,12 @@ public class FrameworkLogger {
|
|
|
|
|
populateJdkToLog4jLevels("com.fr.third.apache.logging.log4j.Level"); |
|
|
|
|
|
|
|
|
|
log4jLogMethod = log4jLoggerClass.getMethod("log", |
|
|
|
|
new Class[] { |
|
|
|
|
Class.forName("com.fr.third.apache.logging.log4j.Level"), |
|
|
|
|
Object.class, Throwable.class |
|
|
|
|
}); |
|
|
|
|
new Class[]{ |
|
|
|
|
Class.forName("com.fr.third.apache.logging.log4j.Level"), |
|
|
|
|
Object.class, Throwable.class |
|
|
|
|
}); |
|
|
|
|
log4jGetLogger = log4jManagerClass.getMethod("getLogger", |
|
|
|
|
new Class[]{ String.class }); |
|
|
|
|
new Class[]{String.class}); |
|
|
|
|
// This last object is what we toggle on to generate either
|
|
|
|
|
// Log4j or Jdk Logger objects (to wrap).
|
|
|
|
|
|
|
|
|
@ -251,8 +252,8 @@ public class FrameworkLogger {
|
|
|
|
|
// successfully initialized with warnings due to bad config).
|
|
|
|
|
try { |
|
|
|
|
System.err.println( |
|
|
|
|
"<clinit> failure " |
|
|
|
|
+ "instantiating configured Log4j v2 system: " + e); |
|
|
|
|
"<clinit> failure " |
|
|
|
|
+ "instantiating configured Log4j v2 system: " + e); |
|
|
|
|
|
|
|
|
|
// It's possible we don't have write access to System.err.
|
|
|
|
|
} catch (Throwable t) { |
|
|
|
@ -266,8 +267,8 @@ public class FrameworkLogger {
|
|
|
|
|
// Reset
|
|
|
|
|
log4jLoggerClass = null; |
|
|
|
|
log4jManagerClass = null; |
|
|
|
|
log4jLogMethod = null; |
|
|
|
|
log4jGetLogger = null; |
|
|
|
|
log4jLogMethod = null; |
|
|
|
|
log4jGetLogger = null; |
|
|
|
|
jdkToLog4jLevels.clear(); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
@ -287,12 +288,12 @@ public class FrameworkLogger {
|
|
|
|
|
populateJdkToLog4jLevels("com.fr.third.apache.log4j.Level"); |
|
|
|
|
|
|
|
|
|
log4jLogMethod = log4jLoggerClass.getMethod("log", |
|
|
|
|
new Class[] { |
|
|
|
|
String.class, Class.forName("com.fr.third.apache.log4j.Priority"), |
|
|
|
|
Object.class, Throwable.class |
|
|
|
|
}); |
|
|
|
|
new Class[]{ |
|
|
|
|
String.class, Class.forName("com.fr.third.apache.log4j.Priority"), |
|
|
|
|
Object.class, Throwable.class |
|
|
|
|
}); |
|
|
|
|
log4jGetLogger = log4jManagerClass.getMethod("getLogger", |
|
|
|
|
new Class[]{ String.class }); |
|
|
|
|
new Class[]{String.class}); |
|
|
|
|
// This last object is what we toggle on to generate either
|
|
|
|
|
// Log4j or Jdk Logger objects (to wrap).
|
|
|
|
|
callerFqcnAvailable = true; |
|
|
|
@ -304,8 +305,8 @@ public class FrameworkLogger {
|
|
|
|
|
// successfully initialized with warnings due to bad config).
|
|
|
|
|
try { |
|
|
|
|
System.err.println( |
|
|
|
|
"<clinit> failure " |
|
|
|
|
+ "instantiating configured Log4j v1 system: " + e); |
|
|
|
|
"<clinit> failure " |
|
|
|
|
+ "instantiating configured Log4j v1 system: " + e); |
|
|
|
|
|
|
|
|
|
// It's possible we don't have write access to System.err.
|
|
|
|
|
} catch (Throwable t) { |
|
|
|
@ -319,8 +320,8 @@ public class FrameworkLogger {
|
|
|
|
|
// Reset
|
|
|
|
|
log4jLoggerClass = null; |
|
|
|
|
log4jManagerClass = null; |
|
|
|
|
log4jLogMethod = null; |
|
|
|
|
log4jGetLogger = null; |
|
|
|
|
log4jLogMethod = null; |
|
|
|
|
log4jGetLogger = null; |
|
|
|
|
callerFqcnAvailable = false; |
|
|
|
|
jdkToLog4jLevels.clear(); |
|
|
|
|
|
|
|
|
@ -343,7 +344,7 @@ public class FrameworkLogger {
|
|
|
|
|
ConsoleHandler consoleHandler = new ConsoleHandler(); |
|
|
|
|
|
|
|
|
|
consoleHandler.setFormatter( |
|
|
|
|
new BasicTextJdkLogFormatter(false)); |
|
|
|
|
new BasicTextJdkLogFormatter(false)); |
|
|
|
|
consoleHandler.setLevel(Level.INFO); |
|
|
|
|
|
|
|
|
|
istream = FrameworkLogger.class.getResourceAsStream(path); |
|
|
|
@ -371,8 +372,8 @@ public class FrameworkLogger {
|
|
|
|
|
noopMode = true; |
|
|
|
|
|
|
|
|
|
System.err.println( |
|
|
|
|
"<clinit> failure initializing JDK logging system. " |
|
|
|
|
+ "Continuing without Application logging."); |
|
|
|
|
"<clinit> failure initializing JDK logging system. " |
|
|
|
|
+ "Continuing without Application logging."); |
|
|
|
|
e.printStackTrace(); |
|
|
|
|
} finally { |
|
|
|
|
if (istream != null) { |
|
|
|
@ -380,7 +381,7 @@ public class FrameworkLogger {
|
|
|
|
|
istream.close(); |
|
|
|
|
} catch (IOException ioe) { |
|
|
|
|
System.err.println("Failed to close logging input stream: " |
|
|
|
|
+ ioe); |
|
|
|
|
+ ioe); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -397,10 +398,10 @@ public class FrameworkLogger {
|
|
|
|
|
} else { |
|
|
|
|
try { |
|
|
|
|
log4jLogger = log4jGetLogger.invoke(null, |
|
|
|
|
new Object[]{ s }); |
|
|
|
|
new Object[]{s}); |
|
|
|
|
} catch (Exception e) { |
|
|
|
|
throw new RuntimeException( |
|
|
|
|
"Failed to instantiate Log4j Logger", e); |
|
|
|
|
"Failed to instantiate Log4j Logger", e); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -412,7 +413,7 @@ public class FrameworkLogger {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* User's entry-point into this logging system. |
|
|
|
|
* <P/> |
|
|
|
|
* <p/> |
|
|
|
|
* You normally want to work with static (class-level) pointers to |
|
|
|
|
* logger instances, for performance efficiency. |
|
|
|
|
* See the class-level JavaDoc for a usage example. |
|
|
|
@ -431,7 +432,7 @@ public class FrameworkLogger {
|
|
|
|
|
*/ |
|
|
|
|
public static FrameworkLogger getLog(Class c, String contextId) { |
|
|
|
|
return (contextId == null) ? getLog(c) |
|
|
|
|
: getLog(contextId + '.' + c.getName()); |
|
|
|
|
: getLog(contextId + '.' + c.getName()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -442,7 +443,7 @@ public class FrameworkLogger {
|
|
|
|
|
*/ |
|
|
|
|
public static FrameworkLogger getLog(String baseId, String contextId) { |
|
|
|
|
return (contextId == null) ? getLog(baseId) |
|
|
|
|
: getLog(contextId + '.' + baseId); |
|
|
|
|
: getLog(contextId + '.' + baseId); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -465,9 +466,9 @@ public class FrameworkLogger {
|
|
|
|
|
* Just like FrameworkLogger.log(Level, String), |
|
|
|
|
* but also logs a stack trace. |
|
|
|
|
* |
|
|
|
|
* @param level java.util.logging.Level level to filter and log at |
|
|
|
|
* @param level java.util.logging.Level level to filter and log at |
|
|
|
|
* @param message Message to be logged |
|
|
|
|
* @param t Throwable whose stack trace will be logged. |
|
|
|
|
* @param t Throwable whose stack trace will be logged. |
|
|
|
|
* @see #log(Level, String) |
|
|
|
|
* @see Logger#log(Level, String) |
|
|
|
|
* @see Level |
|
|
|
@ -492,8 +493,8 @@ public class FrameworkLogger {
|
|
|
|
|
|
|
|
|
|
if (log4jLogger == null) { |
|
|
|
|
StackTraceElement[] elements = new Throwable().getStackTrace(); |
|
|
|
|
String c = ""; |
|
|
|
|
String m = ""; |
|
|
|
|
String c = ""; |
|
|
|
|
String m = ""; |
|
|
|
|
|
|
|
|
|
if (elements.length > revertMethods) { |
|
|
|
|
c = elements[revertMethods].getClassName(); |
|
|
|
@ -508,15 +509,15 @@ public class FrameworkLogger {
|
|
|
|
|
} else { |
|
|
|
|
try { |
|
|
|
|
log4jLogMethod.invoke(log4jLogger, callerFqcnAvailable |
|
|
|
|
? new Object[] { |
|
|
|
|
skipClass.getName(), jdkToLog4jLevels.get(level), |
|
|
|
|
message, t} |
|
|
|
|
: new Object[] { |
|
|
|
|
jdkToLog4jLevels.get(level), message, t} |
|
|
|
|
? new Object[]{ |
|
|
|
|
skipClass.getName(), jdkToLog4jLevels.get(level), |
|
|
|
|
message, t} |
|
|
|
|
: new Object[]{ |
|
|
|
|
jdkToLog4jLevels.get(level), message, t} |
|
|
|
|
); |
|
|
|
|
} catch (Exception e) { |
|
|
|
|
throw new RuntimeException( |
|
|
|
|
"Logging failed when attempting to log: " + message, e); |
|
|
|
|
"Logging failed when attempting to log: " + message, e); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -539,17 +540,17 @@ public class FrameworkLogger {
|
|
|
|
|
} else { |
|
|
|
|
try { |
|
|
|
|
log4jLogMethod.invoke(log4jLogger, callerFqcnAvailable |
|
|
|
|
? new Object[] { |
|
|
|
|
FrameworkLogger.class.getName(), |
|
|
|
|
jdkToLog4jLevels.get(level), message, null} |
|
|
|
|
: new Object[] { |
|
|
|
|
jdkToLog4jLevels.get(level), message, null} |
|
|
|
|
? new Object[]{ |
|
|
|
|
FrameworkLogger.class.getName(), |
|
|
|
|
jdkToLog4jLevels.get(level), message, null} |
|
|
|
|
: new Object[]{ |
|
|
|
|
jdkToLog4jLevels.get(level), message, null} |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// Test where SqlFile correct here.
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
throw new RuntimeException( |
|
|
|
|
"Logging failed when attempting to log: " + message, e); |
|
|
|
|
"Logging failed when attempting to log: " + message, e); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -557,7 +558,7 @@ public class FrameworkLogger {
|
|
|
|
|
// Wrappers
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* @param level java.util.logging.Level level to filter and log at |
|
|
|
|
* @param level java.util.logging.Level level to filter and log at |
|
|
|
|
* @param message Message to be logged |
|
|
|
|
* @see Logger#log(Level, String) |
|
|
|
|
* @see Level |
|
|
|
@ -679,21 +680,21 @@ public class FrameworkLogger {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Whether this JVM is configured with java.util.logging defaults. |
|
|
|
|
* |
|
|
|
|
* <p> |
|
|
|
|
* If the JRE-provided config file is not in the expected place, then |
|
|
|
|
* we return false. |
|
|
|
|
*/ |
|
|
|
|
public static boolean isDefaultJdkConfig() { |
|
|
|
|
|
|
|
|
|
File globalCfgFile = new File(System.getProperty("java.home"), |
|
|
|
|
"lib/logging.properties"); |
|
|
|
|
"lib/logging.properties"); |
|
|
|
|
|
|
|
|
|
if (!globalCfgFile.isFile()) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
FileInputStream fis = null; |
|
|
|
|
LogManager lm = LogManager.getLogManager(); |
|
|
|
|
LogManager lm = LogManager.getLogManager(); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
fis = new FileInputStream(globalCfgFile); |
|
|
|
@ -703,14 +704,14 @@ public class FrameworkLogger {
|
|
|
|
|
defaultProps.load(fis); |
|
|
|
|
|
|
|
|
|
Enumeration names = defaultProps.propertyNames(); |
|
|
|
|
int i = 0; |
|
|
|
|
String name; |
|
|
|
|
String liveVal; |
|
|
|
|
int i = 0; |
|
|
|
|
String name; |
|
|
|
|
String liveVal; |
|
|
|
|
|
|
|
|
|
while (names.hasMoreElements()) { |
|
|
|
|
i++; |
|
|
|
|
|
|
|
|
|
name = (String) names.nextElement(); |
|
|
|
|
name = (String) names.nextElement(); |
|
|
|
|
liveVal = lm.getProperty(name); |
|
|
|
|
|
|
|
|
|
if (liveVal == null) { |
|
|
|
|