Home | History | Annotate | Download | only in logging
      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
     26 can be used around a variety of different logging implementations, including
     27 prebuilt 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
     50 illustrates the typical declaration and use of a logger that is named (by
     51 convention) 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
     76 to System.err.  Therefore, you really will want to review the remainder of
     77 this page in order to understand how to configure logging for your
     78 application.</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
     87 object reference to the <code>LogFactory</code> instance that will be used
     88 to create <code><a href="Log.html">Log</a></code> instances for this
     89 application.  This is normally accomplished by calling the static
     90 <code>getFactory()</code> method.  This method implements the following
     91 discovery algorithm to select the name of the <code>LogFactory</code>
     92 implementation 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
    111 properties defined there are also used to set configuration attributes on
    112 the instantiated <code>LogFactory</code> instance.</p>
    113 
    114 <p>Once an implementation class name is selected, the corresponding class is
    115 loaded from the current Thread context class loader (if there is one), or
    116 from the class loader that loaded the <code>LogFactory</code> class itself
    117 otherwise.  This allows a copy of <code>commons-logging.jar</code> to be
    118 shared in a multiple class loader environment (such as a servlet container),
    119 but still allow each web application to provide its own <code>LogFactory</code>
    120 implementation, if it so desires.  An instance of this class will then be
    121 created, 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>
    127 implementation class (<a href="impl/LogFactoryImpl.html">
    128 org.apache.commons.logging.impl.LogFactoryImpl</a>) that is selected if no
    129 other implementation class name can be discovered.  Its primary purpose is
    130 to create (as necessary) and return <a href="Log.html">Log</a> instances
    131 in response to calls to the <code>getInstance()</code> method.  The default
    132 implementation 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
    168 configuration 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
    174 configuration of the underlying logging system.
    175 Commons-logging should not change the existing configuration.</p>
    176 
    177 <p>Each individual <a href="Log.html">Log</a> implementation may
    178 support its own configuration properties.  These will be documented in the
    179 class descriptions for the corresponding implementation class.</p>
    180 
    181 <p>Finally, some <code>Log</code> implementations (such as the one for Log4J)
    182 require an external configuration file for the entire logging environment.
    183 This file should be prepared in a manner that is specific to the actual logging
    184 technology 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
    190 component, 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
    217 use a <a href="Log.html">Log</a> instance in an application component:</p>
    218 <pre>
    219 import org.apache.commons.logging.Log;
    220 import org.apache.commons.logging.LogFactory;
    221 
    222 public 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