- * public class SomeClass {
- * private static ILoggingTool logger =
- * LoggingToolFactory.createLoggingTool(SomeClass.class);
- * }
- *
- * There is no special reason not to make the logger private and static, as the logging
- * information is closely bound to one specific Class, not subclasses and not instances.
- *
- * The logger has five logging levels: - *
Consider that the debugging will not always be turned on. Therefore, it is better - * not to concatenate string in the logger.debug() call, but have the LoggingTool do - * this when appropriate. In other words, use: - *
- * logger.debug("The String X has this value: ", someString);
- * logger.debug("The int Y has this value: ", y);
- *
- * instead of:
- *
- * logger.debug("The String X has this value: " + someString);
- * logger.debug("The int Y has this value: " + y);
- *
- *
- * For logging calls that require even more computation you can use the
- * isDebugEnabled() method:
- *
- * if (logger.isDebugEnabled()) {
- * logger.info("The 1056389822th prime that is used is: ",
- * calculatePrime(1056389822));
- * }
- *
- *
- * The class uses log4j as a backend if available, and System.out otherwise.
- *
- * @cdk.module log4j
- * @cdk.githash
- * @cdk.builddepends log4j.jar
- */
-@TestClass("org.openscience.cdk.tools.LoggingToolTest")
-public class LoggingTool implements ILoggingTool {
-
- private boolean doDebug = false;
- private boolean toSTDOUT = false;
-
- private Logger log4jLogger;
- private static ILoggingTool logger;
- private String classname;
-
- private int stackLength; // NOPMD
-
- /** Default number of StackTraceElements to be printed by debug(Exception). */
- public final int DEFAULT_STACK_LENGTH = 5;
-
- /**
- * Constructs a LoggingTool which produces log lines without any special
- * indication which class the message originates from.
- */
- public LoggingTool() {
- this(LoggingTool.class);
- }
-
- /**
- * Constructs a LoggingTool which produces log lines indicating them to be
- * for the Class of the Object.
- *
- * @param object Object from which the log messages originate
- */
- public LoggingTool(Object object) {
- this(object.getClass());
- }
-
- /**
- * Constructs a LoggingTool which produces log lines indicating them to be
- * for the given Class.
- *
- * @param classInst Class from which the log messages originate
- */
- public LoggingTool(Class> classInst) {
- LoggingTool.logger = this;
- stackLength = DEFAULT_STACK_LENGTH;
- this.classname = classInst.getName();
- try {
- log4jLogger = Logger.getLogger(classname);
- } catch (NoClassDefFoundError e) {
- toSTDOUT = true;
- logger.debug("Log4J class not found!");
- } catch (NullPointerException e) { // NOPMD
- toSTDOUT = true;
- logger.debug("Properties file not found!");
- } catch (Exception e) {
- toSTDOUT = true;
- logger.debug("Unknown error occured: ", e.getMessage());
- }
- /* **************************************************************
- * but some JVMs (i.e. MSFT) won't pass the SecurityException to
- * this exception handler. So we are going to check the JVM
- * version first
- ****************************************************************/
- doDebug = false;
- String strJvmVersion = System.getProperty("java.version");
- if (strJvmVersion.compareTo("1.2") >= 0) {
- // Use a try {} to catch SecurityExceptions when used in applets
- try {
- // by default debugging is set off, but it can be turned on
- // with starting java like "java -Dcdk.debugging=true"
- if (System.getProperty("cdk.debugging", "false").equals("true")) {
- doDebug = true;
- }
- if (System.getProperty("cdk.debug.stdout", "false").equals("true")) {
- toSTDOUT = true;
- }
- } catch (Exception e) {
- logger.debug("guessed what happened: security exception thrown by applet runner");
- logger.debug(" therefore, do not debug");
- }
- }
- }
-
- /**
- * Forces the LoggingTool to configurate the Log4J toolkit.
- * Normally this should be done by the application that uses the CDK library,
- * but is available for convenience.
- */
- @TestMethod("testConfigureLog4j")
- public static void configureLog4j() {
- LoggingTool localLogger = new LoggingTool(LoggingTool.class);
- try { // NOPMD
- org.apache.log4j.PropertyConfigurator.configure(
- LoggingTool.class.getResource("/org/openscience/cdk/config/data/log4j.properties"));
- } catch (NullPointerException e) { // NOPMD
- localLogger.error("Properties file not found: ", e.getMessage());
- localLogger.debug(e);
- } catch (Exception e) {
- localLogger.error("Unknown error occured: ", e.getMessage());
- localLogger.debug(e);
- }
- }
-
- /**
- * Outputs system properties for the operating system and the java
- * version. More specifically: os.name, os.version, os.arch, java.version
- * and java.vendor.
- */
- @TestMethod("testDumpSystemProperties")
- public void dumpSystemProperties() {
- debug("os.name : " + System.getProperty("os.name"));
- debug("os.version : " + System.getProperty("os.version"));
- debug("os.arch : " + System.getProperty("os.arch"));
- debug("java.version : " + System.getProperty("java.version"));
- debug("java.vendor : " + System.getProperty("java.vendor"));
- }
-
- /**
- * Sets the number of StackTraceElements to be printed in DEBUG mode when
- * calling debug(Throwable).
- * The default value is DEFAULT_STACK_LENGTH.
- *
- * @param length the new stack length
- *
- * @see #DEFAULT_STACK_LENGTH
- */
- @TestMethod("testSetStackLength_int")
- public void setStackLength(int length) {
- this.stackLength = length;
- }
-
- /**
- * Outputs the system property for java.class.path.
- */
- @TestMethod("testDumpClasspath")
- public void dumpClasspath() {
- debug("java.class.path: " + System.getProperty("java.class.path"));
- }
-
- /**
- * Shows DEBUG output for the Object. If the object is an instanceof
- * Throwable it will output the trace. Otherwise it will use the
- * toString() method.
- *
- * @param object Object to apply toString() too and output
- */
- @TestMethod("testDebug_Object")
- public void debug(Object object) {
- if (doDebug) {
- if (object instanceof Throwable) {
- debugThrowable((Throwable)object);
- } else {
- debugString("" + object);
- }
- }
- }
-
- private void debugString(String string) {
- if (toSTDOUT) {
- printToSTDOUT("DEBUG", string);
- } else {
- log4jLogger.debug(string);
- }
- }
-
- /**
- * Shows DEBUG output for the given Object's. It uses the
- * toString() method to concatenate the objects.
- *
- * @param object Object to apply toString() too and output
- * @param objects Object[] to apply toString() too and output
- */
- @TestMethod("testDebug_Object_int")
- public void debug(Object object, Object... objects) {
- if (doDebug) {
- StringBuilder result = new StringBuilder();
- result.append(object.toString());
- for (Object obj : objects) {
- result.append(obj.toString());
- }
- debugString(result.toString());
- }
- }
-
- private void debugThrowable(Throwable problem) {
- if (problem != null) {
- if (problem instanceof Error) {
- debug("Error: ", problem.getMessage());
- } else {
- debug("Exception: ", problem.getMessage());
- }
- java.io.StringWriter stackTraceWriter = new java.io.StringWriter();
- problem.printStackTrace(new PrintWriter(stackTraceWriter));
- String trace = stackTraceWriter.toString();
- try {
- BufferedReader reader = new BufferedReader(new StringReader(trace));
- if (reader.ready()) {
- String traceLine = reader.readLine();
- int counter = 0;
- while (reader.ready() && traceLine != null &&
- (counter < stackLength)) {
- debug(traceLine);
- traceLine = reader.readLine();
- counter++;
- }
- }
- } catch (Exception ioException) {
- error("Serious error in LoggingTool while printing exception stack trace: " +
- ioException.getMessage());
- logger.debug(ioException);
- }
- Throwable cause = problem.getCause();
- if (cause != null) {
- debug("Caused by: ");
- debugThrowable(cause);
- }
- }
- }
-
- /**
- * Shows ERROR output for the Object. It uses the toString() method.
- *
- * @param object Object to apply toString() too and output
- */
- @TestMethod("testError_Object")
- public void error(Object object) {
- if (doDebug) {
- errorString("" + object);
- }
- }
-
- /**
- * Shows ERROR output for the given Object's. It uses the
- * toString() method to concatenate the objects.
- *
- * @param object Object to apply toString() too and output
- * @param objects Object[] to apply toString() too and output
- */
- @TestMethod("testError_Object_int")
- public void error(Object object, Object... objects) {
- if (doDebug) {
- StringBuilder result = new StringBuilder();
- result.append(object.toString());
- for (Object obj : objects) {
- result.append(obj.toString());
- }
- errorString(result.toString());
- }
- }
-
- private void errorString(String string) {
- if (toSTDOUT) {
- printToSTDOUT("ERROR", string);
- } else {
- log4jLogger.error(string);
- }
- }
-
- /**
- * Shows FATAL output for the Object. It uses the toString() method.
- *
- * @param object Object to apply toString() too and output
- */
- @TestMethod("testFatal_Object")
- public void fatal(Object object) {
- if (doDebug) {
- if (toSTDOUT) {
- printToSTDOUT("FATAL", object.toString());
- } else {
- log4jLogger.fatal("" + object.toString());
- }
- }
- }
-
- /**
- * Shows INFO output for the Object. It uses the toString() method.
- *
- * @param object Object to apply toString() too and output
- */
- @TestMethod("testInfo_Object")
- public void info(Object object) {
- if (doDebug) {
- infoString("" + object);
- }
- }
-
- /**
- * Shows INFO output for the given Object's. It uses the
- * toString() method to concatenate the objects.
- *
- * @param object Object to apply toString() too and output
- * @param objects Object[] to apply toString() too and output
- */
- @TestMethod("testInfo_Object_int")
- public void info(Object object, Object... objects) {
- if (doDebug) {
- StringBuilder result = new StringBuilder();
- result.append(object.toString());
- for (Object obj : objects) {
- result.append(obj.toString());
- }
- infoString(result.toString());
- }
- }
-
- private void infoString(String string) {
- if (toSTDOUT) {
- printToSTDOUT("INFO", string);
- } else {
- log4jLogger.info(string);
- }
- }
-
- /**
- * Shows WARN output for the Object. It uses the toString() method.
- *
- * @param object Object to apply toString() too and output
- */
- @TestMethod("testWarn_Object")
- public void warn(Object object) {
- if (doDebug) {
- warnString("" + object);
- }
- }
-
- private void warnString(String string) {
- if (toSTDOUT) {
- printToSTDOUT("WARN", string);
- } else {
- log4jLogger.warn(string);
- }
- }
-
- /**
- * Shows WARN output for the given Object's. It uses the
- * toString() method to concatenate the objects.
- *
- * @param object Object to apply toString() too and output
- * @param objects Object[] to apply toString() too and output
- */
- @TestMethod("testWarn_Object_int")
- public void warn(Object object, Object... objects) {
- if (doDebug) {
- StringBuilder result = new StringBuilder();
- result.append(object.toString());
- for (Object obj : objects) {
- result.append(obj.toString());
- }
- warnString(result.toString());
- }
- }
- /**
- * Use this method for computational demanding debug info.
- * For example:
- *
- * if (logger.isDebugEnabled()) {
- * logger.info("The 1056389822th prime that is used is: ",
- * calculatePrime(1056389822));
- * }
- *
- *
- * @return true, if debug is enabled
- */
- @TestMethod("testIsDebugEnabled")
- public boolean isDebugEnabled() {
- return doDebug;
- }
-
- private void printToSTDOUT(String level, String message) {
- System.out.print(classname);
- System.out.print(" ");
- System.out.print(level);
- System.out.print(": ");
- System.out.println(message);
- }
-
- /**
- * Creates a new {@link LoggingTool} for the given class.
- *
- * @param sourceClass Class for which logging messages are recorded.
- * @return A {@link LoggingTool}.
- */
- @TestMethod("testCreate")
- public static ILoggingTool create(Class> sourceClass) {
- return new LoggingTool(sourceClass);
- }
-
-}
-