<!-- Copyright 2001-2004 The Apache Software Foundation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <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://logging.apache.org/log4j/">Log4J</a> (version 1.2 or later) from Apache's Jakarta project. Each named <a href="Log.html">Log</a> instance is connected to a corresponding Log4J Logger.</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="http://avalon.apache.org/logkit/">LogKit</a> from Apache's Avalon project. Each named <a href="Log.html">Log</a> instance is connected to a corresponding LogKit <code>Logger</code>.</li> <li><a href="impl/NoOpLog.html">NoOpLog</a> implementation that simply swallows all log output, for all named <a href="Log.html">Log</a> instances.</li> <li><a href="impl/SimpleLog.html">SimpleLog</a> implementation that writes all log output, for all named <a href="Log.html">Log</a> instances, to System.err.</li> </ul> <h3>Quick Start Guide</h3> <p>For those impatient to just get on with it, the following example illustrates the typical declaration and use of a logger that is named (by convention) after the calling class: <pre> import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class Foo { private Log log = LogFactory.getLog(Foo.class); public void foo() { ... try { if (log.isDebugEnabled()) { log.debug("About to do something to object " + name); } name.bar(); } catch (IllegalStateException e) { log.error("Something bad happened to " + name, e); } ... } </pre> <p>Unless you configure things differently, all log output will be written to System.err. Therefore, you really will want to review the remainder of this page in order to understand how to configure logging for your application.</p> <h3>Configuring the Commons Logging Package</h3> <h4>Choosing a <code>LogFactory</code> Implementation</h4> <p>From an application perspective, the first requirement is to retrieve an object reference to the <code>LogFactory</code> instance that will be used to create <code><a href="Log.html">Log</a></code> instances for this application. This is normally accomplished by calling the static <code>getFactory()</code> method. This method implements the following discovery algorithm to select the name of the <code>LogFactory</code> implementation class this application wants to use:</p> <ul> <li>Check for a system property named <code>org.apache.commons.logging.LogFactory</code>.</li> <li>Use the JDK 1.3 JAR Services Discovery mechanism (see <a href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html"> http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html</a> for more information) to look for a resource named <code>META-INF/services/org.apache.commons.logging.LogFactory</code> whose first line is assumed to contain the desired class name.</li> <li>Look for a properties file named <code>commons-logging.properties</code> visible in the application class path, with a property named <code>org.apache.commons.logging.LogFactory</code> defining the desired implementation class name.</li> <li>Fall back to a default implementation, which is described further below.</li> </ul> <p>If a <code>commons-logging.properties</code> file is found, all of the properties defined there are also used to set configuration attributes on the instantiated <code>LogFactory</code> instance.</p> <p>Once an implementation class name is selected, the corresponding class is loaded from the current Thread context class loader (if there is one), or from the class loader that loaded the <code>LogFactory</code> class itself otherwise. This allows a copy of <code>commons-logging.jar</code> to be shared in a multiple class loader environment (such as a servlet container), but still allow each web application to provide its own <code>LogFactory</code> implementation, if it so desires. An instance of this class will then be created, and cached per class loader. <h4>The Default <code>LogFactory</code> Implementation</h4> <p>The Logging Package APIs include a default <code>LogFactory</code> implementation class (<a href="impl/LogFactoryImpl.html"> org.apache.commons.logging.impl.LogFactoryImpl</a>) that is selected if no other implementation class name can be discovered. Its primary purpose is to create (as necessary) and return <a href="Log.html">Log</a> instances in response to calls to the <code>getInstance()</code> method. The default implementation uses the following rules:</p> <ul> <li>At most one <code>Log</code> instance of the same name will be created. Subsequent <code>getInstance()</code> calls to the same <code>LogFactory</code> instance, with the same name or <code>Class</code> parameter, will return the same <code>Log</code> instance.</li> <li>When a new <code>Log</code> instance must be created, the default <code>LogFactory</code> implementation uses the following discovery process: <ul> <li>Look for a configuration attribute of this factory named <code>org.apache.commons.logging.Log</code> (for backwards compatibility to pre-1.0 versions of this API, an attribute <code>org.apache.commons.logging.log</code> is also consulted).</li> <li>Look for a system property named <code>org.apache.commons.logging.Log</code> (for backwards compatibility to pre-1.0 versions of this API, a system property <code>org.apache.commons.logging.log</code> is also consulted).</li> <li>If the Log4J logging system is available in the application class path, use the corresponding wrapper class (<a href="impl/Log4JLogger.html">Log4JLogger</a>).</li> <li>If the application is executing on a JDK 1.4 system, use the corresponding wrapper class (<a href="impl/Jdk14Logger.html">Jdk14Logger</a>).</li> <li>Fall back to the default simple logging implementation (<a href="impl/SimpleLog.html">SimpleLog</a>).</li> </ul></li> <li>Load the class of the specified name from the thread context class loader (if any), or from the class loader that loaded the <code>LogFactory</code> class otherwise.</li> <li>Instantiate an instance of the selected <code>Log</code> implementation class, passing the specified name as the single argument to its constructor.</li> </ul> <p>See the <a href="impl/SimpleLog.html">SimpleLog</a> JavaDocs for detailed configuration information for this default implementation.</p> <h4>Configuring the Underlying Logging System</h4> <p>The basic principle is that the user is totally responsible for the configuration of the underlying logging system. Commons-logging should not change the existing configuration.</p> <p>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="LogFactory.html#getInstance(java.lang.String)"> LogFactory.getInstance(String name)</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>Cause messages to be logged (if the corresponding detail level is enabled) by calling appropriate methods (<code>trace()</code>, <code>debug()</code>, <code>info()</code>, <code>warn()</code>, <code>error</code>, and <code>fatal()</code>).</li> </ol> <p>For convenience, <code>LogFactory</code> also offers a static method <code>getLog()</code> that combines the typical two-step pattern:</p> <pre> Log log = LogFactory.getFactory().getInstance(Foo.class); </pre> <p>into a single method call:</p> <pre> Log log = LogFactory.getLog(Foo.class); </pre> <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.LogFactory; public class MyComponent { protected Log log = LogFactory.getLog(MyComponent.class); // 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>