Mercurial > hg > blitz_condensed
view src/com/go/trove/log/Log.java @ 34:6f68e94c1fb8 default tip
Add CondensedStats monitoring utility, equivalent to vmstat
author | Dominic Cleal <dominic-cleal@cdo2.com> |
---|---|
date | Thu, 05 Aug 2010 11:07:25 +0100 |
parents | 3dc0c5604566 |
children |
line wrap: on
line source
/* ==================================================================== * Trove - Copyright (c) 1997-2000 Walt Disney Internet Group * ==================================================================== * The Tea Software License, Version 1.1 * * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. 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. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Walt Disney Internet Group (http://opensource.go.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact opensource@dig.com. * * 5. Products derived from this software may not be called "Tea", * "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet", * "Kettle", "Trove" or "BeanDoc" appear in their name, without prior * written permission of the Walt Disney Internet Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 WALT DISNEY INTERNET GROUP OR ITS * 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. * ==================================================================== * * For more information about Tea, please see http://opensource.go.com/. */ package com.go.trove.log; import java.io.*; import java.util.*; import java.lang.ref.WeakReference; /****************************************************************************** * General purpose logging class that operates using a hierarchy of Logs and * an event model. All LogEvents are categorized into one of four types: * debugging, informational, warning and error. * * A log event can be generated by writing to one of the four PrintWriter * fields provided (debug, info, warn and error), or by calling the debug, * info, warn or error methods. * * Logs can have a parent Log, which by default, receives all the events * that the Log generates or receives. If a log is disabled, it will not * generate or propagate events. * * Examples: * <pre> * Log log = new Log("test", null); * log.addLogListener(new LogScribe(new PrintWriter(System.out))); * * log.debug().println("Printing a debugging message"); * log.info("System running"); * * Syslog.info().println("Creating child log..."); * Log child = new Log("child", Syslog.log); * child.warn("This is a system warning..."); * * try { * ... * } * catch (Exception e) { * child.error(e); * } * * Log saved = new Log("saved", Syslog.log); * File logDir = new File("/logs/"); * OutputStream out = new DailyFileLogStream(logDir); * saved.addLogListener(new LogScribe(new PrintWriter(out))); * saved.info("Saved log file initialized"); * </pre> * * @author Brian S O'Neill * @version * <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 6/28/01 <!-- $--> * @see LogScribe * @see Syslog * @see LogEventParsingWriter * @see DailyFileLogStream */ public class Log implements LogListener, Serializable { private static final int ENABLED_MASK = 0x01; private static final int DEBUG_ENABLED_MASK = 0x02; private static final int INFO_ENABLED_MASK = 0x04; private static final int WARN_ENABLED_MASK = 0x08; private static final int ERROR_ENABLED_MASK = 0x10; private final transient PrintWriter mDebug; private final transient PrintWriter mInfo; private final transient PrintWriter mWarn; private final transient PrintWriter mError; private Log mParent; private Collection mChildren = new Vector(); private String mName; private String mDescription; private int mEnabledFlags = 0xfffffff; private transient List mListeners = new Vector(); /** * Create a new Log that inherits enabled settings from its parent. If no * parent is specified, then the Log is fully enabled. If a parent is * specified, then it is added automatically as a listener to this Log. * * @param name The optional name of this Log. * @param parent The parent Log that will be added as a LogListener to this * Log. If null, then this Log has no parent Log. */ public Log(String name, Log parent) { this(); if (parent != null) { mParent = parent; parent.mChildren.add(new WeakReference(this)); mEnabledFlags = parent.mEnabledFlags; addLogListener(parent); } mName = name; mDescription = name; } private Log() { LogEventParsingWriter writer; writer = new LogEventParsingWriter(this, LogEvent.DEBUG_TYPE, this) { public boolean isEnabled() { return isDebugEnabled(); } }; writer.addLogListener(this); mDebug = new PrintWriter(writer, true); writer = new LogEventParsingWriter(this, LogEvent.INFO_TYPE, this) { public boolean isEnabled() { return isInfoEnabled(); } }; writer.addLogListener(this); mInfo = new PrintWriter(writer, true); writer = new LogEventParsingWriter(this, LogEvent.WARN_TYPE, this) { public boolean isEnabled() { return isWarnEnabled(); } }; writer.addLogListener(this); mWarn = new PrintWriter(writer, true); writer = new LogEventParsingWriter(this, LogEvent.ERROR_TYPE, this) { public boolean isEnabled() { return isErrorEnabled(); } }; writer.addLogListener(this); mError = new PrintWriter(writer, true); } /** * adds a listener to the root log, the log with a null parent */ public void addRootLogListener(LogListener listener) { if (mParent == null) { addLogListener(listener); } else { mParent.addRootLogListener(listener); } } public void removeRootLogListener(LogListener listener) { mListeners.remove(listener); if (mParent == null) { removeLogListener(listener); } else { mParent.removeRootLogListener(listener); } } public void addLogListener(LogListener listener) { mListeners.add(listener); } public void removeLogListener(LogListener listener) { mListeners.remove(listener); } /** * If this Log is enabled, then dispatch the LogEvent to all of its * listeners as a logged message. */ public void logMessage(LogEvent e) { if (isEnabled()) { dispatchLogMessage(e); } } /** * If this Log is enabled, then dispatch the LogEvent to all of its * listeners as a logged exception. */ public void logException(LogEvent e) { if (isEnabled()) { dispatchLogException(e); } } private void dispatchLogMessage(LogEvent e) { int size = mListeners.size(); try { for (int i=0; i<size; i++) { ((LogListener)mListeners.get(i)).logMessage(e); } } catch (IndexOutOfBoundsException ex) { } } private void dispatchLogException(LogEvent e) { int size = mListeners.size(); try { for (int i=0; i<size; i++) { ((LogListener)mListeners.get(i)).logException(e); } } catch (IndexOutOfBoundsException ex) { } } /** * Returns a PrintWriter for debug messages. */ public PrintWriter debug() { return mDebug; } /** * Simple method for logging a single debugging message. */ public synchronized void debug(String s) { if (isEnabled() && isDebugEnabled()) { dispatchLogMessage(new LogEvent(this, LogEvent.DEBUG_TYPE, s)); } } /** * Simple method for logging a single debugging exception. */ public synchronized void debug(Throwable t) { if (isEnabled() && isDebugEnabled()) { dispatchLogException(new LogEvent(this, LogEvent.DEBUG_TYPE, t)); } } /** * Returns a PrintWriter for information messages. */ public PrintWriter info() { return mInfo; } /** * Simple method for logging a single information message. */ public synchronized void info(String s) { if (isEnabled() && isInfoEnabled()) { dispatchLogMessage(new LogEvent(this, LogEvent.INFO_TYPE, s)); } } /** * Simple method for logging a single information exception. */ public synchronized void info(Throwable t) { if (isEnabled() && isInfoEnabled()) { dispatchLogException(new LogEvent(this, LogEvent.INFO_TYPE, t)); } } /** * Returns a PrintWriter for warning messages. */ public PrintWriter warn() { return mWarn; } /** * Simple method for logging a single warning message. */ public synchronized void warn(String s) { if (isEnabled() && isWarnEnabled()) { dispatchLogMessage(new LogEvent(this, LogEvent.WARN_TYPE, s)); } } /** * Simple method for logging a single warning exception. */ public synchronized void warn(Throwable t) { if (isEnabled() && isWarnEnabled()) { dispatchLogException(new LogEvent(this, LogEvent.WARN_TYPE, t)); } } /** * Returns a PrintWriter for error messages. */ public PrintWriter error() { return mError; } /** * Simple method for logging a single error message. */ public synchronized void error(String s) { if (isEnabled() && isErrorEnabled()) { dispatchLogMessage(new LogEvent(this, LogEvent.ERROR_TYPE, s)); } } /** * Simple method for logging a single error exception. */ public synchronized void error(Throwable t) { if (isEnabled() && isErrorEnabled()) { dispatchLogException(new LogEvent(this, LogEvent.ERROR_TYPE, t)); } } /** * Returns a copy of the children Logs. */ public Log[] getChildren() { Collection copy; synchronized (mChildren) { copy = new ArrayList(mChildren.size()); Iterator it = mChildren.iterator(); while (it.hasNext()) { Log child = (Log)((WeakReference)it.next()).get(); if (child == null) { it.remove(); } else { copy.add(child); } } } return (Log[])copy.toArray(new Log[copy.size()]); } /** * Returns null if this Log has no name. */ public String getName() { return mName; } /** * Returns a brief description of this Log. By default, returns the name. */ public String getDescription() { return mDescription; } /** * Set the log's description text. */ public void setDescription(String desc) { mDescription = desc; } /** * Returns true if this Log is enabled. If log is disabled, then no log * events of any kind are generated or propagated to listeners. */ public boolean isEnabled() { return isEnabled(ENABLED_MASK); } /** * When this Log is enabled, all parent Logs are also enabled. When this * Log is disabled, parent Logs are unaffected. */ public synchronized void setEnabled(boolean enabled) { setEnabled(enabled, ENABLED_MASK); if (enabled) { Log parent; if ((parent = mParent) != null) { parent.setEnabled(true); } } } /** * Returns true if debug events for this Log are enabled. If debug events * are disabled, then no debug log events are generated, but they can be * propagated to listeners. */ public boolean isDebugEnabled() { return isEnabled(DEBUG_ENABLED_MASK); } /** * When debug is enabled, this Log is enabled and all parent Logs are * enabled. Disabling debug only affects this Log's debug state. */ public synchronized void setDebugEnabled(boolean enabled) { setEnabled(enabled, DEBUG_ENABLED_MASK); if (enabled) { setEnabled(true); } } /** * Returns true if info events for this Log are enabled. If info events * are disabled, then no info log events are generated, but they can be * propagated to listeners. */ public boolean isInfoEnabled() { return isEnabled(INFO_ENABLED_MASK); } /** * When info is enabled, this Log is enabled and all parent Logs are * enabled. Disabling info only affects this Log's info state. */ public synchronized void setInfoEnabled(boolean enabled) { setEnabled(enabled, INFO_ENABLED_MASK); if (enabled) { setEnabled(true); } } /** * Returns true if warn events for this Log are enabled. If warn events * are disabled, then no warn log events are generated, but they can be * propagated to listeners. */ public boolean isWarnEnabled() { return isEnabled(WARN_ENABLED_MASK); } /** * When warn is enabled, this Log is enabled and all parent Logs are * enabled. Disabling warn only affects this Log's warn state. */ public synchronized void setWarnEnabled(boolean enabled) { setEnabled(enabled, WARN_ENABLED_MASK); if (enabled) { setEnabled(true); } } /** * Returns true if error events for this Log are enabled. If error events * are disabled, then no error log events are generated, but they can be * propagated to listeners. */ public boolean isErrorEnabled() { return isEnabled(ERROR_ENABLED_MASK); } /** * When error is enabled, this Log is enabled and all parent Logs are * enabled. Disabling error only affects this Log's error state. */ public synchronized void setErrorEnabled(boolean enabled) { setEnabled(enabled, ERROR_ENABLED_MASK); if (enabled) { setEnabled(true); } } /** * Understands and applies the following boolean properties. True is the * default value if the value doesn't equal "false", ignoring case. * * <ul> * <li>enabled * <li>debug * <li>info * <li>warn * <li>error * </ul> */ public synchronized void applyProperties(Map properties) { if (properties.containsKey("enabled")) { setEnabled(!"false".equalsIgnoreCase ((String)properties.get("enabled"))); } if (properties.containsKey("debug")) { setDebugEnabled(!"false".equalsIgnoreCase ((String)properties.get("debug"))); } if (properties.containsKey("info")) { setInfoEnabled(!"false".equalsIgnoreCase ((String)properties.get("info"))); } if (properties.containsKey("warn")) { setWarnEnabled(!"false".equalsIgnoreCase ((String)properties.get("warn"))); } if (properties.containsKey("error")) { setErrorEnabled(!"false".equalsIgnoreCase ((String)properties.get("error"))); } } /** * Returns a short description of this log. */ public String toString() { return "Log[" + getDescription() + "]@" + Integer.toHexString(hashCode()); } private synchronized boolean isEnabled(int mask) { return (mEnabledFlags & mask) == mask; } private synchronized void setEnabled(boolean enabled, int mask) { if (enabled) { mEnabledFlags |= mask; } else { mEnabledFlags &= ~mask; } } }