1
0

Migrate the "logging" package from jakarta-commons-sandbox.

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/logging/trunk@138814 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Craig R. McClanahan
2001-12-04 04:28:03 +00:00
parent 85cb60fc43
commit ad40b8fdb4
10 changed files with 1010 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.commons.logging;
/**
* A simple logging interface abstracting logging APIs. In order to be
* instantiated successfully by {@link LogFactory}, classes that implement
* this interface must have a constructor that takes a single String
* parameter representing the "name" of this Log.
*
* @author Rod Waldhoff
* @version $Id: Log.java,v 1.6 2001/12/04 04:28:03 craigmcc Exp $
*/
public interface Log {
public void debug(Object message);
public void debug(Object message, Throwable t);
public void info(Object message);
public void info(Object message, Throwable t);
public void warn(Object message);
public void warn(Object message, Throwable t);
public void error(Object message);
public void error(Object message, Throwable t);
public void fatal(Object message);
public void fatal(Object message, Throwable t);
public boolean isDebugEnabled();
public boolean isInfoEnabled();
public void setLevel(int level);
public int getLevel();
/** All logging level. */
public static final int ALL = Integer.MIN_VALUE;
/** "Debug" level logging. */
public static final int DEBUG = 10000;
/** "Info" level logging. */
public static final int INFO = 20000;
/** "Warn" level logging. */
public static final int WARN = 30000;
/** "Error" level logging. */
public static final int ERROR = 40000;
/** "Fatal" level logging. */
public static final int FATAL = 50000;
/** No logging level. */
public static final int OFF = Integer.MAX_VALUE;
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.commons.logging;
import org.apache.log4j.Category;
import org.apache.log4j.Priority;
/**
* <p>Implementation of {@link Log} that maps directly to a Log4J
* <strong>Category</strong>. Initial configuration of the corresponding
* Category instances should be done in the usual manner, as outlined in
* the Log4J documentation.</p>
*
* @author Rod Waldhoff
* @version $Id: Log4JCategoryLog.java,v 1.6 2001/12/04 04:28:03 craigmcc Exp $
*/
public class Log4JCategoryLog implements Log {
Category _category = null;
public Log4JCategoryLog(String name) {
_category = Category.getInstance(name);
}
public final void debug(Object message) {
_category.debug(message);
}
public final void debug(Object message, Throwable t) {
_category.debug(message,t);
}
public final void info(Object message) {
_category.info(message);
}
public final void info(Object message, Throwable t) {
_category.info(message,t);
}
public final void warn(Object message) {
_category.warn(message);
}
public final void warn(Object message, Throwable t) {
_category.warn(message,t);
}
public final void error(Object message) {
_category.error(message);
}
public final void error(Object message, Throwable t) {
_category.error(message,t);
}
public final void fatal(Object message) {
_category.fatal(message);
}
public final void fatal(Object message, Throwable t) {
_category.fatal(message,t);
}
public final boolean isDebugEnabled() {
return _category.isDebugEnabled();
}
public final boolean isInfoEnabled() {
return _category.isInfoEnabled();
}
public final boolean isEnabledFor(Priority p) {
return _category.isEnabledFor(p);
}
public final void setLevel(int level) {
switch(level) {
case Log.DEBUG:
_category.setPriority(Priority.DEBUG);
break;
case Log.INFO:
_category.setPriority(Priority.INFO);
break;
case Log.WARN:
_category.setPriority(Priority.WARN);
break;
case Log.ERROR:
_category.setPriority(Priority.ERROR);
break;
case Log.FATAL:
_category.setPriority(Priority.FATAL);
break;
default:
_category.setPriority(Priority.toPriority(level));
break;
}
}
public final int getLevel() {
return _category.getPriority().toInt();
}
}

View File

@@ -0,0 +1,175 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.commons.logging;
import java.util.HashMap;
import java.lang.reflect.Constructor;
import java.util.Iterator;
import java.lang.reflect.InvocationTargetException;
/**
* <p>Factory for creating {@link Log} instances. Applications should call
* the <code>makeNewLogInstance()</code> method to instantiate new instances
* of the configured {@link Log} implementation class.</p>
*
* @author Rod Waldhoff
* @version $Id: LogSource.java,v 1.4 2001/12/04 04:28:03 craigmcc Exp $
*/
public class LogSource {
static protected HashMap _logs = new HashMap();
static protected boolean _log4jIsAvailable = false;
static {
try {
if(null != Class.forName("org.apache.log4j.Category")) {
_log4jIsAvailable = true;
} else {
_log4jIsAvailable = false;
}
} catch(ClassNotFoundException e) {
_log4jIsAvailable = false;
} catch(ExceptionInInitializerError e) {
_log4jIsAvailable = false;
} catch(LinkageError e) {
_log4jIsAvailable = false;
}
}
static protected Constructor _logimplctor = null;
static {
try {
setLogImplementation(System.getProperty("org.apache.commons.logging.log","org.apache.commons.logging.NoOpLog"));
} catch(SecurityException e) {
_logimplctor = null;
} catch(LinkageError e) {
_logimplctor = null;
} catch(NoSuchMethodException e) {
_logimplctor = null;
} catch(ClassNotFoundException e) {
_logimplctor = null;
}
}
private LogSource() {
}
/**
* Set the log implementation/log implementation factory
* by the name of the class. The given class
* must implement {@link Log}, and provide a constructor that
* takes a single {@link String} argument (containing the name
* of the log).
*/
static public void setLogImplementation(String classname) throws
LinkageError, ExceptionInInitializerError,
NoSuchMethodException, SecurityException,
ClassNotFoundException {
Class logclass = Class.forName(classname);
Class[] argtypes = new Class[1];
argtypes[0] = "".getClass();
_logimplctor = logclass.getConstructor(argtypes);
}
/**
* Set the log implementation/log implementation factory
* by class. The given class must implement {@link Log},
* and provide a constructor that takes a single {@link String}
* argument (containing the name of the log).
*/
static public void setLogImplementation(Class logclass) throws
LinkageError, ExceptionInInitializerError,
NoSuchMethodException, SecurityException {
Class[] argtypes = new Class[1];
argtypes[0] = "".getClass();
_logimplctor = logclass.getConstructor(argtypes);
}
static public Log getInstance(String name) {
Log log = (Log)(_logs.get(name));
if(null == log) {
log = makeNewLogInstance(name);
_logs.put(name,log);
}
return log;
}
static public Log getInstance(Class clazz) {
return getInstance(clazz.getName());
}
/**
* Create a new {@link Log} implementation, based
* on the given <i>name</i>
* <p>
* The specific {@link Log} implementation returned
* is determined by the value of the
* <tt>org.apache.commons.logging.log</tt> property.
* The value of <tt>org.apache.commons.logging.log</tt> may be set to
* the fully specified name of a class that implements
* the {@link Log} interface. This class must also
* have a public constructor that takes a single
* {@link String} argument (containing the <i>name</i>
* of the {@link Log} to be constructed.
* <p>
* When <tt>httpclient.log</tt> is not set,
* or when no corresponding class can be found,
* this method will return a {@link Log4JCategoryLog}
* if the log4j {@link org.apache.log4j.Category} class is
* available in the {@link LogSource}'s classpath, or
* a {@link NoOpLog} if it is not.
*
* @param name the log name (or category)
*/
static public Log makeNewLogInstance(String name) {
Log log = null;
try {
Object[] args = new Object[1];
args[0] = name;
log = (Log)(_logimplctor.newInstance(args));
} catch (InstantiationException e) {
log = null;
} catch (IllegalAccessException e) {
log = null;
} catch (IllegalArgumentException e) {
log = null;
} catch (InvocationTargetException e) {
log = null;
} catch (NullPointerException e) {
log = null;
}
if(null == log) {
if(_log4jIsAvailable) {
return new Log4JCategoryLog(name);
} else {
log = new NoOpLog(name);
}
}
return log;
}
/**
* Sets the log level for all {@link Log}s known
* to me.
*/
static public void setLevel(int level) {
Iterator it = _logs.entrySet().iterator();
while(it.hasNext()) {
Log log = (Log)(it.next());
log.setLevel(level);
}
}
/**
* Returns a {@link String} array containing the names of
* all logs known to me.
*/
static public String[] getLogNames() {
return (String[])(_logs.keySet().toArray(new String[_logs.size()]));
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.commons.logging;
/**
* <p>Default implementation of Log that throws away all messages. No
* configurable system properties are supported.</p>
*
* @author Rod Waldhoff
* @version $Id: NoOpLog.java,v 1.6 2001/12/04 04:28:03 craigmcc Exp $
*/
public final class NoOpLog implements Log {
public NoOpLog() { }
public NoOpLog(String name) { }
public void debug(Object message) { }
public void debug(Object message, Throwable t) { }
public void info(Object message) { }
public void info(Object message, Throwable t) { }
public void warn(Object message) { }
public void warn(Object message, Throwable t) { }
public void error(Object message) { }
public void error(Object message, Throwable t) { }
public void fatal(Object message) { }
public void fatal(Object message, Throwable t) { }
public final boolean isDebugEnabled() { return false; }
public final boolean isInfoEnabled() { return false; }
public final void setLevel(int level) { }
public final int getLevel() { return Log.OFF; }
}

View File

@@ -0,0 +1,206 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.commons.logging;
import java.util.Properties;
import java.util.Enumeration;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.util.Date;
/**
* <p>Simple implementation of Log that sends all enabled log messages,
* for all defined loggers, to System.out. The following system properties
* are supported to configure the behavior of this logger:</p>
* <ul>
* <li><code>org.apache.commons.logging.simplelog.defaultlog</code> -
* Default logging detail level for all instances of SimpleLog.
* Must be one of ("debug", "info", "warn", "error", or "fatal").
* If not specified, defaults to "error".</li>
* <li><code>org.apache.commons.logging.simplelog.log.xxxxx</code> -
* Logging detail level for a SimpleLog instance named "xxxxx".
* Must be one of ("debug", "info", "warn", "error", or "fatal").
* If not specified, the default logging detail level is used.</li>
* <li><code>org.apache.commons.logging.simplelog.showlogname</code> -
* Set to <code>true</code> if you want the Log instance name to be
* included in output messages.</li>
* <li><code>org.apache.commons.logging.simplelog.showtime</code> -
* Set to <code>true</code> if you want the current date and time
* to be included in output messages.</li>
* </ul>
*
* <p>In addition to looking for system properties with the names specified
* above, this implementation also checks for a class loader resource named
* <code>"simplelog.properties"</code>, and includes any matching definitions
* from this resource (if it exists).</p>
*
* @author Rod Waldhoff
* @version $Id: SimpleLog.java,v 1.6 2001/12/04 04:28:03 craigmcc Exp $
*/
public class SimpleLog implements Log {
static protected final String _prefix =
"org.apache.commons.logging.simplelog.";
static protected final Properties _simplelogProps = new Properties();
static protected boolean _showlogname = false;
static protected boolean _showtime = false;
static protected DateFormat _df = null;
static {
// add all system props that start with the specified prefix
Enumeration enum = System.getProperties().propertyNames();
while(enum.hasMoreElements()) {
String name = (String)(enum.nextElement());
if(null != name && name.startsWith(_prefix)) {
_simplelogProps.setProperty(name,System.getProperty(name));
}
}
// add props from the resource simplelog.properties
InputStream in =
ClassLoader.getSystemResourceAsStream("simplelog.properties");
if(null != in) {
try {
_simplelogProps.load(in);
in.close();
} catch(java.io.IOException e) {
// ignored
}
}
try {
} catch(Throwable t) {
// ignored
}
_showlogname = "true".equalsIgnoreCase(_simplelogProps.getProperty(_prefix + "showlogname","true"));
_showtime = "true".equalsIgnoreCase(_simplelogProps.getProperty(_prefix + "showdate","true"));
if(_showtime) {
_df = new SimpleDateFormat(_simplelogProps.getProperty(_prefix + "dateformat","yyyy/MM/dd HH:mm:ss:SSS zzz"));
}
}
protected static final int DEBUG = 5;
protected static final int INFO = 4;
protected static final int WARN = 3;
protected static final int ERROR = 2;
protected static final int FATAL = 1;
protected int _logLevel = 2;
protected String _name = null;
public SimpleLog(String name) {
_name = name;
String lvl = _simplelogProps.getProperty(_prefix + "log." + _name);
int i = String.valueOf(name).lastIndexOf(".");
while(null == lvl && i > -1) {
name = name.substring(0,i);
lvl = _simplelogProps.getProperty(_prefix + "log." + name);
i = String.valueOf(name).lastIndexOf(".");
}
if(null == lvl) {
lvl = _simplelogProps.getProperty(_prefix + "defaultlog");
}
if("debug".equalsIgnoreCase(lvl)) {
_logLevel = DEBUG;
} else if("info".equalsIgnoreCase(lvl)) {
_logLevel = INFO;
} else if("warn".equalsIgnoreCase(lvl)) {
_logLevel = WARN;
} else if("error".equalsIgnoreCase(lvl)) {
_logLevel = ERROR;
} else if("fatal".equalsIgnoreCase(lvl)) {
_logLevel = FATAL;
}
}
protected void log(int type, Object message, Throwable t) {
if(_logLevel >= type) {
StringBuffer buf = new StringBuffer();
if(_showtime) {
buf.append(_df.format(new Date()));
buf.append(" ");
}
switch(type) {
case DEBUG: buf.append("[DEBUG] "); break;
case INFO: buf.append("[INFO] "); break;
case WARN: buf.append("[WARN] "); break;
case ERROR: buf.append("[ERROR] "); break;
case FATAL: buf.append("[FATAL] "); break;
}
if(_showlogname) {
buf.append(String.valueOf(_name)).append(" - ");
}
buf.append(String.valueOf(message));
if(t != null) {
buf.append(" <");
buf.append(t.toString());
buf.append(">");
t.printStackTrace();
}
System.out.println(buf.toString());
}
}
public final void debug(Object message) {
log(DEBUG,message,null);
}
public final void debug(Object message, Throwable t) {
log(DEBUG,message,t);
}
public final void info(Object message) {
log(INFO,message,null);
}
public final void info(Object message, Throwable t) {
log(INFO,message,t);
}
public final void warn(Object message) {
log(WARN,message,null);
}
public final void warn(Object message, Throwable t) {
log(WARN,message,t);
}
public final void error(Object message) {
log(ERROR,message,null);
}
public final void error(Object message, Throwable t) {
log(ERROR,message,t);
}
public final void fatal(Object message) {
log(FATAL,message,null);
}
public final void fatal(Object message, Throwable t) {
log(FATAL,message,t);
}
public final boolean isDebugEnabled() {
return (_logLevel >= DEBUG);
}
public final boolean isInfoEnabled() {
return (_logLevel >= INFO);
}
public final void setLevel(int level) {
_logLevel = level;
}
public final int getLevel() {
return _logLevel;
}
}

View File

@@ -0,0 +1,123 @@
<body>
<p>Simple wrapper API around multiple logging APIs.</p>
<h3>Overview</h3>
<p>This package provides an API for logging in server-based applications that
can be used around a variety of different logging implementations, including
prebuilt support for the following:</p>
<ul>
<li><a href="http://jakarta.apache.org/log4j/">Log4J</a> from Apache's
Jakarta project. Each named <a href="Log.html">Log</a> instance is
connected to a corresponding Log4J Category.</li>
<!--
<li><a href="http://java.sun.com/j2se/1.4/docs/guide/util/logging/index.html">
JDK Logging API</a>, included in JDK 1.4 or later systems. Each named
<a href="Log.html">Log</a> instance is connected to a corresponding
<code>java.util.logging.Logger</code> instance.</li>
-->
<li><a href="NoOpLog.html">NoOpLog</a> implementation that simply swallows
all log output, for all named <a href="Log.html">Log</a> isntances.</li>
<li><a href="SimpleLog.html">SimpleLog</a> implementation that writes all
log output, for all named <a href="Log.html">Log</a> instances, to
System.out.</li>
</ul>
<h3>Configuring the Logging Package APIs</h3>
<p>The Logging Package APIs are configured based on the values of system
properties, which are normally set on the command line that started your
application. The following system properties are global to all
<a href="Log.html">Log</a> implementations:
<ul>
<li><code>org.apache.commons.logging.log</code> - Fully qualified class name
of the <code>org.apache.commons.logging.Log</code> implementation to be
used.</li>
</ul>
<p>If you do not specify the class name of the Log implementation to use, the
following algorithm is applied:</p>
<ul>
<li>If Log4J is available, return an instance of
<a href="Log4JCategoryLog.html">Log4JCategoryLog</a> that wraps a
Log4J Category instance of the specified name.</li>
<!--
<li>If the JDK 1.4 logging APIs are available, return an instance
of <a href="JdkLogger.html">JdkLogger</a> that wraps an instance of
<code>java.util.logging.Logger</code> for the specified name.</li>
-->
<li>Return an instance of <a href="NoOpLog.html">NoOpLog</a> that
throws away all logged output.</li>
</ul>
<p>Additionally, each individual <a href="Log.html">Log</a> implementation may
support its own configuration properties. These will be documented in the
class descriptions for the corresponding implementation class.</p>
<p>Finally, some <code>Log</code> implementations (such as the one for Log4J)
require an external configuration file for the entire logging environment.
This file should be prepared in a manner that is specific to the actual logging
technology being used.</p>
<h3>Using the Logging Package APIs</h3>
<p>Use of the Logging Package APIs, from the perspective of an application
component, consists of the following steps:</p>
<ol>
<li>Acquire a reference to an instance of
<a href="Log.html">org.apache.commons.logging.Log</a>, by calling the
factory method
<a href="LogSource.html#makeNewLogInstance(java.lang.String)">
LogSource.makeNewLogInstance()</a>. Your application can contain
references to multiple loggers that are used for different
purposes. A typical scenario for a server application is to have each
major component of the server use its own Log instance.</li>
<li>Optionally, you can dynamically change the logging detail level by
calling <a href="Log.html#setLevel(int)">Log.setLevel()</a> with
an appropriate constant from the <code>Log</code> interface. Note that,
in most cases, the underlying logging system configuration will have
been preconfigured by the system administrator.</li>
<li>Cause messages to be logged (if the corresponding detail level is enabled)
by calling appropriate methods (<code>debug()</code>, <code>info()</code>,
<code>warn()</code>, <code>error</code>, and <code>fatal()</code>).</li>
</ol>
<p>For example, you might use the following technique to initialize and
use a <a href="Log.html">Log</a> instance in an application component:</p>
<pre>
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogSource;
public class MyComponent {
protected Log log = LogSource.makeNewInstance("mycomponent");
// Called once at startup time
public void start() {
...
log.info("MyComponent started");
...
}
// Called once at shutdown time
public void stop() {
...
log.info("MyComponent stopped");
...
}
// Called repeatedly to process a particular argument value
// which you want logged if debugging is enabled
public void process(String value) {
...
// Do the string concatenation only if logging is enabled
if (log.isDebugEnabled())
log.debug("MyComponent processing " + value);
...
}
}
</pre>
</body>