0001: package com.protomatter.syslog;
0002:
0003: /**
0004: * {{{ The Protomatter Software License, Version 1.0
0005: * derived from The Apache Software License, Version 1.1
0006: *
0007: * Copyright (c) 1998-2002 Nate Sammons. All rights reserved.
0008: *
0009: * Redistribution and use in source and binary forms, with or without
0010: * modification, are permitted provided that the following conditions
0011: * are met:
0012: *
0013: * 1. Redistributions of source code must retain the above copyright
0014: * notice, this list of conditions and the following disclaimer.
0015: *
0016: * 2. Redistributions in binary form must reproduce the above copyright
0017: * notice, this list of conditions and the following disclaimer in
0018: * the documentation and/or other materials provided with the
0019: * distribution.
0020: *
0021: * 3. The end-user documentation included with the redistribution,
0022: * if any, must include the following acknowledgment:
0023: * "This product includes software developed for the
0024: * Protomatter Software Project
0025: * (http://protomatter.sourceforge.net/)."
0026: * Alternately, this acknowledgment may appear in the software itself,
0027: * if and wherever such third-party acknowledgments normally appear.
0028: *
0029: * 4. The names "Protomatter" and "Protomatter Software Project" must
0030: * not be used to endorse or promote products derived from this
0031: * software without prior written permission. For written
0032: * permission, please contact support@protomatter.com.
0033: *
0034: * 5. Products derived from this software may not be called "Protomatter",
0035: * nor may "Protomatter" appear in their name, without prior written
0036: * permission of the Protomatter Software Project
0037: * (support@protomatter.com).
0038: *
0039: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0040: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0041: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0042: * DISCLAIMED. IN NO EVENT SHALL THE PROTOMATTER SOFTWARE PROJECT OR
0043: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0044: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0045: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0046: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0047: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0048: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0049: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0050: * SUCH DAMAGE. }}}
0051: */
0052:
0053: import java.io.*;
0054: import java.net.*;
0055: import java.util.*;
0056: import java.lang.reflect.*;
0057: import java.text.MessageFormat;
0058: import com.protomatter.util.*;
0059: import com.protomatter.Protomatter;
0060:
0061: /**
0062: * This class implements a system-wide logging utility. Please read the <a
0063: * href="syslog-whitepaper.html">Syslog Whitepaper</a> for more information. It
0064: * allows a program to log messages and objects at different severity levels in
0065: * a standardized way. The implementation of the log is specified by an object
0066: * which implements the Syslogger interface. You can have multiple log
0067: * implementations, and each can have it's own log mask or can inherit it's log
0068: * mask from Syslog (this is the default behavior).<P>
0069: *
0070: * There are 5 severity levels: DEBUG, INFO, WARNING, ERROR, FATAL. They
0071: * correspond to the numbers 0, 4, 8, 12, and 16, respectively. You can enable
0072: * logging for any combination of these levels. The default setting logs only
0073: * WARNING and above.<P>
0074: *
0075: *
0076: * <DL>
0077: * <DT> <B>Quickie introduction and usage:</B> </DT>
0078: * <DD>
0079: * <TABLEBORDER=1 CELLPADDING=5 CELLSPACING=0>
0080: *
0081: * <TR>
0082: *
0083: * <TD>
0084: * Anywhere you're doing this: <BLOCKQUOTE> <TT>
0085: * System.out.println("Some message");</TT> </BLOCKQUOTE> <P>
0086: *
0087: * Do this instead: <BLOCKQUOTE> <TT>Syslog.debug(this, "Some
0088: * message");</TT> </BLOCKQUOTE> <P>
0089: *
0090: * If you're in a <tt>static</tt> method, do this: <BLOCKQUOTE> <TT>
0091: * Syslog.debug(MyClass.class, "Some message");</TT> </BLOCKQUOTE> <P>
0092: *
0093: * If you like what this gets you, start playing around with different
0094: * log levels (call "<TT>Syslog.info(...)</TT> " and others). If you
0095: * like that, start playing around with channels and configuring the
0096: * loggers and other things. Syslog has a <u>very</u> robust API and
0097: * can be bent around to do all sorts of things, but it <u>does not
0098: * have to be complicated to use</u> even though it <u>can</u> be
0099: * configured in all sorts of complicated ways.
0100: * </TD>
0101: *
0102: * </TR>
0103: *
0104: * </TABLE>
0105: * </DD>
0106: * </DL>
0107: * <P>
0108: *
0109: *
0110: * <DL>
0111: * <DT> <B>More involved usage examples:</B> </DT>
0112: * <DD>
0113: * <TABLEBORDER=1 CELLPADDING=5 CELLSPACING=0>
0114: *
0115: * <TR>
0116: * <TD>
0117: * <pre>
0118: * // log simple message at DEBUG level
0119: * // pass 'this' as the object performing the logging
0120: * Syslog.log(this, "simple message", null, Syslog.DEBUG);<P>
0121: *
0122: * // this performs toString() on object 'obj', and prints a message
0123: * Syslog.log(this, "logging object", obj, Syslog.INFO);<P>
0124: *
0125: * // logs 'exception' and its stack trace at ERROR level
0126: * Syslog.log(this, exception);<P>
0127: *
0128: * // here's how you log in a static method -- pass the class object
0129: * Syslog.log(MyClass.class, "logging in MyClass");<P>
0130: *
0131: * // shortcuts for each log level Syslog.debug(this, "foo");
0132: * Syslog.debug(this, "foo", bar); Syslog.info(this, "foo");
0133: * Syslog.info(this, "foo", bar);<P>
0134: *
0135: * // log to multiple channels (the "foo" and "bar" channels)
0136: * Syslog.infoToChannel(this, new String[]{"foo", "bar"}, "My
0137: * message"); </pre>
0138: * </TD>
0139: * </TR>
0140: * </TABLE>
0141: * </DD>
0142: * </DL>
0143: * <P>
0144: *
0145: * There are basically three types of methods on this class for issuing log
0146: * messages. Whenever a channel name is not specified, the channel <tt>
0147: * DEFAULT_CHANNEL</tt> is used.<P>
0148: *
0149: * Whenever a channel is specified, it is an <tt>Object</tt> . This argument
0150: * can either be a <tt>String</tt> or an array of <tt>String</tt> (in which
0151: * case, the message will be sent out to multiple channels).<P>
0152: *
0153: *
0154: * <ul>
0155: * <dl>
0156: * <dt> <tt>log(...);</tt> <br>
0157: * </dt>
0158: * <dd> They have the following forms:<P>
0159: *
0160: * </dd>
0161: * <dd> <tt> log(Object logger, Throwable t);<br>
0162: * log(Object logger, Throwable t, int level);<br>
0163: * log(Object logger, Object msg, Object detail, int level);<br>
0164: * log(Object logger, Object chan, Object msg, Object detail, int level);
0165: * <br>
0166: * log(InetAddress host, Object logger, Throwable t);<br>
0167: * log(InetAddress host, Object logger, Throwable t, int level);<br>
0168: * log(InetAddress host, Object logger, Object msg, Object detail, int
0169: * level);<br>
0170: * log(InetAddress host, Object logger, Object chan, Object msg, Object
0171: * detail, int level);<br>
0172: * </tt> </dd> <P>
0173: *
0174: *
0175: * <dt> <tt>xxx(...);</tt> <br>
0176: * </dt>
0177: * <dd> Where "<tt>xxx</tt> " is "<tt>debug</tt> ", "<tt>info</tt> ", "<tt>
0178: * warning</tt> ", "<tt>error</tt> ", or "<tt>fatal</tt> " These are
0179: * shortcuts to the <tt>log(...)</tt> method for each log level. They have
0180: * the following forms:<P>
0181: *
0182: * </dd>
0183: * <dd> <tt> xxx(Object logger, Object msg);<br>
0184: * xxx(Object logger, Object msg, Object detail);<br>
0185: * xxx(InetAddress host, Object logger, Object msg);<br>
0186: * xxx(InetAddress host, Object logger, Object msg, Object detail);<br>
0187: * </tt> </dd> <P>
0188: *
0189: *
0190: * <dt> <tt>xxxToChannel(...);</tt> <br>
0191: * </dt>
0192: * <dd> Where "<tt>xxx</tt> " is "<tt>debug</tt> ", "<tt>info</tt> ", "<tt>
0193: * warning</tt> ", "<tt>error</tt> ", or "<tt>fatal</tt> " These are
0194: * shortcuts to the <tt>log(...)</tt> method for each log level, and to a
0195: * specific channel. They have the following forms:<P>
0196: *
0197: * </dd>
0198: * <dd> <tt> xxxToChannel(Object logger, Object chan, Object msg);<br>
0199: * xxxToChannel(Object logger, Object chan, Object msg, Object detail);<br>
0200: * xxxToChannel(InetAddress host, Object logger, Object chan, Object msg);
0201: * <br>
0202: * xxxToChannel(InetAddress host, Object logger, Object chan, Object msg,
0203: * Object detail);<br>
0204: * </tt> </dd> <P>
0205: *
0206: *
0207: * </dl>
0208: *
0209: * </ul><P>
0210: *
0211: * You may want to look at the <tt><a href="Channel.html">Channel</a></tt>
0212: * class. Some people prefet its API.<P>
0213: *
0214: * When the <TT>Syslog</TT> class is loaded, the following happens:<P>
0215: *
0216: *
0217: * <ol>
0218: * <li> If the <tt>Syslog.level</tt> system property is set, it is passed to
0219: * <tt>Syslog.setLogMask(...)</tt> (otherwise it defaults to <tt>WARNING</tt>
0220: * ).<P>
0221: *
0222: *
0223: * <li> A <tt>PrintWriterLog</tt> named "<TT>PrintWriterLog.err</TT> " is
0224: * added using <tt>Syslog.addLogger(...)</tt> and connected to the <tt>
0225: * System.err</tt> PrintStream.<P>
0226: *
0227: *
0228: * <li> If the <tt>Syslog.file</tt> system property is set, it is interpreted
0229: * as a filename and another <tt>PrintWriterLog</tt> is added and connected
0230: * to that file. The logger is named "<TT>PrintWriterLog.file</TT> ".
0231: * </ol>
0232: * <P>
0233: *
0234: * If you want to change these defaults, you can use the <tt>getLoggers()</tt>
0235: * , <tt>addLogger(...)</tt> , <tt>removeLogger(...)</tt> and <tt>
0236: * removeAllLoggers()</tt> methods to change what loggers are registered with
0237: * <tt>Syslog</tt> .<P>
0238: *
0239: * Syslog provides background work queues for loggers that need to perform
0240: * their operations asynchronously. For instance, the <tt>MailLog</tt> performs
0241: * its policy check synchronously and then if it decides that a message will
0242: * actually need to be sent, it asks syslog to perform the operation
0243: * asynchronously. This is far more efficient than doing <i>everything</i> in
0244: * the background because the amount of synchronization necessary to add work
0245: * to a queue is usually larger than a policy check.<P>
0246: *
0247: * <B>Please read the <a href="syslog-whitepaper.html">Syslog Whitepaper</a>
0248: * for more information on Syslog.</B> <P>
0249: *
0250: *
0251: *
0252: *@author nate
0253: *@created May 3, 2002
0254: *@see Syslogger
0255: *@see SyslogChannelAware
0256: */
0257: public class Syslog {
0258: public static final Debug debugging = Debug
0259: .forPackage(Syslog.class);
0260:
0261: /**
0262: * A log generated during debugging of the software.
0263: */
0264: public final static int DEBUG = 1;
0265:
0266: /**
0267: * An informational message that might come in handy later.
0268: */
0269: public final static int INFO = 2;
0270:
0271: /**
0272: * A warning message that the system administrator might want to know
0273: * about.
0274: */
0275: public final static int WARNING = 4;
0276:
0277: /**
0278: * One of the software components caused an error or exception.
0279: */
0280: public final static int ERROR = 8;
0281:
0282: /**
0283: * One of the software components is no longer functional.
0284: */
0285: public final static int FATAL = 16;
0286:
0287: /**
0288: * Loggers can inherit Syslog's log mask by setting their log mask to this
0289: * value.
0290: */
0291: public final static int INHERIT_MASK = 0;
0292:
0293: /**
0294: * The name of the default log channel.
0295: */
0296: public final static String DEFAULT_CHANNEL = "DEFAULT_CHANNEL";
0297:
0298: /**
0299: * The symbolic name for all channels.
0300: */
0301: public final static String ALL_CHANNEL = "*";
0302:
0303: /**
0304: * The current system-wide log mask. This variable is exposed so that
0305: * policies that inherit their mask from Syslog can get the value faster
0306: * than by calling a method.
0307: */
0308: public static int currentLogMask = atOrAbove(WARNING);
0309:
0310: /**
0311: * The name of a log channel for syslog configuration and system related
0312: * messages.
0313: */
0314: public static String SYSLOG_CHANNEL_NAME = "SYSLOG";
0315:
0316: /**
0317: * A log channel for syslog configuration and system related messages.
0318: */
0319: public static Channel channel = Channel
0320: .getChannel(SYSLOG_CHANNEL_NAME);
0321:
0322: // these loggers may or may not be synchronous.
0323: private static List loggers;
0324: private static Syslogger loggerArray[];
0325:
0326: private static Syslog instance = null;
0327:
0328: private static Map queueMap = new HashMap();
0329:
0330: private static InetAddress localHost = null;
0331:
0332: private static SyslogFlushThread flushThread = null;
0333:
0334: // turns off everything.
0335: private static boolean masterSwitch = true;
0336:
0337: private static String[] defaultChannelList = new String[] { DEFAULT_CHANNEL };
0338:
0339: private static String Q_MARK = "?";
0340:
0341: private static ResourceBundle resources = null;
0342:
0343: private static boolean computeCaller = false;
0344:
0345: private static boolean alwaysComputeCaller = false;
0346:
0347: /**
0348: * Syslog classloader warning system property name.
0349: */
0350: public final static String WARNING_PROPERTY = "Syslog.classloader.warning";
0351:
0352: /**
0353: * Protected constructor. Please don't make a subclass of <TT>Syslog</TT>
0354: * unless you really know what you're doing.
0355: */
0356: protected Syslog() {
0357: super ();
0358: }
0359:
0360: /**
0361: * Returns the global Syslog instance. You really should not need to get
0362: * ahold of it, as all the methods are static. You might want to get it so
0363: * that you can keep an instance around to keep the class from being
0364: * unloaded if you're writing application servers.
0365: *
0366: *@return The instance value
0367: */
0368: public static Syslog getInstance() {
0369: return instance;
0370: }
0371:
0372: /**
0373: * Set the flag for computing calling class and method
0374: * names at runtime. Default is <tt>false</tt>.
0375: */
0376: public static void setComputeCaller(boolean setting) {
0377: computeCaller = setting;
0378: }
0379:
0380: /**
0381: * Get the flag for computing calling class and method
0382: * names at runtime. Default is <tt>false</tt>.
0383: */
0384: public static boolean getComputeCaller() {
0385: return computeCaller;
0386: }
0387:
0388: /**
0389: * Set the flag for always computing calling class and method
0390: * names at runtime. Default is <tt>false</tt>.
0391: */
0392: public static void setAlwaysComputeCaller(boolean setting) {
0393: alwaysComputeCaller = setting;
0394: }
0395:
0396: /**
0397: * Get the flag for always computing calling class and method
0398: * names at runtime. Default is <tt>false</tt>. If this is
0399: * set to <tt>true</tt> then the correct method name and caller
0400: * are always computed so they are available to the
0401: * log policies. This can be overly expensive if you have
0402: * lots of debug statements. If this flag is set to <tt>false</tt>
0403: * then the caller class and method are only computed if
0404: * the log call passes the policy check, and if the
0405: * <tt>getComputeCallingClassAndMethod()</tt> flag is also
0406: * set to <tt>true</tt>.
0407: */
0408: public static boolean getAlwaysComputeCaller() {
0409: return alwaysComputeCaller;
0410: }
0411:
0412: /**
0413: * Get a map of the background work queues. The key to the map is the name
0414: * of the queue, and the value is a <tt>{@link
0415: * com.protomatter.util.WorkQueue com.protomatter.util.WorkQueue}</tt>
0416: * object. You should <i>never</i> play with the queues -- this method is
0417: * provided so that external processes can monitor the size of each queue
0418: * by calling the <tt>getObjectPoolSize()</tt> method on each queue. The
0419: * map itself is read-only.
0420: *
0421: *@return The workQueueMap value
0422: */
0423: public static Map getWorkQueueMap() {
0424: return Collections.unmodifiableMap(queueMap);
0425: }
0426:
0427: /**
0428: * Static initializer. Performs the initialization steps described above
0429: * when the class is loaded.
0430: */
0431: static {
0432: checkClassLoader();
0433: instance = new Syslog();
0434: loggers = new ArrayList();
0435: loggerArray = new Syslogger[0];
0436: init();
0437: }
0438:
0439: /**
0440: * Check to see if we are being loaded by the system classloader or not.
0441: */
0442: private static void checkClassLoader() {
0443: ClassLoader loader = Syslog.class.getClassLoader();
0444: String loaderString = loader.toString();
0445: ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
0446: ClassLoader systemLoaderParent = systemLoader.getParent();
0447: boolean warningFlag = "off".equalsIgnoreCase(System
0448: .getProperty(WARNING_PROPERTY));
0449:
0450: if ((systemLoader != loader) && (systemLoaderParent != loader)
0451: && (!warningFlag)) {
0452: System.err
0453: .println(" /***************************************************************************\\");
0454: System.err
0455: .println(" * *");
0456: System.err
0457: .println(" * Protomatter Syslog Classloader Warning *");
0458: System.err
0459: .println(" * -------------------------------------- *");
0460: System.err
0461: .println(" * *");
0462: System.err
0463: .println(" * Protomatter Syslog has been loaded by a classloader other than *");
0464: System.err
0465: .println(" * the system classloader. This indicates that the Syslog libraries *");
0466: System.err
0467: .println(" * are not in the system CLASSPATH. Usually this is because Syslog *");
0468: System.err
0469: .println(" * is being used in an application server and the Syslog libraries *");
0470: System.err
0471: .println(" * are in the \"lib\" directory for a WebApp or EAR, etc. *");
0472: System.err
0473: .println(" * *");
0474: System.err.println(" * ClassLoader: "
0475: + StringUtil.pad(loaderString, 56) + " *");
0476: System.err
0477: .println(" * *");
0478: System.err
0479: .println(" * Syslog may not work as you might expect if it is not loaded by *");
0480: System.err
0481: .println(" * the system classloader. Under some circumstances, users may want *");
0482: System.err
0483: .println(" * to take advantage of features of this kind of configuration. If *");
0484: System.err
0485: .println(" * this is the case, you can disable this warning message by setting *");
0486: System.err
0487: .println(" * the \"Syslog.classloader.warning\" system property to \"off\". In *");
0488: System.err
0489: .println(" * most cases, though, you don't want to do that. *");
0490: System.err
0491: .println(" * *");
0492: System.err
0493: .println(" * For more information on this behavior and the logic behind it, *");
0494: System.err
0495: .println(" * please see the documentation at the following address: *");
0496: System.err
0497: .println(" * *");
0498: System.err
0499: .println(" * http://protomatter.sourceforge.net/"
0500: + StringUtil.pad(Protomatter.VERSION
0501: + "/javadoc/", 32) + " *");
0502: System.err
0503: .println(" * com/protomatter/syslog/classloader-warning.html *");
0504: System.err
0505: .println(" * *");
0506: System.err
0507: .println(" \\**************************************************************************/");
0508: }
0509: }
0510:
0511: /**
0512: * Get the local hostname.
0513: *
0514: *@return The localHostName value
0515: */
0516: public static InetAddress getLocalHostName() {
0517: return localHost;
0518: }
0519:
0520: /**
0521: * Set the number of milliseconds a flush thread should wait before
0522: * flushing output on each logger. If the interval is 0 (or negative) the
0523: * thread will be stopped. The default is not to have a flush thread
0524: * running. You cannot set it to less than 1000ms, except for setting it to
0525: * 0.
0526: *
0527: *@param interval The new flushThreadInterval value
0528: */
0529: public static void setFlushThreadInterval(long interval) {
0530: synchronized (instance) {
0531: if (flushThread != null) {
0532: flushThread.stopRunning();
0533: flushThread = null;
0534: }
0535:
0536: if (interval > 0) {
0537: if (interval < 1000) {
0538: throw new IllegalArgumentException(
0539: MessageFormat
0540: .format(
0541: getResourceString(MessageConstants.CANNOT_SET_FLUSH_INTERVAL_MESSAGE),
0542: new Object[] { "1000", "0" }));
0543: }
0544:
0545: flushThread = new SyslogFlushThread(interval);
0546: flushThread.start();
0547: }
0548: }
0549: }
0550:
0551: /**
0552: * Get the sleep interval of the logger flush thread. This method will
0553: * either return the number of milliseconds between flush calls, or zero if
0554: * there is no flush thread running.
0555: *
0556: *@return The flushThreadInterval value
0557: */
0558: public static long getFlushThreadInterval() {
0559: synchronized (instance) {
0560: if (flushThread != null) {
0561: return flushThread.getSleepInterval();
0562: }
0563: return 0;
0564: }
0565: }
0566:
0567: /**
0568: * Set the local hostname automatically. This sets the hostname to whatever
0569: * <tt>InetAddress.getLocalHost()</tt> returns. This is called by <tt>
0570: * SimpleSyslogTextFormatter</tt> when it is configured if it is supposed
0571: * to log the host name.
0572: */
0573: public static void setLocalHostName() {
0574: try {
0575: setLocalHostName(InetAddress.getLocalHost());
0576: } catch (UnknownHostException x) {
0577: throw new IllegalStateException(
0578: getResourceString(MessageConstants.CANNOT_DETERMINE_HOSTNAME_MESSAGE));
0579: }
0580: }
0581:
0582: /**
0583: * Set the local hostname.
0584: *
0585: *@param host The new localHostName value
0586: */
0587: public static void setLocalHostName(InetAddress host) {
0588: localHost = host;
0589: }
0590:
0591: /**
0592: * Set the value of the master switch. If this switch is set to <TT>false
0593: * </TT>, then all log requests will be ignored.
0594: *
0595: *@param value The new masterSwitch value
0596: */
0597: public static void setMasterSwitch(boolean value) {
0598: masterSwitch = value;
0599: }
0600:
0601: /**
0602: * Add work to the given background queue. Queues are created (but not
0603: * destroyed) dynamically.
0604: *
0605: *@param queueName The feature to be added to the Work attribute
0606: *@param r The feature to be added to the Work attribute
0607: */
0608: public static void addWork(String queueName, Runnable r) {
0609: WorkQueue queue = (WorkQueue) queueMap.get(queueName);
0610: if (queue == null) {
0611: synchronized (queueMap) {
0612: // re-check once in here to avoid race conditions.
0613: queue = (WorkQueue) queueMap.get(queueName);
0614: if (queue == null) {
0615: queue = new WorkQueue("Syslog: " + queueName, 1);
0616: queueMap.put(queueName, queue);
0617: }
0618: }
0619: }
0620: queue.addWork(r);
0621: }
0622:
0623: /**
0624: * Initializes the logging facility. This gets called upon initialization,
0625: * and can be called multiple times during a program. It checks the system
0626: * properties file for "syslog.level" property and sets the default log
0627: * mask to that value. Also, if "syslog.file" is defined, will log to that
0628: * file.<P>
0629: *
0630: * If the "<tt>Syslog.config.xml</tt>" system property is set,
0631: * then the XML configuration helper is loaded and Syslog
0632: * is configured. See the <tt><a href="xml/SyslogXML.html#configure(org.jdom.Element)">SylogXML</a></tt>
0633: * class for more information.
0634: */
0635: private final static synchronized void init() {
0636: resources = ResourceBundle
0637: .getBundle("com.protomatter.syslog.Syslog");
0638:
0639: String loglevelstr = System.getProperty("Syslog.level");
0640: if (loglevelstr != null) {
0641: // either give the value as the number or "DEBUG", etc...
0642: try {
0643: int loglevel = Integer.parseInt(loglevelstr);
0644: setLogMask(atOrAbove(loglevel));
0645: } catch (NumberFormatException x) {
0646: setLogMask(loglevelstr);
0647: }
0648: }
0649:
0650: // add the logger that writes to Stderr.
0651: Syslogger l = new PrintWriterLog("System.err");
0652: l.setName("PrintWriterLog.err");
0653: addLogger(l);
0654:
0655: // add a logger that writes to a file.
0656: String logfilestr = System.getProperty("Syslog.file");
0657: if (logfilestr != null) {
0658: FileLog fileLogger = new FileLog(new File(logfilestr));
0659: fileLogger.setName("FileLog.file");
0660: addLogger(fileLogger);
0661: }
0662:
0663: if (System.getProperty("Syslog.config.xml") != null) {
0664: // load the class manually so that we don't get this class
0665: // depending on the XML things.
0666: try {
0667: Class config = Class
0668: .forName("com.protomatter.syslog.xml.SyslogXML");
0669: Method configure = config.getMethod("configure",
0670: new Class[] { File.class, String.class,
0671: Boolean.TYPE });
0672: configure.invoke(null, new Object[] {
0673: new File(System
0674: .getProperty("Syslog.config.xml")),
0675: System.getProperty("Syslog.xml.parser"),
0676: new Boolean(true) });
0677: } catch (Exception x) {
0678: System.err
0679: .println(Syslog
0680: .getResourceString(MessageConstants.CANNOT_CONFIGURE_MESSAGE));
0681: x.printStackTrace();
0682: }
0683: }
0684: }
0685:
0686: /**
0687: * Registers a new Syslogger object with Syslog.
0688: *
0689: *@param log The feature to be added to the Logger attribute
0690: */
0691: public final static synchronized void addLogger(Syslogger log) {
0692: loggers.add(log);
0693: loggerArray = (Syslogger[]) loggers.toArray(new Syslogger[0]);
0694: }
0695:
0696: /**
0697: * Deregisters a Syslogger object from Syslog.
0698: *
0699: *@param log The logger to remove
0700: *@return true if the logger was removed
0701: */
0702: public final static synchronized boolean removeLogger(Syslogger log) {
0703: if (loggers.contains(log)) {
0704: loggers.remove(loggers.indexOf(log));
0705: loggerArray = (Syslogger[]) loggers
0706: .toArray(new Syslogger[0]);
0707: return true;
0708: }
0709: return false;
0710: }
0711:
0712: /**
0713: * Deregisters all Syslogger objects.
0714: */
0715: public final static synchronized void removeAllLoggers() {
0716: loggers = new ArrayList();
0717: loggerArray = new Syslogger[0];
0718: }
0719:
0720: /**
0721: * Returns an Enumeration of all Syslogger objects registered with Syslog.
0722: *
0723: *@return The loggers value
0724: */
0725: public final static Iterator getLoggers() {
0726: return loggers.iterator();
0727: }
0728:
0729: /**
0730: * Remove all the loggers and shut them down. Waits for all background
0731: * queues to finish processing work. Any new messages received immediately
0732: * after this method is called (before it completes) will be ignored.
0733: */
0734: public static synchronized void shutdown() {
0735: // turn everything off.
0736: masterSwitch = false;
0737:
0738: // remove loggers just in case.
0739: List list = loggers;
0740: removeAllLoggers();
0741:
0742: // wait for all background queues to shut down.
0743: Iterator i = queueMap.keySet().iterator();
0744: while (i.hasNext()) {
0745: String queueName = (String) i.next();
0746: WorkQueue queue = (WorkQueue) queueMap.get(queueName);
0747: while ((queue.getQueueLength() > 0)
0748: || (queue.getNumWorkers() > 0)) {
0749: try {
0750: Thread.yield();
0751: Thread.sleep(100);
0752: } catch (InterruptedException x) {
0753: ; // who cares.
0754: }
0755: }
0756: }
0757:
0758: // shut 'em down. Loggers should flush and close files, etc.
0759: i = list.iterator();
0760: while (i.hasNext()) {
0761: Syslogger l = (Syslogger) i.next();
0762: l.shutdown();
0763: }
0764: }
0765:
0766: /**
0767: * Get a logger by name. If there are multiple loggers with the same name,
0768: * the first one registered with that name will be returned. If there is no
0769: * logger by that name, <tt>null</tt> is returned.
0770: *
0771: *@param name The name of the logger to get.
0772: *@return The logger
0773: */
0774: public final static Syslogger getLogger(String name) {
0775: Iterator i = getLoggers();
0776: Syslogger l = null;
0777: while (i.hasNext()) {
0778: l = (Syslogger) i.next();
0779: if (l.getName() == null && name == null) {
0780: return l;
0781: }
0782: if (l.getName() != null && name != null
0783: && l.getName().equals(name)) {
0784: return l;
0785: }
0786: }
0787: return null;
0788: }
0789:
0790: /**
0791: * Set the default mask for logging of messages. For example, to log all
0792: * messages of type ERROR or greater, you would:
0793: * Syslog.setLogMask(Syslog.atOrAbove(ERROR));
0794: *
0795: *@param mask The new logMask value
0796: */
0797: public final static void setLogMask(int mask) {
0798: if (mask == INHERIT_MASK) {
0799: throw new IllegalArgumentException(
0800: MessageFormat
0801: .format(
0802: getResourceString(MessageConstants.CANNOT_SET_MASK_MESSAGE),
0803: new Object[] { "INHERIT_MASK" }));
0804: }
0805: currentLogMask = mask;
0806: }
0807:
0808: /**
0809: * Set the mask.
0810: *
0811: *@param mask The new logMask value
0812: *@see #parseLogMask
0813: */
0814: public final static void setLogMask(String mask) {
0815: setLogMask(parseLogMask(mask));
0816: }
0817:
0818: /**
0819: * Parse the mask. If the value passed in is the name of a level, like "
0820: * <TT>INFO</TT> " or "<TT>WARNING</TT> " the mask will be set to <I>at or
0821: * above</I> the listed level. If the string passed in is "<TT>INHERIT_MASK
0822: * </TT>" then this policy will inherit the mask set in Syslog itself.<P>
0823: *
0824: * You can also pass in a list of levels, separated by commas and with an "
0825: * <TT>=</TT> " before each level to select non-contiguous groups of
0826: * levels. For instance, passing in "<TT>=INFO,=ERROR</TT> " will catch
0827: * messages only at the <TT>INFO</TT> and <TT>ERROR</TT> levels, and <I>
0828: * NOTHING ELSE</I> .
0829: *
0830: *@param mask String representation of the mask
0831: *@return Computed log mask
0832: */
0833: public final static int parseLogMask(String mask) {
0834: if (mask.equals("DEBUG")) {
0835: return Syslog.atOrAbove(Syslog.DEBUG);
0836: } else if (mask.equals("INFO")) {
0837: return Syslog.atOrAbove(Syslog.INFO);
0838: } else if (mask.equals("WARNING")) {
0839: return Syslog.atOrAbove(Syslog.WARNING);
0840: } else if (mask.equals("ERROR")) {
0841: return Syslog.atOrAbove(Syslog.ERROR);
0842: } else if (mask.equals("FATAL")) {
0843: return Syslog.atOrAbove(Syslog.FATAL);
0844: } else if (mask.equals("INHERIT_MASK")) {
0845: return Syslog.INHERIT_MASK;
0846: } else if (mask.startsWith("=")) {
0847: int newMask = 0;
0848: StringTokenizer st = new StringTokenizer(mask, ", ");
0849: while (st.hasMoreTokens()) {
0850: String elt = st.nextToken().substring(1);
0851: if (elt.equals("DEBUG")) {
0852: newMask |= Syslog.DEBUG;
0853: } else if (elt.equals("INFO")) {
0854: newMask |= Syslog.INFO;
0855: } else if (elt.equals("WARNING")) {
0856: newMask |= Syslog.WARNING;
0857: } else if (elt.equals("ERROR")) {
0858: newMask |= Syslog.ERROR;
0859: } else if (elt.equals("FATAL")) {
0860: newMask |= Syslog.FATAL;
0861: }
0862: }
0863: return newMask;
0864: } else {
0865: throw new IllegalArgumentException(
0866: getResourceString(MessageConstants.INVALID_MASK_MESSAGE));
0867: }
0868: }
0869:
0870: /**
0871: * Get a string representation of the current master log mask.
0872: *
0873: *@return The logMaskAsString value
0874: */
0875: public static String getLogMaskAsString() {
0876: return getLogMaskAsString(currentLogMask);
0877: }
0878:
0879: /**
0880: * Get a string representation of the given log mask.
0881: *
0882: *@param logMask The parsed log mask
0883: *@return The log mask rendered as a string
0884: */
0885: public static String getLogMaskAsString(int logMask) {
0886: if (logMask == Syslog.INHERIT_MASK) {
0887: return "INHERIT_MASK";
0888: } else if (logMask == Syslog.atOrAbove(Syslog.DEBUG)) {
0889: return "DEBUG";
0890: } else if (logMask == Syslog.atOrAbove(Syslog.INFO)) {
0891: return "INFO";
0892: } else if (logMask == Syslog.atOrAbove(Syslog.WARNING)) {
0893: return "WARNING";
0894: } else if (logMask == Syslog.atOrAbove(Syslog.ERROR)) {
0895: return "ERROR";
0896: } else if (logMask == Syslog.atOrAbove(Syslog.FATAL)) {
0897: return "FATAL";
0898: }
0899:
0900: // bah... list of levels to pay attention to.
0901: Vector list = new Vector(5);
0902: if (inMask(Syslog.DEBUG, logMask)) {
0903: list.addElement("=DEBUG");
0904: }
0905: if (inMask(Syslog.INFO, logMask)) {
0906: list.addElement("=INFO");
0907: }
0908: if (inMask(Syslog.WARNING, logMask)) {
0909: list.addElement("=WARNING");
0910: }
0911: if (inMask(Syslog.ERROR, logMask)) {
0912: list.addElement("=ERROR");
0913: }
0914: if (inMask(Syslog.FATAL, logMask)) {
0915: list.addElement("=FATAL");
0916: }
0917: StringBuffer b = new StringBuffer(32);
0918: Enumeration e = list.elements();
0919: while (e.hasMoreElements()) {
0920: b.append(e.nextElement());
0921: if (e.hasMoreElements()) {
0922: b.append(",");
0923: }
0924: }
0925: return b.toString();
0926: }
0927:
0928: /**
0929: * Check if the given level is covered by the given mask.
0930: *
0931: *@param level Log message severity
0932: *@param mask Log mask to compare it to
0933: *@return true if the given level is "in" the mask.
0934: */
0935: public final static boolean inMask(int level, int mask) {
0936: return ((level & mask) > 0);
0937: }
0938:
0939: /**
0940: * Get the default mask for logging of messages.
0941: *
0942: *@return The logMask value
0943: */
0944: public final static int getLogMask() {
0945: return currentLogMask;
0946: }
0947:
0948: /**
0949: *@param level The minimum severity of messages
0950: *@return the log mask for "all logs at or above this level"
0951: */
0952: public final static int atOrAbove(int level) {
0953: if (level == DEBUG) {
0954: return DEBUG | INFO | WARNING | ERROR | FATAL;
0955: }
0956: if (level == INFO) {
0957: return INFO | WARNING | ERROR | FATAL;
0958: }
0959: if (level == WARNING) {
0960: return WARNING | ERROR | FATAL;
0961: }
0962: if (level == ERROR) {
0963: return ERROR | FATAL;
0964: }
0965: if (level == FATAL) {
0966: return FATAL;
0967: }
0968: throw new IllegalArgumentException(
0969: MessageFormat
0970: .format(
0971: getResourceString(MessageConstants.ILLEGAL_ARGUMENT_MESSAGE),
0972: new Object[] { String.valueOf(level) }));
0973: }
0974:
0975: /**
0976: * Log a message. Logs to the <tt>DEFAULT_CHANNEL</tt> channel.
0977: *
0978: *@param host The machine the log entry originated on.
0979: *@param logger The object which is perfoming the log. It's class name
0980: * will be extracted and added to the log.
0981: *@param msg A short message describing the log entry.
0982: *@param detail A longer message with more information (can be null).
0983: *@param level The level of the log entry.
0984: */
0985: public final static void log(InetAddress host, Object logger,
0986: Object msg, Object detail, int level) {
0987: log(host, logger, null, msg, detail, level, Thread
0988: .currentThread(), Thread.currentThread().getName(),
0989: System.currentTimeMillis(), 1);
0990: }
0991:
0992: /**
0993: * Log a message. Logs to the <tt>DEFAULT_CHANNEL</tt> channel.
0994: *
0995: *@param logger The object which is perfoming the log. It's class name
0996: * will be extracted and added to the log.
0997: *@param msg A short message describing the log entry.
0998: *@param detail A longer message with more information (can be null).
0999: *@param level The level of the log entry.
1000: */
1001: public final static void log(Object logger, Object msg,
1002: Object detail, int level) {
1003: log(localHost, logger, null, msg, detail, level, Thread
1004: .currentThread(), Thread.currentThread().getName(),
1005: System.currentTimeMillis(), 1);
1006: }
1007:
1008: /**
1009: * Log a message. If <tt>detail</tt> is a subclass of <tt>Throwable</tt>
1010: * it's stack trace will be included in the output. If you want to log to a
1011: * channel other than <tt>DEFAULT_CHANNEL</tt> you will have to use this
1012: * method or one of the <tt><i>xxx</i> ToChannel(...)</tt> methods.
1013: *
1014: *@param logger The object which is perfoming the log. It's class name
1015: * will be extracted and added to the log.
1016: *@param channel The log channel to write to.
1017: *@param msg A short message describing the log entry.
1018: *@param detail A longer message with more information (can be null).
1019: *@param level The level of the log entry.
1020: */
1021: public final static void log(Object logger, Object channel,
1022: Object msg, Object detail, int level) {
1023: log(localHost, logger, channel, msg, detail, level, Thread
1024: .currentThread(), Thread.currentThread().getName(),
1025: System.currentTimeMillis(), 1);
1026: }
1027:
1028: /**
1029: * Log a message. If <tt>detail</tt> is a subclass of <tt>Throwable</tt>
1030: * it's stack trace will be included in the output. If you want to log to a
1031: * channel other than <tt>DEFAULT_CHANNEL</tt> you will have to use this
1032: * method or one of the <tt><i>xxx</i> ToChannel(...)</tt> methods.
1033: *
1034: *@param host The host the log message originated on.
1035: *@param logger The object which is perfoming the log. It's class name
1036: * will be extracted and added to the log.
1037: *@param channel The log channel to write to.
1038: *@param msg A short message describing the log entry.
1039: *@param detail A longer message with more information (can be null).
1040: *@param level The level of the log entry.
1041: */
1042: public final static void log(InetAddress host, Object logger,
1043: Object channel, Object msg, Object detail, int level) {
1044: log(host, logger, channel, msg, detail, level, Thread
1045: .currentThread(), Thread.currentThread().getName(),
1046: System.currentTimeMillis(), 1);
1047: }
1048:
1049: final static String[] convertChannelObject(Object channel) {
1050: if (channel == null) {
1051: return defaultChannelList;
1052: }
1053:
1054: if (channel instanceof String) {
1055: return new String[] { (String) channel };
1056: } else if (channel instanceof String[]) {
1057: return (String[]) channel;
1058: } else if (channel instanceof Object[]) {
1059: Object array[] = (Object[]) channel;
1060: String channels[] = new String[array.length];
1061: for (int i = 0; i < array.length; i++) {
1062: channels[i] = array[i].toString();
1063: }
1064: return channels;
1065: }
1066:
1067: return new String[] { channel.toString() };
1068: }
1069:
1070: /**
1071: * Log a message. <I>This method should not be called unless it's by a
1072: * remote log adapter.</I>
1073: *
1074: *@param host The host the log message originated on.
1075: *@param logger The object which is perfoming the log. It's class
1076: * name will be extracted and added to the log.
1077: *@param msg A short message describing the log entry.
1078: *@param detail A longer message with more information (can be
1079: * null).
1080: *@param level The level of the log entry.
1081: *@param thread The thread making the log call (null if remote)
1082: *@param threadName The name of the thread making the log call.
1083: *@param messageSendTime The time the message was sent.
1084: *@param incomingChannel Message channel
1085: */
1086: public final static void log(InetAddress host, Object logger,
1087: Object incomingChannel, Object msg, Object detail,
1088: int level, Thread thread, String threadName,
1089: long messageSendTime) {
1090: log(host, logger, incomingChannel, msg, detail, level, thread,
1091: threadName, messageSendTime, 1);
1092: }
1093:
1094: /**
1095: * Log a message. <I>This method should not be called unless it's by a
1096: * remote log adapter.</I>
1097: *
1098: *@param host The host the log message originated on.
1099: *@param logger The object which is perfoming the log. It's class
1100: * name will be extracted and added to the log.
1101: *@param msg A short message describing the log entry.
1102: *@param detail A longer message with more information (can be
1103: * null).
1104: *@param level The level of the log entry.
1105: *@param thread The thread making the log call (null if remote)
1106: *@param threadName The name of the thread making the log call.
1107: *@param messageSendTime The time the message was sent.
1108: *@param incomingChannel Channel
1109: *@param traceDepth Caller's depth in call stack, for computing
1110: * caller and method names at runtime.
1111: */
1112: public final static void log(InetAddress host, Object logger,
1113: Object incomingChannel, Object msg, Object detail,
1114: int level, Thread thread, String threadName,
1115: long messageSendTime, int traceDepth) {
1116: if (!masterSwitch) {
1117: return;
1118: }
1119:
1120: String methodName = null;
1121: int lineNumber = StackTraceInfo.LINE_NUMBER_UNKNOWN;
1122: traceDepth++;
1123:
1124: Class loggerClass = (logger == null) ? null : logger.getClass();
1125:
1126: // get logger name
1127: String classname = null;
1128: if (!alwaysComputeCaller && !computeCaller) {
1129: if (logger == null) {
1130: classname = Q_MARK;
1131: } else {
1132: if (loggerClass == Class.class) {
1133: classname = ((Class) logger).getName();
1134: } else if (loggerClass == String.class) {
1135: classname = (String) logger;
1136: } else {
1137: classname = logger.getClass().getName();
1138: }
1139: }
1140: }
1141:
1142: // determine what channel(s) we should
1143: // send this log message to
1144: String channels[] = null;
1145: if (incomingChannel != null) { // specified channel in the call to log(...)
1146:
1147: channels = convertChannelObject(incomingChannel);
1148: } else { // no channel(s) specified
1149:
1150: // check if the logger is channel aware. If so,
1151: // ask it what channels it prefers.
1152: if (loggerClass == SyslogChannelAware.class) {
1153: channels = convertChannelObject(((SyslogChannelAware) logger)
1154: .getSyslogChannel());
1155: } else {
1156: channels = defaultChannelList;
1157: }
1158: }
1159:
1160: // then log to all objects in loggers
1161: int loggerIndex = 0;
1162: int channelIndex = channels.length;
1163: Syslogger[] localLoggerArray = loggerArray;
1164: int size = localLoggerArray.length;
1165: Syslogger log = null;
1166: SyslogMessage sm = null;
1167:
1168: for (; --channelIndex >= 0;) {
1169: // outer loop is through the channel array
1170: sm = new SyslogMessage(host, messageSendTime,
1171: channels[channelIndex], logger, classname, msg,
1172: detail, level, thread, threadName, methodName,
1173: lineNumber);
1174: for (loggerIndex = size; --loggerIndex >= 0;) {
1175: // inner loop is through the loggers
1176: log = localLoggerArray[loggerIndex];
1177: try {
1178: // should we compute the calling method
1179: if (alwaysComputeCaller
1180: && (sm.callingMethodName == null)) {
1181: StackTraceInfo info = StackTraceUtil
1182: .whereAmI(traceDepth);
1183: if (info != null) {
1184: sm.loggerClassname = info.className;
1185: sm.callingMethodName = info.methodName;
1186: sm.callingMethodLineNumber = info.lineNumber;
1187: }
1188: }
1189:
1190: if (log.getPolicy().shouldLog(sm)) {
1191: // should we compute the calling method
1192: if (computeCaller
1193: && (sm.callingMethodName == null)) {
1194: StackTraceInfo info = StackTraceUtil
1195: .whereAmI(traceDepth);
1196: if (info != null) {
1197: sm.loggerClassname = info.className;
1198: sm.callingMethodName = info.methodName;
1199: sm.callingMethodLineNumber = info.lineNumber;
1200: }
1201: }
1202:
1203: log.log(sm);
1204: }
1205: } catch (Throwable t) {
1206: System.err
1207: .println(MessageFormat
1208: .format(
1209: getResourceString(MessageConstants.WRITE_PROBLEM),
1210: new Object[] {
1211: ((log.getName() == null) ? log
1212: .toString()
1213: : log
1214: .getName()),
1215: t.toString() }));
1216: t.printStackTrace();
1217: }
1218: }
1219: }
1220: }
1221:
1222: /**
1223: * Logs an exception for the given object. The log level will be ERROR.
1224: *
1225: *@param host hostname
1226: *@param logger Calling object
1227: *@param e exception to log
1228: */
1229: public final static void log(InetAddress host, Object logger,
1230: Throwable e) {
1231: log(host, logger, null, e.toString(), e, ERROR, Thread
1232: .currentThread(), Thread.currentThread().getName(),
1233: System.currentTimeMillis(), 1);
1234: }
1235:
1236: /**
1237: * Logs an exception for the given object at a given level.
1238: *
1239: *@param host hostname
1240: *@param logger Calling object
1241: *@param e exception to log
1242: *@param level Severity to log the message at
1243: */
1244: public final static void log(InetAddress host, Object logger,
1245: Throwable e, int level) {
1246: log(host, logger, null, e.toString(), e, level, Thread
1247: .currentThread(), Thread.currentThread().getName(),
1248: System.currentTimeMillis(), 1);
1249: }
1250:
1251: /**
1252: * Logs an exception for the given object. The log level will be ERROR.
1253: *
1254: *@param logger Calling object
1255: *@param e Exception to log
1256: */
1257: public final static void log(Object logger, Throwable e) {
1258: log(localHost, logger, null, e.toString(), e, ERROR, Thread
1259: .currentThread(), Thread.currentThread().getName(),
1260: System.currentTimeMillis(), 1);
1261: }
1262:
1263: /**
1264: * Logs an exception for the given object at a given level.
1265: *
1266: *@param logger Calling object
1267: *@param e Exception to log
1268: *@param level Severity to log the message at
1269: */
1270: public final static void log(Object logger, Throwable e, int level) {
1271: log(localHost, logger, null, e.toString(), e, level, Thread
1272: .currentThread(), Thread.currentThread().getName(),
1273: System.currentTimeMillis(), 1);
1274: }
1275:
1276: /**
1277: * Logs a debug message, which will be converted through toString().
1278: *
1279: *@param host hostname
1280: *@param logger Calling object
1281: *@param message Message to log
1282: */
1283: public final static void debug(InetAddress host, Object logger,
1284: Object message) {
1285: log(host, logger, null, message, null, DEBUG);
1286: log(host, logger, null, message, null, DEBUG, Thread
1287: .currentThread(), Thread.currentThread().getName(),
1288: System.currentTimeMillis(), 1);
1289: }
1290:
1291: /**
1292: * Logs a debug message with a detail object, both of which will be
1293: * converted through toString().
1294: *
1295: *@param host hostname
1296: *@param logger Calling object
1297: *@param message Message to log
1298: *@param detail Extended message or exception
1299: */
1300: public final static void debug(InetAddress host, Object logger,
1301: Object message, Object detail) {
1302: log(host, logger, null, message, detail, DEBUG, Thread
1303: .currentThread(), Thread.currentThread().getName(),
1304: System.currentTimeMillis(), 1);
1305: }
1306:
1307: /**
1308: * Logs a debug message to the given channel.
1309: *
1310: *@param host hostname
1311: *@param logger Calling object
1312: *@param message Message to log
1313: */
1314: public final static void debugToChannel(InetAddress host,
1315: Object logger, Object channel, Object message) {
1316: log(host, logger, channel, message, null, DEBUG, Thread
1317: .currentThread(), Thread.currentThread().getName(),
1318: System.currentTimeMillis(), 1);
1319: }
1320:
1321: /**
1322: * Logs a debug message with a detail object to the given channel.
1323: *
1324: *@param host hostname
1325: *@param logger Calling object
1326: *@param channel Channel to log message on
1327: *@param message Message to log
1328: *@param detail Extended message or exception
1329: */
1330: public final static void debugToChannel(InetAddress host,
1331: Object logger, Object channel, Object message, Object detail) {
1332: log(host, logger, channel, message, detail, DEBUG, Thread
1333: .currentThread(), Thread.currentThread().getName(),
1334: System.currentTimeMillis(), 1);
1335: }
1336:
1337: /**
1338: * Logs a debug message, which will be converted through toString().
1339: *
1340: *@param logger Calling object
1341: *@param message Message to log
1342: */
1343: public final static void debug(Object logger, Object message) {
1344: log(localHost, logger, null, message, null, DEBUG, Thread
1345: .currentThread(), Thread.currentThread().getName(),
1346: System.currentTimeMillis(), 1);
1347: }
1348:
1349: /**
1350: * Logs a debug message with a detail object, both of which will be
1351: * converted through toString().
1352: *
1353: *@param logger Calling object
1354: *@param message Message to log
1355: *@param detail Extended message or exception
1356: */
1357: public final static void debug(Object logger, Object message,
1358: Object detail) {
1359: log(localHost, logger, null, message, detail, DEBUG, Thread
1360: .currentThread(), Thread.currentThread().getName(),
1361: System.currentTimeMillis(), 1);
1362: }
1363:
1364: /**
1365: * Logs a debug message to the given channel.
1366: *
1367: *@param logger Calling object
1368: *@param message Message to log
1369: *@param channel Channel to log message on
1370: */
1371: public final static void debugToChannel(Object logger,
1372: Object channel, Object message) {
1373: log(localHost, logger, channel, message, null, DEBUG, Thread
1374: .currentThread(), Thread.currentThread().getName(),
1375: System.currentTimeMillis(), 1);
1376: }
1377:
1378: /**
1379: * Logs a debug message with a detail object to the given channel.
1380: *
1381: *@param logger Calling object
1382: *@param channel Channel to log message on
1383: *@param message Message to log
1384: *@param detail Extended message or exception
1385: */
1386: public final static void debugToChannel(Object logger,
1387: Object channel, Object message, Object detail) {
1388: log(localHost, logger, channel, message, detail, DEBUG, Thread
1389: .currentThread(), Thread.currentThread().getName(),
1390: System.currentTimeMillis(), 1);
1391: }
1392:
1393: /**
1394: * Logs a info message, which will be converted through toString().
1395: *
1396: *@param host Hostname
1397: *@param logger Calling object
1398: *@param message Message to log
1399: */
1400: public final static void info(InetAddress host, Object logger,
1401: Object message) {
1402: log(host, logger, null, message, null, INFO, Thread
1403: .currentThread(), Thread.currentThread().getName(),
1404: System.currentTimeMillis(), 1);
1405: }
1406:
1407: /**
1408: * Logs a info message with a detail object, both of which will be
1409: * converted through toString().
1410: *
1411: *@param host Hostname
1412: *@param logger Calling object
1413: *@param message Message to log
1414: *@param detail Extended message or exception
1415: */
1416: public final static void info(InetAddress host, Object logger,
1417: Object message, Object detail) {
1418: log(host, logger, null, message, detail, INFO, Thread
1419: .currentThread(), Thread.currentThread().getName(),
1420: System.currentTimeMillis(), 1);
1421: }
1422:
1423: /**
1424: * Logs an info message to the given channel.
1425: *
1426: *@param host Hostname
1427: *@param logger Calling object
1428: *@param channel Channel to log message on
1429: *@param message Message to log
1430: */
1431: public final static void infoToChannel(InetAddress host,
1432: Object logger, Object channel, Object message) {
1433: log(host, logger, channel, message, null, INFO, Thread
1434: .currentThread(), Thread.currentThread().getName(),
1435: System.currentTimeMillis(), 1);
1436: }
1437:
1438: /**
1439: * Logs an info message with a detail object to the given channel.
1440: *
1441: *@param host Hostname
1442: *@param logger Calling object
1443: *@param channel Channel to log message on
1444: *@param message Message to log
1445: *@param detail Extended message or exception
1446: */
1447: public final static void infoToChannel(InetAddress host,
1448: Object logger, Object channel, Object message, Object detail) {
1449: log(host, logger, channel, message, detail, INFO, Thread
1450: .currentThread(), Thread.currentThread().getName(),
1451: System.currentTimeMillis(), 1);
1452: }
1453:
1454: /**
1455: * Logs a info message, which will be converted through toString().
1456: *
1457: *@param logger Calling object
1458: *@param message Message to log
1459: */
1460: public final static void info(Object logger, Object message) {
1461: log(localHost, logger, null, message, null, INFO, Thread
1462: .currentThread(), Thread.currentThread().getName(),
1463: System.currentTimeMillis(), 1);
1464: }
1465:
1466: /**
1467: * Logs a info message with a detail object, both of which will be
1468: * converted through toString().
1469: *
1470: *@param logger Calling object
1471: *@param message Message to log
1472: *@param detail Extended message or exception
1473: */
1474: public final static void info(Object logger, Object message,
1475: Object detail) {
1476: log(localHost, logger, null, message, detail, INFO, Thread
1477: .currentThread(), Thread.currentThread().getName(),
1478: System.currentTimeMillis(), 1);
1479: }
1480:
1481: /**
1482: * Logs an info message to the given channel.
1483: *
1484: *@param logger Calling object
1485: *@param channel Channel to log message on
1486: *@param message Message to log
1487: */
1488: public final static void infoToChannel(Object logger,
1489: Object channel, Object message) {
1490: log(localHost, logger, channel, message, null, INFO, Thread
1491: .currentThread(), Thread.currentThread().getName(),
1492: System.currentTimeMillis(), 1);
1493: }
1494:
1495: /**
1496: * Logs an info message with a detail object to the given channel.
1497: *
1498: *@param logger Calling object
1499: *@param channel Channel to log message on
1500: *@param message Message to log
1501: *@param detail Extended message or exception
1502: */
1503: public final static void infoToChannel(Object logger,
1504: Object channel, Object message, Object detail) {
1505: log(localHost, logger, channel, message, detail, INFO, Thread
1506: .currentThread(), Thread.currentThread().getName(),
1507: System.currentTimeMillis(), 1);
1508: }
1509:
1510: /**
1511: * Logs a warning message, which will be converted through toString().
1512: *
1513: *@param host Hostname
1514: *@param logger Calling object
1515: *@param message Message to log
1516: */
1517: public final static void warning(InetAddress host, Object logger,
1518: Object message) {
1519: log(host, logger, null, message, null, WARNING, Thread
1520: .currentThread(), Thread.currentThread().getName(),
1521: System.currentTimeMillis(), 1);
1522: }
1523:
1524: /**
1525: * Logs a warning message with a detail object, both of which will be
1526: * converted through toString().
1527: *
1528: *@param host Hostname
1529: *@param logger Calling object
1530: *@param message Message to log
1531: *@param detail Extended message or exception
1532: */
1533: public final static void warning(InetAddress host, Object logger,
1534: Object message, Object detail) {
1535: log(host, logger, null, message, detail, WARNING, Thread
1536: .currentThread(), Thread.currentThread().getName(),
1537: System.currentTimeMillis(), 1);
1538: }
1539:
1540: /**
1541: * Logs a warning message to the given channel.
1542: *
1543: *@param host Hostname
1544: *@param logger Calling object
1545: *@param channel Channel to log message on
1546: *@param message Message to log
1547: */
1548: public final static void warningToChannel(InetAddress host,
1549: Object logger, Object channel, Object message) {
1550: log(host, logger, channel, message, null, WARNING, Thread
1551: .currentThread(), Thread.currentThread().getName(),
1552: System.currentTimeMillis(), 1);
1553: }
1554:
1555: /**
1556: * Logs a warning message with a detail object to the given channel.
1557: *
1558: *@param host Hostname
1559: *@param logger Calling object
1560: *@param channel Channel to log message on
1561: *@param message Message to log
1562: *@param detail Extended message or exception
1563: */
1564: public final static void warningToChannel(InetAddress host,
1565: Object logger, Object channel, Object message, Object detail) {
1566: log(host, logger, channel, message, detail, WARNING, Thread
1567: .currentThread(), Thread.currentThread().getName(),
1568: System.currentTimeMillis(), 1);
1569: }
1570:
1571: /**
1572: * Logs a warning message, which will be converted through toString().
1573: *
1574: *@param logger Calling object
1575: *@param message Message to log
1576: */
1577: public final static void warning(Object logger, Object message) {
1578: log(localHost, logger, null, message, null, WARNING, Thread
1579: .currentThread(), Thread.currentThread().getName(),
1580: System.currentTimeMillis(), 1);
1581: }
1582:
1583: /**
1584: * Logs a warning message with a detail object, both of which will be
1585: * converted through toString().
1586: *
1587: *@param logger Calling object
1588: *@param message Message to log
1589: *@param detail Extended message or exception
1590: */
1591: public final static void warning(Object logger, Object message,
1592: Object detail) {
1593: log(localHost, logger, null, message, detail, WARNING, Thread
1594: .currentThread(), Thread.currentThread().getName(),
1595: System.currentTimeMillis(), 1);
1596: }
1597:
1598: /**
1599: * Logs a warning message to the given channel.
1600: *
1601: *@param logger Calling object
1602: *@param channel Channel to log message on
1603: *@param message Message to log
1604: */
1605: public final static void warningToChannel(Object logger,
1606: Object channel, Object message) {
1607: log(localHost, logger, channel, message, null, WARNING, Thread
1608: .currentThread(), Thread.currentThread().getName(),
1609: System.currentTimeMillis(), 1);
1610: }
1611:
1612: /**
1613: * Logs a warning message with a detail object to the given channel.
1614: *
1615: *@param logger Calling object
1616: *@param channel Channel to log message on
1617: *@param message Message to log
1618: *@param detail Extended message or exception
1619: */
1620: public final static void warningToChannel(Object logger,
1621: Object channel, Object message, Object detail) {
1622: log(localHost, logger, channel, message, detail, WARNING,
1623: Thread.currentThread(), Thread.currentThread()
1624: .getName(), System.currentTimeMillis(), 1);
1625: }
1626:
1627: /**
1628: * Logs a error message, which will be converted through toString().
1629: *
1630: *@param host Hostname
1631: *@param logger Calling object
1632: *@param message Message to log
1633: */
1634: public final static void error(InetAddress host, Object logger,
1635: Object message) {
1636: log(host, logger, null, message, null, ERROR, Thread
1637: .currentThread(), Thread.currentThread().getName(),
1638: System.currentTimeMillis(), 1);
1639: }
1640:
1641: /**
1642: * Logs a error message with a detail object, both of which will be
1643: * converted through toString().
1644: *
1645: *@param host Hostname
1646: *@param logger Calling object
1647: *@param message Message to log
1648: *@param detail Extended message or exception
1649: */
1650: public final static void error(InetAddress host, Object logger,
1651: Object message, Object detail) {
1652: log(host, logger, null, message, detail, ERROR, Thread
1653: .currentThread(), Thread.currentThread().getName(),
1654: System.currentTimeMillis(), 1);
1655: }
1656:
1657: /**
1658: * Logs an error message to the given channel.
1659: *
1660: *@param host Hostname
1661: *@param logger Calling object
1662: *@param channel Channel to log message on
1663: *@param message Message to log
1664: */
1665: public final static void errorToChannel(InetAddress host,
1666: Object logger, Object channel, Object message) {
1667: log(host, logger, channel, message, null, ERROR, Thread
1668: .currentThread(), Thread.currentThread().getName(),
1669: System.currentTimeMillis(), 1);
1670: }
1671:
1672: /**
1673: * Logs an error message with a detail object to the given channel.
1674: *
1675: *@param host Hostname
1676: *@param logger Calling object
1677: *@param channel Channel to log message on
1678: *@param message Message to log
1679: *@param detail Extended message or exception
1680: */
1681: public final static void errorToChannel(InetAddress host,
1682: Object logger, Object channel, Object message, Object detail) {
1683: log(host, logger, channel, message, detail, ERROR, Thread
1684: .currentThread(), Thread.currentThread().getName(),
1685: System.currentTimeMillis(), 1);
1686: }
1687:
1688: /**
1689: * Logs a error message, which will be converted through toString().
1690: *
1691: *@param logger Calling object
1692: *@param message Message to log
1693: */
1694: public final static void error(Object logger, Object message) {
1695: log(localHost, logger, null, message, null, ERROR, Thread
1696: .currentThread(), Thread.currentThread().getName(),
1697: System.currentTimeMillis(), 1);
1698: }
1699:
1700: /**
1701: * Logs a error message with a detail object, both of which will be
1702: * converted through toString().
1703: *
1704: *@param logger Calling object
1705: *@param message Message to log
1706: *@param detail Extended message or exception
1707: */
1708: public final static void error(Object logger, Object message,
1709: Object detail) {
1710: log(localHost, logger, null, message, detail, ERROR, Thread
1711: .currentThread(), Thread.currentThread().getName(),
1712: System.currentTimeMillis(), 1);
1713: }
1714:
1715: /**
1716: * Logs an error message to the given channel.
1717: *
1718: *@param logger Calling object
1719: *@param channel Channel to log message on
1720: *@param message Message to log
1721: */
1722: public final static void errorToChannel(Object logger,
1723: Object channel, Object message) {
1724: log(localHost, logger, channel, message, null, ERROR, Thread
1725: .currentThread(), Thread.currentThread().getName(),
1726: System.currentTimeMillis(), 1);
1727: }
1728:
1729: /**
1730: * Logs an error message with a detail object to the given channel.
1731: *
1732: *@param logger Calling object
1733: *@param channel Channel to log message on
1734: *@param message Message to log
1735: *@param detail Extended message or exception
1736: */
1737: public final static void errorToChannel(Object logger,
1738: Object channel, Object message, Object detail) {
1739: log(localHost, logger, channel, message, detail, ERROR, Thread
1740: .currentThread(), Thread.currentThread().getName(),
1741: System.currentTimeMillis(), 1);
1742: }
1743:
1744: /**
1745: * Logs a fatal message, which will be converted through toString().
1746: *
1747: *@param host Hostname
1748: *@param logger Calling object
1749: *@param message Message to log
1750: */
1751: public final static void fatal(InetAddress host, Object logger,
1752: Object message) {
1753: log(host, logger, null, message, null, FATAL, Thread
1754: .currentThread(), Thread.currentThread().getName(),
1755: System.currentTimeMillis(), 1);
1756: }
1757:
1758: /**
1759: * Logs a fatal message with a detail object, both of which will be
1760: * converted through toString().
1761: *
1762: *@param host Hostname
1763: *@param logger Calling object
1764: *@param message Message to log
1765: *@param detail Extended message or exception
1766: */
1767: public final static void fatal(InetAddress host, Object logger,
1768: Object message, Object detail) {
1769: log(host, logger, null, message, detail, FATAL, Thread
1770: .currentThread(), Thread.currentThread().getName(),
1771: System.currentTimeMillis(), 1);
1772: }
1773:
1774: /**
1775: * Logs a fatal message to the given channel.
1776: *
1777: *@param host Hostname
1778: *@param logger Calling object
1779: *@param channel Channel to log message on
1780: *@param message Message to log
1781: */
1782: public final static void fatalToChannel(InetAddress host,
1783: Object logger, Object channel, Object message) {
1784: log(host, logger, channel, message, null, FATAL, Thread
1785: .currentThread(), Thread.currentThread().getName(),
1786: System.currentTimeMillis(), 1);
1787: }
1788:
1789: /**
1790: * Logs a fatal message with a detail object to the given channel.
1791: *
1792: *@param host Hostname
1793: *@param logger Calling object
1794: *@param channel Channel to log message on
1795: *@param message Message to log
1796: *@param detail Extended message or exception
1797: */
1798: public final static void fatalToChannel(InetAddress host,
1799: Object logger, Object channel, Object message, Object detail) {
1800: log(host, logger, channel, message, detail, FATAL, Thread
1801: .currentThread(), Thread.currentThread().getName(),
1802: System.currentTimeMillis(), 1);
1803: }
1804:
1805: /**
1806: * Logs a fatal message, which will be converted through toString().
1807: *
1808: *@param logger Calling object
1809: *@param message Message to log
1810: */
1811: public final static void fatal(Object logger, Object message) {
1812: log(localHost, logger, null, message, null, FATAL, Thread
1813: .currentThread(), Thread.currentThread().getName(),
1814: System.currentTimeMillis(), 1);
1815: }
1816:
1817: /**
1818: * Logs a fatal message with a detail object, both of which will be
1819: * converted through toString().
1820: *
1821: *@param logger Calling object
1822: *@param message Message to log
1823: *@param detail Extended message or exception
1824: */
1825: public final static void fatal(Object logger, Object message,
1826: Object detail) {
1827: log(localHost, logger, null, message, detail, FATAL, Thread
1828: .currentThread(), Thread.currentThread().getName(),
1829: System.currentTimeMillis(), 1);
1830: }
1831:
1832: /**
1833: * Logs a fatal message to the given channel.
1834: *
1835: *@param logger Calling object
1836: *@param channel Channel to log message on
1837: *@param message Message to log
1838: */
1839: public final static void fatalToChannel(Object logger,
1840: Object channel, Object message) {
1841: log(localHost, logger, channel, message, null, FATAL, Thread
1842: .currentThread(), Thread.currentThread().getName(),
1843: System.currentTimeMillis(), 1);
1844: }
1845:
1846: /**
1847: * Logs a fatal message with a detail object to the given channel.
1848: *
1849: *@param logger Calling object
1850: *@param channel Channel to log message on
1851: *@param message Message to log
1852: *@param detail Extended message or exception
1853: */
1854: public final static void fatalToChannel(Object logger,
1855: Object channel, Object message, Object detail) {
1856: log(localHost, logger, channel, message, detail, FATAL, Thread
1857: .currentThread(), Thread.currentThread().getName(),
1858: System.currentTimeMillis(), 1);
1859: }
1860:
1861: /**
1862: * Logs a breadcrumb at the debug level. The breadcrumb
1863: * includes information from a <tt><a href="../util/StackTraceInfo.html">StackTraceInfo</a></tt>
1864: * object.
1865: */
1866: public final static void crumb() {
1867: StackTraceInfo trace = StackTraceUtil.whereAmI(1);
1868: log(localHost, trace.className, null, MessageFormat.format(
1869: getResourceString(MessageConstants.CRUMB_MESSAGE),
1870: new Object[] { trace }), (Object) null, DEBUG, Thread
1871: .currentThread(), Thread.currentThread().getName(),
1872: System.currentTimeMillis(), 1);
1873: }
1874:
1875: /**
1876: * Logs a breadcrumb at the debug level. The breadcrumb
1877: * includes information from a <tt><a href="../util/StackTraceInfo.html">StackTraceInfo</a></tt>
1878: * object.
1879: */
1880: public final static void crumb(Object logger) {
1881: log(localHost, logger, (Object) null, MessageFormat.format(
1882: getResourceString(MessageConstants.CRUMB_MESSAGE),
1883: new Object[] { Syslog.whereAmI(1) }), (Object) null,
1884: DEBUG, Thread.currentThread(), Thread.currentThread()
1885: .getName(), System.currentTimeMillis(), 1);
1886: }
1887:
1888: /**
1889: * Logs a breadcrumb at the debug level.
1890: */
1891: public final static void crumb(Object logger, Object channel) {
1892: log(localHost, logger, channel, MessageFormat.format(
1893: getResourceString(MessageConstants.CRUMB_MESSAGE),
1894: new Object[] { Syslog.whereAmI(1) }), null, DEBUG,
1895: Thread.currentThread(), Thread.currentThread()
1896: .getName(), System.currentTimeMillis(), 1);
1897: }
1898:
1899: static String whereAmI(int depth) {
1900: StackTraceInfo trace = StackTraceUtil.whereAmI(depth + 1);
1901: return trace.toString();
1902: }
1903:
1904: /**
1905: * Determine if the current default syslog mask would allow the given level
1906: * of message to be logged. This is not an absolute method of determining
1907: * if a message would be logged by some registered logger. If there is a
1908: * registered logger who is not inheriting the mask from <tt>Syslog</tt>
1909: * itself, it may (or may not) have logged the message.
1910: *
1911: *@param level Message severity to test
1912: *@return True if it is likely to be logged
1913: *@deprecated
1914: */
1915: public final static boolean canLog(int level) {
1916: return inMask(level, currentLogMask);
1917: }
1918:
1919: /**
1920: * Determine if the current syslog mask would allow a message at the <tt>
1921: * DEBUG</tt> level to be logged.
1922: *
1923: *@return True if it is likely to be logged
1924: *@deprecated
1925: */
1926: public final static boolean canDebug() {
1927: return canLog(DEBUG);
1928: }
1929:
1930: /**
1931: * Determine if the current syslog mask would allow a message at the <tt>
1932: * INFO</tt> level to be logged.
1933: *
1934: *@return True if it is likely to be logged
1935: *@deprecated
1936: */
1937: public final static boolean canInfo() {
1938: return canLog(INFO);
1939: }
1940:
1941: /**
1942: * Determine if the current syslog mask would allow a message at the <tt>
1943: * WARNING</tt> level to be logged.
1944: *
1945: *@return True if it is likely to be logged
1946: *@deprecated
1947: */
1948: public final static boolean canWarning() {
1949: return canLog(WARNING);
1950: }
1951:
1952: /**
1953: * Determine if the current syslog mask would allow a message at the <tt>
1954: * ERROR</tt> level to be logged.
1955: *
1956: *@return True if it is likely to be logged
1957: *@see #canLog(int)
1958: *@deprecated
1959: */
1960: public final static boolean canError() {
1961: return canLog(ERROR);
1962: }
1963:
1964: /**
1965: * Determine if the current syslog mask would allow a message at the <tt>
1966: * FATAL</tt> level to be logged.
1967: *
1968: *@return True if it is likely to be logged
1969: *@see #canLog(int)
1970: *@deprecated
1971: */
1972: public final static boolean canFatal() {
1973: return canLog(FATAL);
1974: }
1975:
1976: /**
1977: * Determine if it's likely that someone will listen to a message from the
1978: * given logger at the given level.
1979: *
1980: *@param logger Calling object
1981: *@return True if it is likely to be logged
1982: *@see #mightLog(Object, int, Object)
1983: *@deprecated
1984: */
1985: public final static boolean mightLog(Object logger, int level) {
1986: return mightLog(logger, level, null);
1987: }
1988:
1989: /**
1990: * Determine if it's likely that someone will listen to a debug message
1991: * from the given logger.
1992: *
1993: *@param logger Calling object
1994: *@return True if it is likely to be logged
1995: *@see #mightLog(Object, int, Object)
1996: *@deprecated
1997: */
1998: public final static boolean mightDebug(Object logger) {
1999: return mightLog(logger, DEBUG, null);
2000: }
2001:
2002: /**
2003: * Determine if it's likely that someone will listen to an info message
2004: * from the given logger.
2005: *
2006: *@param logger Calling object
2007: *@return True if it is likely to be logged
2008: *@see #mightLog(Object, int, Object)
2009: *@deprecated
2010: */
2011: public final static boolean mightInfo(Object logger) {
2012: return mightLog(logger, INFO, null);
2013: }
2014:
2015: /**
2016: * Determine if it's likely that someone will listen to a warning message
2017: * from the given logger.
2018: *
2019: *@param logger Calling object
2020: *@return True if it is likely to be logged
2021: *@see #mightLog(Object, int, Object)
2022: *@deprecated
2023: */
2024: public final static boolean mightWarning(Object logger) {
2025: return mightLog(logger, WARNING, null);
2026: }
2027:
2028: /**
2029: * Determine if it's likely that someone will listen to an error message
2030: * from the given logger.
2031: *
2032: *@param logger Calling object
2033: *@return True if it is likely to be logged
2034: *@see #mightLog(Object, int, Object)
2035: *@deprecated
2036: */
2037: public final static boolean mightError(Object logger) {
2038: return mightLog(logger, ERROR, null);
2039: }
2040:
2041: /**
2042: * Determine if it's likely that someone will listen to a fatal message
2043: * from the given logger.
2044: *
2045: *@param logger Calling object
2046: *@return True if it is likely to be logged
2047: *@see #mightLog(Object, int, Object)
2048: *@deprecated
2049: */
2050: public final static boolean mightFatal(Object logger) {
2051: return mightLog(logger, FATAL, null);
2052: }
2053:
2054: /**
2055: * Determine if it's likely that someone will listen to a debug message
2056: * from the given logger on the given channel(s).
2057: *
2058: *@param logger Calling object
2059: *@param channel Channel name or list
2060: *@return True if it is likely to be logged
2061: *@see #mightLog(Object, int, Object)
2062: *@deprecated
2063: */
2064: public final static boolean mightDebug(Object logger, Object channel) {
2065: return mightLog(logger, DEBUG, channel);
2066: }
2067:
2068: /**
2069: * Determine if it's likely that someone will listen to an info message
2070: * from the given logger on the given channel(s).
2071: *
2072: *@param logger Calling object
2073: *@param channel Channel name or list
2074: *@return True if it is likely to be logged
2075: *@see #mightLog(Object, int, Object)
2076: *@deprecated
2077: */
2078: public final static boolean mightInfo(Object logger, Object channel) {
2079: return mightLog(logger, INFO, channel);
2080: }
2081:
2082: /**
2083: * Determine if it's likely that someone will listen to a warning message
2084: * from the given logger on the given channel(s).
2085: *
2086: *@param logger Calling object
2087: *@param channel Channel name or list
2088: *@return True if it is likely to be logged
2089: *@see #mightLog(Object, int, Object)
2090: *@deprecated
2091: */
2092: public final static boolean mightWarning(Object logger,
2093: Object channel) {
2094: return mightLog(logger, WARNING, channel);
2095: }
2096:
2097: /**
2098: * Determine if it's likely that someone will listen to an error message
2099: * from the given logger on the given channel(s).
2100: *
2101: *@param logger Calling object
2102: *@param channel Channel name or list
2103: *@return True if it is likely to be logged
2104: *@see #mightLog(Object, int, Object)
2105: *@deprecated
2106: */
2107: public final static boolean mightError(Object logger, Object channel) {
2108: return mightLog(logger, ERROR, channel);
2109: }
2110:
2111: /**
2112: * Determine if it's likely that someone will listen to a fatal message
2113: * from the given logger on the given channel(s).
2114: *
2115: *@param logger Calling object
2116: *@param channel Channel name or list
2117: *@return True if it is likely to be logged
2118: *@see #mightLog(Object, int, Object)
2119: *@deprecated
2120: */
2121: public final static boolean mightFatal(Object logger, Object channel) {
2122: return mightLog(logger, FATAL, channel);
2123: }
2124:
2125: /**
2126: * This method has been deprecated. You should use the
2127: * <tt><a href="../util/Debug.html">com.protomatter.util.Debug</a></tt>
2128: * class instead.
2129: *
2130: *@param logger Calling object
2131: *@param level Message severity
2132: *@param channel Channel to log message on
2133: *@return True if it is likely to be logged
2134: *@deprecated
2135: */
2136: public final static boolean mightLog(Object logger, int level,
2137: Object channel) {
2138: int theLevel = level;
2139: Object theLogger = logger;
2140:
2141: // determine channel list.
2142: if (channel == null) {
2143: if (logger instanceof SyslogChannelAware) {
2144: channel = ((SyslogChannelAware) logger)
2145: .getSyslogChannel();
2146: } else {
2147: channel = new Object[] { DEFAULT_CHANNEL };
2148: }
2149: }
2150:
2151: // make up a nice list of channels.
2152: String[] list = null;
2153: if (channel instanceof String) {
2154: list = new String[] { (String) channel };
2155: } else if (channel instanceof String[]) {
2156: list = (String[]) channel;
2157: }
2158:
2159: // ask each logger if they care.
2160: int i = loggers.size();
2161: int j = 0;
2162: Syslogger l = null;
2163: for (; --i >= 0;) {
2164: l = (Syslogger) loggers.get(i);
2165: for (j = list.length; --j >= 0;) {
2166: if (l.mightLog(theLogger, level, list[j])) {
2167: return true;
2168: } // somebody cares
2169: }
2170: }
2171:
2172: // nobody wants it.
2173: return false;
2174: }
2175:
2176: /**
2177: * Pass-through to <TT>mightLog(Object logger, int level)</TT> .
2178: *
2179: *@param logger Calling object
2180: *@param level Message severity
2181: *@return True if it is likely to be logged
2182: *@see #mightLog(Object, int)
2183: *@deprecated
2184: */
2185: public final static boolean canLog(Object logger, int level) {
2186: return mightLog(logger, level);
2187: }
2188:
2189: /**
2190: * Pass-through to <TT>mightDebug(Object logger)</TT> .
2191: *
2192: *@param logger Calling object
2193: *@return True if it is likely to be logged
2194: *@deprecated
2195: *@see #mightDebug(Object)
2196: */
2197: public final static boolean canDebug(Object logger) {
2198: return canLog(logger, DEBUG);
2199: }
2200:
2201: /**
2202: * Pass-through to <TT>mightInfo(Object logger)</TT> .
2203: *
2204: *@param logger Calling object
2205: *@return True if it is likely to be logged
2206: *@deprecated
2207: *@see #mightInfo(Object)
2208: */
2209: public final static boolean canInfo(Object logger) {
2210: return canLog(logger, INFO);
2211: }
2212:
2213: /**
2214: * Pass-through to <TT>mightWarning(Object logger)</TT> .
2215: *
2216: *@param logger Calling object
2217: *@return True if it is likely to be logged
2218: *@deprecated
2219: *@see #mightWarning(Object)
2220: */
2221: public final static boolean canWarning(Object logger) {
2222: return canLog(logger, WARNING);
2223: }
2224:
2225: /**
2226: * Pass-through to <TT>mightError(Object logger)</TT> .
2227: *
2228: *@param logger Calling object
2229: *@return True if it is likely to be logged
2230: *@deprecated
2231: *@see #mightError(Object)
2232: */
2233: public final static boolean canError(Object logger) {
2234: return canLog(logger, ERROR);
2235: }
2236:
2237: /**
2238: * Pass-through to <TT>mightFatal(Object logger)</TT> .
2239: *
2240: *@param logger Calling object
2241: *@return True if it is likely to be logged
2242: *@deprecated
2243: *@see #mightFatal(Object)
2244: */
2245: public final static boolean canFatal(Object logger) {
2246: return canLog(logger, FATAL);
2247: }
2248:
2249: /**
2250: * Flush output to all loggers.
2251: */
2252: public static void flush() {
2253: // run through the loggers and have them each
2254: // flush their output.
2255: Iterator i = Syslog.getLoggers();
2256: while (i.hasNext()) {
2257: Syslogger logger = (Syslogger) i.next();
2258: try {
2259: logger.flush();
2260: } catch (Throwable t) {
2261: System.err
2262: .println(MessageFormat
2263: .format(
2264: getResourceString(MessageConstants.FLUSH_PROBLEM_MESSAGE),
2265: new Object[] {
2266: logger.getName(),
2267: t.toString() }));
2268: t.printStackTrace();
2269: }
2270: }
2271: }
2272:
2273: /**
2274: * Get the resource bundle associated with Syslog.
2275: *
2276: *@return The resources value
2277: */
2278: public final static ResourceBundle getResources() {
2279: return resources;
2280: }
2281:
2282: /**
2283: * Get the value of the given resource name associated with Syslog.
2284: *
2285: *@param name Resource name to get
2286: *@return The resourceString value
2287: */
2288: public final static String getResourceString(String name) {
2289: return getResources().getString(name);
2290: }
2291:
2292: private static class SyslogFlushThread extends Thread {
2293: private long sleepInterval;
2294: private boolean stop = false;
2295:
2296: public SyslogFlushThread(long sleepInterval) {
2297: super (
2298: Syslog
2299: .getResourceString(MessageConstants.FLUSH_THREAD_NAME_MESSAGE));
2300: setDaemon(true);
2301: this .sleepInterval = sleepInterval;
2302: }
2303:
2304: public long getSleepInterval() {
2305: return this .sleepInterval;
2306: }
2307:
2308: public void stopRunning() {
2309: this .stop = true;
2310: }
2311:
2312: public void run() {
2313: while (true && !stop) {
2314: Syslog.flush();
2315: try {
2316: Thread.sleep(sleepInterval);
2317: } catch (InterruptedException x) {
2318: ;
2319: }
2320: }
2321: }
2322: }
2323: }
|