/* * Copyright (c) 2008, Harald Kuhr * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name "TwelveMonkeys" nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.twelvemonkeys.sql; import com.twelvemonkeys.lang.SystemUtil; import java.io.*; import java.util.Date; import java.util.Hashtable; import java.util.Properties; /** * Class used for logging. * The class currently supports four levels of logging (debug, warning, error * and info). * <P> * The class maintains a cahce of OutputStreams, to avoid more than one stream * logging to a specific file. The class should also be thread safe, in that no * more than one instance of the class can log to the same OuputStream. * <P> * <STRONG> * WARNING: The uniqueness of logfiles is based on filenames alone, meaning * "info.log" and "./info.log" will probably be treated as different files, * and have different streams attatched to them. * </STRONG> * <P> * <STRONG> * WARNING: The cached OutputStreams can possibly be in error state or be * closed without warning. Should be fixed in later versions! * </STRONG> * * @author Harald Kuhr (haraldk@iconmedialab.no) * @author last modified by $Author: haku $ * * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-sandbox/src/main/java/com/twelvemonkeys/sql/Log.java#1 $ * * @deprecated Use the JDK java.util.logging for logging. * This class is old and outdated, and is here only for compatibility. It will * be removed from the library in later releases. * <P> * All new code are strongly encouraged to use the org.apache.commons.logging * package for logging. * * @see java.util.logging.Logger * */ class Log { private static Hashtable streamCache = new Hashtable(); static { streamCache.put("System.out", System.out); streamCache.put("System.err", System.err); } private static Log globalLog = null; private String owner = null; private boolean logDebug = false; private boolean logWarning = false; private boolean logError = true; // Log errors! private boolean logInfo = false; private PrintStream debugLog = null; private PrintStream warningLog = null; private PrintStream errorLog = null; private PrintStream infoLog = null; /** * Init global log */ static { Properties config = null; try { config = SystemUtil.loadProperties(Log.class); } catch (FileNotFoundException fnf) { // That's okay. } catch (IOException ioe) { // Not so good log(System.err, "ERROR", Log.class.getName(), null, ioe); } globalLog = new Log(new Log(), config); // Defaults if (globalLog.debugLog == null) globalLog.setDebugLog(System.out); if (globalLog.warningLog == null) globalLog.setWarningLog(System.err); if (globalLog.errorLog == null) globalLog.setErrorLog(System.err); if (globalLog.infoLog == null) globalLog.setInfoLog(System.out); // Info globalLog.logDebug("Logging system started."); log(globalLog.infoLog, "INFO", Log.class.getName(), "Logging system started.", null); } /** * Internal use only */ private Log() { } /** * Creates a log */ public Log(Object owner) { this.owner = owner.getClass().getName(); } /** * Creates a log */ public Log(Object owner, Properties config) { this(owner); if (config == null) return; // Set logging levels logDebug = new Boolean(config.getProperty("logDebug", "false")).booleanValue(); logWarning = new Boolean(config.getProperty("logWarning", "false")).booleanValue(); logError = new Boolean(config.getProperty("logError", "true")).booleanValue(); logInfo = new Boolean(config.getProperty("logInfo", "true")).booleanValue(); // Set logging streams String fileName; try { if ((fileName = config.getProperty("debugLog")) != null) setDebugLog(fileName); if ((fileName = config.getProperty("warningLog")) != null) setWarningLog(fileName); if ((fileName = config.getProperty("errorLog")) != null) setErrorLog(fileName); if ((fileName = config.getProperty("infoLog")) != null) setInfoLog(fileName); } catch (IOException ioe) { if (errorLog == null) setErrorLog(System.err); logError("Could not create one or more logging streams! ", ioe); } } /** * Checks if we log debug info * * @return True if logging */ public boolean getLogDebug() { return logDebug; } /** * Sets wheter we are to log debug info * * @param logDebug Boolean, true if we want to log debug info */ public void setLogDebug(boolean logDebug) { this.logDebug = logDebug; } /** * Checks if we globally log debug info * * @return True if global logging */ /* public static boolean getGlobalDebug() { return globalDebug; } */ /** * Sets wheter we are to globally log debug info * * @param logDebug Boolean, true if we want to globally log debug info */ /* public static void setGlobalDebug(boolean globalDebug) { Log.globalDebug = globalDebug; } /* /** * Sets the OutputStream we want to print to * * @param os The OutputStream we will use for logging */ public void setDebugLog(OutputStream os) { debugLog = new PrintStream(os, true); } /** * Sets the filename of the File we want to print to. Equivalent to * setDebugLog(new FileOutputStream(fileName, true)) * * @param file The File we will use for logging * @see #setDebugLog(OutputStream) */ public void setDebugLog(String fileName) throws IOException { setDebugLog(getStream(fileName)); } /** * Prints debug info to the current debugLog * * @param message The message to log * @see #logDebug(String, Exception) */ public void logDebug(String message) { logDebug(message, null); } /** * Prints debug info to the current debugLog * * @param exception An Exception * @see #logDebug(String, Exception) */ public void logDebug(Exception exception) { logDebug(null, exception); } /** * Prints debug info to the current debugLog * * @param message The message to log * @param exception An Exception */ public void logDebug(String message, Exception exception) { if (!(logDebug || globalLog.logDebug)) return; if (debugLog != null) log(debugLog, "DEBUG", owner, message, exception); else log(globalLog.debugLog, "DEBUG", owner, message, exception); } // WARNING /** * Checks if we log warning info * * @return True if logging */ public boolean getLogWarning() { return logWarning; } /** * Sets wheter we are to log warning info * * @param logWarning Boolean, true if we want to log warning info */ public void setLogWarning(boolean logWarning) { this.logWarning = logWarning; } /** * Checks if we globally log warning info * * @return True if global logging */ /* public static boolean getGlobalWarning() { return globalWarning; } */ /** * Sets wheter we are to globally log warning info * * @param logWarning Boolean, true if we want to globally log warning info */ /* public static void setGlobalWarning(boolean globalWarning) { Log.globalWarning = globalWarning; } */ /** * Sets the OutputStream we want to print to * * @param os The OutputStream we will use for logging */ public void setWarningLog(OutputStream os) { warningLog = new PrintStream(os, true); } /** * Sets the filename of the File we want to print to. Equivalent to * setWarningLog(new FileOutputStream(fileName, true)) * * @param file The File we will use for logging * @see #setWarningLog(OutputStream) */ public void setWarningLog(String fileName) throws IOException { setWarningLog(getStream(fileName)); } /** * Prints warning info to the current warningLog * * @param message The message to log * @see #logWarning(String, Exception) */ public void logWarning(String message) { logWarning(message, null); } /** * Prints warning info to the current warningLog * * @param exception An Exception * @see #logWarning(String, Exception) */ public void logWarning(Exception exception) { logWarning(null, exception); } /** * Prints warning info to the current warningLog * * @param message The message to log * @param exception An Exception */ public void logWarning(String message, Exception exception) { if (!(logWarning || globalLog.logWarning)) return; if (warningLog != null) log(warningLog, "WARNING", owner, message, exception); else log(globalLog.warningLog, "WARNING", owner, message, exception); } // ERROR /** * Checks if we log error info * * @return True if logging */ public boolean getLogError() { return logError; } /** * Sets wheter we are to log error info * * @param logError Boolean, true if we want to log error info */ public void setLogError(boolean logError) { this.logError = logError; } /** * Checks if we globally log error info * * @return True if global logging */ /* public static boolean getGlobalError() { return globalError; } */ /** * Sets wheter we are to globally log error info * * @param logError Boolean, true if we want to globally log error info */ /* public static void setGlobalError(boolean globalError) { Log.globalError = globalError; } */ /** * Sets the OutputStream we want to print to * * @param os The OutputStream we will use for logging */ public void setErrorLog(OutputStream os) { errorLog = new PrintStream(os, true); } /** * Sets the filename of the File we want to print to. Equivalent to * setErrorLog(new FileOutputStream(fileName, true)) * * @param file The File we will use for logging * @see #setErrorLog(OutputStream) */ public void setErrorLog(String fileName) throws IOException { setErrorLog(getStream(fileName)); } /** * Prints error info to the current errorLog * * @param message The message to log * @see #logError(String, Exception) */ public void logError(String message) { logError(message, null); } /** * Prints error info to the current errorLog * * @param exception An Exception * @see #logError(String, Exception) */ public void logError(Exception exception) { logError(null, exception); } /** * Prints error info to the current errorLog * * @param message The message to log * @param exception An Exception */ public void logError(String message, Exception exception) { if (!(logError || globalLog.logError)) return; if (errorLog != null) log(errorLog, "ERROR", owner, message, exception); else log(globalLog.errorLog, "ERROR", owner, message, exception); } // INFO /** * Checks if we log info info * * @return True if logging */ public boolean getLogInfo() { return logInfo; } /** * Sets wheter we are to log info info * * @param logInfo Boolean, true if we want to log info info */ public void setLogInfo(boolean logInfo) { this.logInfo = logInfo; } /** * Checks if we globally log info info * * @return True if global logging */ /* public static boolean getGlobalInfo() { return globalInfo; } */ /** * Sets wheter we are to globally log info info * * @param logInfo Boolean, true if we want to globally log info info */ /* public static void setGlobalInfo(boolean globalInfo) { Log.globalInfo = globalInfo; } */ /** * Sets the OutputStream we want to print to * * @param os The OutputStream we will use for logging */ public void setInfoLog(OutputStream os) { infoLog = new PrintStream(os, true); } /** * Sets the filename of the File we want to print to. Equivalent to * setInfoLog(new FileOutputStream(fileName, true)) * * @param file The File we will use for logging * @see #setInfoLog(OutputStream) */ public void setInfoLog(String fileName) throws IOException { setInfoLog(getStream(fileName)); } /** * Prints info info to the current infoLog * * @param message The message to log * @see #logInfo(String, Exception) */ public void logInfo(String message) { logInfo(message, null); } /** * Prints info info to the current infoLog * * @param exception An Exception * @see #logInfo(String, Exception) */ public void logInfo(Exception exception) { logInfo(null, exception); } /** * Prints info info to the current infoLog * * @param message The message to log * @param exception An Exception */ public void logInfo(String message, Exception exception) { if (!(logInfo || globalLog.logInfo)) return; if (infoLog != null) log(infoLog, "INFO", owner, message, exception); else log(globalLog.infoLog, "INFO", owner, message, exception); } // LOG /** * Internal method to get a named stream */ private static OutputStream getStream(String name) throws IOException { OutputStream os = null; synchronized (streamCache) { if ((os = (OutputStream) streamCache.get(name)) != null) return os; os = new FileOutputStream(name, true); streamCache.put(name, os); } return os; } /** * Internal log method */ private static void log(PrintStream ps, String header, String owner, String message, Exception ex) { // Only allow one instance to print to the given stream. synchronized (ps) { // Create output stream for logging LogStream logStream = new LogStream(ps); logStream.time = new Date(System.currentTimeMillis()); logStream.header = header; logStream.owner = owner; if (message != null) logStream.println(message); if (ex != null) { logStream.println(ex.getMessage()); ex.printStackTrace(logStream); } } } } /** * Utility class for logging. * * Minimal overloading of PrintStream */ class LogStream extends PrintStream { Date time = null; String header = null; String owner = null; public LogStream(OutputStream ps) { super(ps); } public void println(Object o) { if (o == null) println("null"); else println(o.toString()); } public void println(String str) { super.println("*** " + header + " (" + time + ", " + time.getTime() + ") " + owner + ": " + str); } }