1<!-- 2 3 Copyright 2001-2004 The Apache Software Foundation. 4 5 Licensed under the Apache License, Version 2.0 (the "License"); 6 you may not use this file except in compliance with the License. 7 You may obtain a copy of the License at 8 9 http://www.apache.org/licenses/LICENSE-2.0 10 11 Unless required by applicable law or agreed to in writing, software 12 distributed under the License is distributed on an "AS IS" BASIS, 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 See the License for the specific language governing permissions and 15 limitations under the License. 16 17--> 18 19<body> 20<p>Simple wrapper API around multiple logging APIs.</p> 21 22 23<h3>Overview</h3> 24 25<p>This package provides an API for logging in server-based applications that 26can be used around a variety of different logging implementations, including 27prebuilt support for the following:</p> 28<ul> 29<li><a href="http://logging.apache.org/log4j/">Log4J</a> (version 1.2 or later) 30 from Apache's Jakarta project. Each named <a href="Log.html">Log</a> 31 instance is connected to a corresponding Log4J Logger.</li> 32<li><a href="http://java.sun.com/j2se/1.4/docs/guide/util/logging/index.html"> 33 JDK Logging API</a>, included in JDK 1.4 or later systems. Each named 34 <a href="Log.html">Log</a> instance is connected to a corresponding 35 <code>java.util.logging.Logger</code> instance.</li> 36<li><a href="http://avalon.apache.org/logkit/">LogKit</a> from Apache's 37 Avalon project. Each named <a href="Log.html">Log</a> instance is 38 connected to a corresponding LogKit <code>Logger</code>.</li> 39<li><a href="impl/NoOpLog.html">NoOpLog</a> implementation that simply swallows 40 all log output, for all named <a href="Log.html">Log</a> instances.</li> 41<li><a href="impl/SimpleLog.html">SimpleLog</a> implementation that writes all 42 log output, for all named <a href="Log.html">Log</a> instances, to 43 System.err.</li> 44</ul> 45 46 47<h3>Quick Start Guide</h3> 48 49<p>For those impatient to just get on with it, the following example 50illustrates the typical declaration and use of a logger that is named (by 51convention) after the calling class: 52 53<pre> 54 import org.apache.commons.logging.Log; 55 import org.apache.commons.logging.LogFactory; 56 57 public class Foo { 58 59 private Log log = LogFactory.getLog(Foo.class); 60 61 public void foo() { 62 ... 63 try { 64 if (log.isDebugEnabled()) { 65 log.debug("About to do something to object " + name); 66 } 67 name.bar(); 68 } catch (IllegalStateException e) { 69 log.error("Something bad happened to " + name, e); 70 } 71 ... 72 } 73</pre> 74 75<p>Unless you configure things differently, all log output will be written 76to System.err. Therefore, you really will want to review the remainder of 77this page in order to understand how to configure logging for your 78application.</p> 79 80 81<h3>Configuring the Commons Logging Package</h3> 82 83 84<h4>Choosing a <code>LogFactory</code> Implementation</h4> 85 86<p>From an application perspective, the first requirement is to retrieve an 87object reference to the <code>LogFactory</code> instance that will be used 88to create <code><a href="Log.html">Log</a></code> instances for this 89application. This is normally accomplished by calling the static 90<code>getFactory()</code> method. This method implements the following 91discovery algorithm to select the name of the <code>LogFactory</code> 92implementation class this application wants to use:</p> 93<ul> 94<li>Check for a system property named 95 <code>org.apache.commons.logging.LogFactory</code>.</li> 96<li>Use the JDK 1.3 JAR Services Discovery mechanism (see 97 <a href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html"> 98 http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html</a> for 99 more information) to look for a resource named 100 <code>META-INF/services/org.apache.commons.logging.LogFactory</code> 101 whose first line is assumed to contain the desired class name.</li> 102<li>Look for a properties file named <code>commons-logging.properties</code> 103 visible in the application class path, with a property named 104 <code>org.apache.commons.logging.LogFactory</code> defining the 105 desired implementation class name.</li> 106<li>Fall back to a default implementation, which is described 107 further below.</li> 108</ul> 109 110<p>If a <code>commons-logging.properties</code> file is found, all of the 111properties defined there are also used to set configuration attributes on 112the instantiated <code>LogFactory</code> instance.</p> 113 114<p>Once an implementation class name is selected, the corresponding class is 115loaded from the current Thread context class loader (if there is one), or 116from the class loader that loaded the <code>LogFactory</code> class itself 117otherwise. This allows a copy of <code>commons-logging.jar</code> to be 118shared in a multiple class loader environment (such as a servlet container), 119but still allow each web application to provide its own <code>LogFactory</code> 120implementation, if it so desires. An instance of this class will then be 121created, and cached per class loader. 122 123 124<h4>The Default <code>LogFactory</code> Implementation</h4> 125 126<p>The Logging Package APIs include a default <code>LogFactory</code> 127implementation class (<a href="impl/LogFactoryImpl.html"> 128org.apache.commons.logging.impl.LogFactoryImpl</a>) that is selected if no 129other implementation class name can be discovered. Its primary purpose is 130to create (as necessary) and return <a href="Log.html">Log</a> instances 131in response to calls to the <code>getInstance()</code> method. The default 132implementation uses the following rules:</p> 133<ul> 134<li>At most one <code>Log</code> instance of the same name will be created. 135 Subsequent <code>getInstance()</code> calls to the same 136 <code>LogFactory</code> instance, with the same name or <code>Class</code> 137 parameter, will return the same <code>Log</code> instance.</li> 138<li>When a new <code>Log</code> instance must be created, the default 139 <code>LogFactory</code> implementation uses the following discovery 140 process: 141 <ul> 142 <li>Look for a configuration attribute of this factory named 143 <code>org.apache.commons.logging.Log</code> (for backwards 144 compatibility to pre-1.0 versions of this API, an attribute 145 <code>org.apache.commons.logging.log</code> is also consulted).</li> 146 <li>Look for a system property named 147 <code>org.apache.commons.logging.Log</code> (for backwards 148 compatibility to pre-1.0 versions of this API, a system property 149 <code>org.apache.commons.logging.log</code> is also consulted).</li> 150 <li>If the Log4J logging system is available in the application 151 class path, use the corresponding wrapper class 152 (<a href="impl/Log4JLogger.html">Log4JLogger</a>).</li> 153 <li>If the application is executing on a JDK 1.4 system, use 154 the corresponding wrapper class 155 (<a href="impl/Jdk14Logger.html">Jdk14Logger</a>).</li> 156 <li>Fall back to the default simple logging implementation 157 (<a href="impl/SimpleLog.html">SimpleLog</a>).</li> 158 </ul></li> 159<li>Load the class of the specified name from the thread context class 160 loader (if any), or from the class loader that loaded the 161 <code>LogFactory</code> class otherwise.</li> 162<li>Instantiate an instance of the selected <code>Log</code> 163 implementation class, passing the specified name as the single 164 argument to its constructor.</li> 165</ul> 166 167<p>See the <a href="impl/SimpleLog.html">SimpleLog</a> JavaDocs for detailed 168configuration information for this default implementation.</p> 169 170 171<h4>Configuring the Underlying Logging System</h4> 172 173<p>The basic principle is that the user is totally responsible for the 174configuration of the underlying logging system. 175Commons-logging should not change the existing configuration.</p> 176 177<p>Each individual <a href="Log.html">Log</a> implementation may 178support its own configuration properties. These will be documented in the 179class descriptions for the corresponding implementation class.</p> 180 181<p>Finally, some <code>Log</code> implementations (such as the one for Log4J) 182require an external configuration file for the entire logging environment. 183This file should be prepared in a manner that is specific to the actual logging 184technology being used.</p> 185 186 187<h3>Using the Logging Package APIs</h3> 188 189<p>Use of the Logging Package APIs, from the perspective of an application 190component, consists of the following steps:</p> 191<ol> 192<li>Acquire a reference to an instance of 193 <a href="Log.html">org.apache.commons.logging.Log</a>, by calling the 194 factory method 195 <a href="LogFactory.html#getInstance(java.lang.String)"> 196 LogFactory.getInstance(String name)</a>. Your application can contain 197 references to multiple loggers that are used for different 198 purposes. A typical scenario for a server application is to have each 199 major component of the server use its own Log instance.</li> 200<li>Cause messages to be logged (if the corresponding detail level is enabled) 201 by calling appropriate methods (<code>trace()</code>, <code>debug()</code>, 202 <code>info()</code>, <code>warn()</code>, <code>error</code>, and 203 <code>fatal()</code>).</li> 204</ol> 205 206<p>For convenience, <code>LogFactory</code> also offers a static method 207<code>getLog()</code> that combines the typical two-step pattern:</p> 208<pre> 209 Log log = LogFactory.getFactory().getInstance(Foo.class); 210</pre> 211<p>into a single method call:</p> 212<pre> 213 Log log = LogFactory.getLog(Foo.class); 214</pre> 215 216<p>For example, you might use the following technique to initialize and 217use a <a href="Log.html">Log</a> instance in an application component:</p> 218<pre> 219import org.apache.commons.logging.Log; 220import org.apache.commons.logging.LogFactory; 221 222public class MyComponent { 223 224 protected Log log = 225 LogFactory.getLog(MyComponent.class); 226 227 // Called once at startup time 228 public void start() { 229 ... 230 log.info("MyComponent started"); 231 ... 232 } 233 234 // Called once at shutdown time 235 public void stop() { 236 ... 237 log.info("MyComponent stopped"); 238 ... 239 } 240 241 // Called repeatedly to process a particular argument value 242 // which you want logged if debugging is enabled 243 public void process(String value) { 244 ... 245 // Do the string concatenation only if logging is enabled 246 if (log.isDebugEnabled()) 247 log.debug("MyComponent processing " + value); 248 ... 249 } 250 251} 252</pre> 253 254</body> 255