You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-cvs@jakarta.apache.org by ce...@apache.org on 2001/09/09 23:59:57 UTC

cvs commit: jakarta-log4j/src/docbook architecture.xml configuration.xml

ceki        01/09/09 14:59:57

  Modified:    src/docbook architecture.xml configuration.xml
  Log:
  More additions to Docbook documentation.
  
  Revision  Changes    Path
  1.3       +5 -3      jakarta-log4j/src/docbook/architecture.xml
  
  Index: architecture.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/src/docbook/architecture.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- architecture.xml	2001/09/09 20:20:26	1.2
  +++ architecture.xml	2001/09/09 21:59:57	1.3
  @@ -618,8 +618,10 @@
   	</tgroup>
         </table>
   
  -
  -      <para>More often than not, users wish to customize not only the
  +      <sect1>
  +	<title>Formatters</title>
  +	
  +	<para>More often than not, users wish to customize not only the
   	output destination but also the output format. This is
   	accomplished by associating a <emphasis>layout</emphasis> with
   	an appender. The layout is responsible for formatting the
  @@ -627,7 +629,7 @@
   	appender takes care of sending the formatted output to its
   	destination. </para>
   
  -      <para>The <ulink
  +	<para>The <ulink
   	  url="../api/org/apache/log4j/PatternLayout.html">PatternLayout</ulink>,
   	  part of the standard log4j distribution, lets the user
   	  specify the output format according to conversion patterns
  
  
  
  1.2       +490 -1    jakarta-log4j/src/docbook/configuration.xml
  
  Index: configuration.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/src/docbook/configuration.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- configuration.xml	2001/09/08 17:57:38	1.1
  +++ configuration.xml	2001/09/09 21:59:57	1.2
  @@ -1,6 +1,495 @@
   <chapter id="chap-configuration">
  -
     <title>Configuration</title>
  +
  +
  +  <para>Inserting log requests into the application code requires a
  +    fair amount of planning and effort. Observation shows that
  +    approximately 4 percent of code is dedicated to
  +    logging. Consequently, even moderately sized applications will
  +    have thousands of logging statements embedded within their code.
  +    Given their number, it becomes imperative to manage these log
  +    statements without the need to modify them manually.
  +  </para>
  +
  +  <para>The log4j environment is fully configurable programmatically.
  +    However, it is far more flexible to configure log4j using
  +    configuration files.  Currently, configuration files can be
  +    written in XML or in Java properties (key=value) format.</para>
  +
  +  <para>Let us give a taste of how this is done with the help of an
  +    imaginary application <code>MyApp</code> that uses log4j.</para>
  +
  +  <para>
  +    <programlisting>
  + import com.foo.Bar;
  +
  + // Import log4j classes.
  + <b>import org.apache.log4j.Category;
  + import org.apache.log4j.BasicConfigurator;</b>
  + 
  + public class MyApp {
  +
  +   // Define a static category variable so that it references the
  +   // Category instance named "MyApp".
  +   <strong>static</strong> Category cat = <strong>Category.getInstance(MyApp.class);</strong>
  +
  +   public static void main(String[] args) {
  +
  +     // Set up a simple configuration that logs on the console.
  +     <strong>BasicConfigurator.configure();</strong>
  +
  +     cat.info("Entering application.");
  +     Bar bar = new Bar();
  +     bar.doIt();
  +     cat.info("Exiting application.");    
  +   }
  + }
  +    </programlisting>
  +  </para>
  +
  +
  +  <para><code>MyApp</code> begins by importing log4j related classes.  It
  +    then defines a static category variable with the name
  +    <code>MyApp</code> which happens to be the fully qualified name of the
  +    class.</para>
  +
  +  <para><code>MyApp</code> uses the <code>Bar</code> class defined in the
  +    package <code>com.foo</code>.</para>
  +
  +  <para>
  +    <programlisting>
  + <b>package com.foo;</b>
  + import org.apache.log4j.Category;
  + 
  + public class Bar {
  +   <strong>static</strong> Category cat = <strong>Category.getInstance(Bar.class);</strong>
  +  
  +   public void doIt() {
  +     cat.debug("Did it again!");    
  +   }
  + }
  +    </programlisting>
  +  </para>
  +
  +  <para>The invocation of the <a
  +      href="api/org/apache/log4j/BasicConfigurator.html#configure()">BasicConfigurator.configure</a>
  +      method creates a rather simple log4j setup. This method is
  +      hardwired to add to the root category a <a
  +      href="api/org/apache/log4j/ConsoleAppender.html">
  +      ConsoleAppender</a>. The output will be formatted using a <a
  +      href="api/org/apache/log4j/PatternLayout.html">PatternLayout</a>
  +      set to the pattern "%-4r [%t] %-5p %c %x - %m%n".
  +  </para>
  +
  +  <para>Note that by default, the root category is assigned to
  +    <code>Priority.DEBUG</code>. </para>
  +
  +<para>The output of MyApp is:
  +    <screen>
  +0    [main] INFO  MyApp  - Entering application.
  +36   [main] DEBUG com.foo.Bar  - Did it again!
  +51   [main] INFO  MyApp  - Exiting application.
  +    </screen>
  +  </para>
  +  
  +  <para>The figure below depicts the object diagram of <code>MyApp</code>
  +    after just having called the <code>BasicConfigurator.configure</code>
  +    method. </para>
  +
  +  <para>
  +    <center>
  +      <img src="od.gif" align="center" >
  +    </center>
  +  </para>
  +
  +  <para>As a side note, let me mention that in log4j child categories
  +    link only to their existing ancestors. In particular, the category
  +    named <code>com.foo.Bar</code> is linked directly to the
  +    <code>root</code> category, thereby circumventing the unused
  +    <code>com</code> or <code>com.foo</code> categories. This
  +    significantly increases performance and reduces log4j's memory
  +    footprint.
  +  </para>
  +
  +  <para>The <code>MyApp</code> class configures log4j by invoking
  +    <code>BasicConfigurator.configure</code> method.  Other classes
  +    only need to import the <code>org.apache.log4j.Category</code>
  +    class, retrieve the categories they wish to use, and log away.
  +  </para>
  +
  +  <para>The previous example always outputs the same log information.
  +    Fortunately, it is easy to modify <code>MyApp</code> so that the
  +    log output can be controlled at run-time. Here is a slightly
  +    modified version.
  +  </para>
  +
  +  <para>
  +    <programlisting>
  +
  + import com.foo.Bar;
  +
  + import org.apache.log4j.Category;
  + <b>import org.apache.log4j.PropertyConfigurator;</b>
  + 
  + public class MyApp {
  +
  +   static Category cat = Category.getInstance(MyApp.class.getName());
  +
  +   public static void main(String[] args) {
  +
  +     
  +     // BasicConfigurator replaced with PropertyConfigurator.
  +     <strong>PropertyConfigurator.configure(args[0]);</strong>
  +
  +     cat.info("Entering application.");
  +     Bar bar = new Bar();
  +     bar.doIt();
  +     cat.info("Exiting application.");    
  +   }
  + }
  +    </programlisting>
  +  </para>
  +
  +  <para>This version of <code>MyApp</code> instructs
  +    <code>PropertyConfigurator</code> to parse a configuration file
  +    and set up logging accordingly.
  +  </para>
  +
  +  <para>Here is a sample configuration file that results in exactly
  +    same output as the previous <code>BasicConfigurator</code> based
  +    example.
  +  </para>
  +
  +  <para>
  +    <screen>
  +# Set root category priority to DEBUG and its only appender to A1.
  +log4j.rootCategory=DEBUG, A1
  +  
  +# A1 is set to be a ConsoleAppender. 
  +log4j.appender.A1=org.apache.log4j.ConsoleAppender
  +  
  +# A1 uses PatternLayout.
  +log4j.appender.A1.layout=org.apache.log4j.PatternLayout
  +log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
  +    </screen>
  +  </para>
  +
  +<!-- <para>Please note that if you copy and paste the examples, then result is
  +likely to include trailing spaces on some lines. These trailing spaces
  +are not trimmed out but interpreted by the PropertyConfigurator.  By
  +the time you read this article the problem should be corrected.
  +-->
  +
  +  <para>Suppose we are no longer interested in seeing the output of
  +    any component belonging to the <code>com.foo</code> package. The
  +    following configuration file shows one possible way of achieving
  +    this.
  +  </para>
  +
  +<para>
  +<programlisting>
  +
  +log4j.rootCategory=DEBUG, A1
  +log4j.appender.A1=org.apache.log4j.ConsoleAppender
  +log4j.appender.A1.layout=org.apache.log4j.PatternLayout
  +  
  +# <strong>Print the date in ISO 8601 format</strong>
  +log4j.appender.A1.layout.ConversionPattern=<strong>%d</strong> [%t] %-5p %c - %m%n
  +  
  +# Print only messages of priority WARN or above in the package com.foo.
  +<strong>log4j.category.com.foo=WARN</strong>
  +    </programlisting>
  +  </para>
  +
  +<para>The output of <code>MyApp</code> configured with this file is shown below.
  +  </para>
  +
  +<screen>
  +<strong>2000-09-07 14:07:41,508</strong> [main] INFO MyApp - Entering
  +application.  <strong>2000-09-07 14:07:41,529</strong> [main] INFO
  +MyApp - Exiting application.
  +  </screen>
  +
  +  <para>As the category <code>com.foo.Bar</code> does not have an
  +    assigned priority, it inherits its priority from
  +    <code>com.foo</code>, which was set to WARN in the configuration
  +    file. The log statement from the <code>Bar.doIt</code> method has
  +    the priority DEBUG, lower than the category priority
  +    WARN. Consequently, <code>doIt()</code> method's log request is
  +    suppressed.</para>
  +
  +    <para>Here is another configuration file that uses multiple
  +    appenders.</para>
  +
  +
  +  <para>
  +    <programlisting>
  +log4j.rootCategory=debug, <strong>stdout, R</strong>
  +
  +log4j.appender.<strong>stdout</strong>=org.apache.log4j.ConsoleAppender
  +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
  +
  +# Pattern to output the caller's file name and line number.
  +log4j.appender.stdout.layout.ConversionPattern=%5p [%t] <strong>(%F:%L)</strong> - %m%n
  +
  +log4j.appender.<strong>R</strong>=org.apache.log4j.RollingFileAppender
  +log4j.appender.R.File=example.log
  +
  +log4j.appender.R.MaxFileSize=<strong>100KB</strong>
  +# Keep one backup file
  +log4j.appender.R.MaxBackupIndex=1
  +
  +log4j.appender.R.layout=org.apache.log4j.PatternLayout
  +log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
  +    </programlisting>
  +  </para>
  +
  +  <para>Calling the enhanced MyApp with the this configuration file
  +    will output the following on the console.
  +  </para>
  +
  +  <screen>
  + INFO [main] <strong>(MyApp2.java:12)</strong> - Entering application.
  +DEBUG [main] (Bar.java:8) - Doing it again!
  + INFO [main] (MyApp2.java:15) - Exiting application.
  +  </screen>
  +
  +  <para>In addition, as the root category has been allocated a second
  +    appender, output will also be directed to the
  +    <code>example.log</code> file. This file will be rolled over when
  +    it reaches 100KB. When roll-over occurs, the old version of
  +    <code>example.log</code> is automatically moved to
  +    <code>example.log.1</code>.
  +  </para>
  +
  +  <para>Note that to obtain these different logging behaviors we did
  +    not need to recompile code. We could just as easily have logged to
  +    a UNIX Syslog daemon, redirected all <code>com.foo</code> output
  +    to an NT Event logger, or forwarded logging events to a remote
  +    log4j server, which would log according to local server policy,
  +    for example by forwarding the log event to a second log4j server.
  +  </para>
  +
  +  <sect1 id="defaultInit">
  +    <title>Default Initialization Procedure</title>
  +
  +    <para>The log4j library does not make any assumptions about its
  +      environment. In particular, there are no default log4j
  +      appenders. Under certain well-defined circumstances however, the
  +      static inializer of the <code>Category</code> class will attempt
  +      to automatically configure log4j. The Java language guarantees
  +      that the static initializer of a class is called once and only
  +      once during the loading of a class into memory. It is important
  +      to remember that different classloaders may load distinct copies
  +      of the same class. These copies of the same class are considered
  +      as totally unrelated by the JVM.
  +    </para>
  +
  +    <para>The default initialization is very useful in environments
  +      where the exact entry point to the application depends on the
  +      runtime environment. For example, the same application can be
  +      used as a stand-alone application, as an applet, or as a servlet
  +      under the control of a web-server.
  +    </para>
  +
  +    <para>The exact default initialization algorithm is defined as
  +    follows:</para>
  +
  +<ol>
  +
  + <li>Skip default initialization if the system property
  + <b>log4j.defaultInitOverride</b> is set to any value other than
  + "false".
  +
  + <para><li>Set the <code>resource</code> string variable to the value of
  + the <b>log4j.configuration</b> system property.  <em>The preferred
  + way to specify the default initialization file is thourough the
  + <b>log4j.configuration</b> system property.</em> In case the system
  + property <b>log4j.configuration</b> is not defined, then set the
  + string variable <code>resource</code> to its default value
  + "log4j.properties".
  +
  + <para><li>Attempt to convert the <code>resource</code> variable to a
  + URL.
  +
  + <para><li>If the resource variable cannot be converted to a URL, for
  + example due to a <code>MalformedURLException</code>, then search for
  + the <code>resource</code> from the classpath by calling
  + <code>org.apache.log4j.helpers.Loader.getResource(resource,
  + Category.class)</code> which returns a URL.  Note that the string
  + "log4j.properties" constitutes a malformed URL.
  +
  + <para>See <a
  + href="api/org/apache/log4j/helpers/Loader.html#getResource(java.lang.String)">Loader.getResource(java.lang.String)</a>
  + for the list of searched locations.
  +
  + <para><li>If no URL could not be found, abort default
  + initialization. Otherwise, configure log4j from the URL.
  +
  + <para>The <a
  +  href="api/org/apache/log4j/PropertyConfigurator.html">PropertyConfigurator</a>
  +  will be used to parse the URL to configure log4j unless the URL ends
  +  with the ".xml" extension, in which case the <a
  +  href="api/org/apache/log4j/xml/DOMConfigurator.html">DOMConfigurator</a>
  +  will be used. You can optionaly specify a custom configurator. The
  +  value of the <b>log4j.configuratorClass</b> system property is taken
  +  as the fully qualified class name of your custom configurator. The
  +  custom configurator you specify <em>must</em> implement the <a
  +  href="api/org/apache/log4j/spi/Configurator.html">Configurator</a>
  +  interface.
  +
  +</ol>
  +
  +<h2>Example Configurations</h2>
  +
  +
  +
  +<h2>Default Initialization under Tomcat</h2>
  +
  +<para>The default log4j initialization is particularly useful in
  +web-server environments. Under Tomcat 3.x and 4.x, you should place
  +the <code>log4j.properties</code> under the
  +<code>WEB-INF/classes</code> directory of your web-applications. Log4j
  +will find the properties file and initialize itself. This is easy to
  +do and it works.
  +
  +<para>You can also choose to set the system property
  +<b>log4j.configuration</b> before starting Tomcat. For Tomcat 3.x The
  +<code>TOMCAT_OPTS</code> environment variable is used to set command
  +line options. For Tomcat 4.0, set the <code>CATALINA_OPTS</code>
  +environment variable instead of <code>TOMCAT_OPTS</code>.
  +
  +<para><b>Example 1</b>
  +
  +<para>The Unix shell command
  +<pre>
  +   export TOMCAT_OPTS="-Dlog4j.configuration=foobar.txt"
  +</pre>
  +
  +tells log4j to use the file <code>foobar.txt</code> as the default
  +configuration file. This file should be place under the
  +<code>WEB-INF/classes</code> directory of your web-application. The
  +file will be read using the <a
  +href="api/org/apache/log4j/xml/PropertyConfigurator.html">PropertyConfigurator</a>. Each
  +web-application will use a different default configuration file because
  +each file is relative to a web-application.
  +
  +
  +<para><b>Example 2</b>
  +
  +<para>The Unix shell command
  +<pre>
  +   export TOMCAT_OPTS="-Dlog4j.debug -Dlog4j.configuration=foobar.xml"
  +</pre>
  +
  +tells log4j to output log4j-internal debugging information and to use
  +the file <code>foobar.xml</code> as the default configuration
  +file. This file should be place under the <code>WEB-INF/classes</code>
  +directory of your web-application. Since the file ends with a
  +<code>.xml</code> extension, it will read using the <a
  +href="api/org/apache/log4j/xml/DOMConfigurator.html">DOMConfigurator</a>. Each
  +web-application will use a different default configuration file because
  +each file is relative to a web-application.
  +
  +<para><b>Example 3</b>
  +
  +<para>The Windows shell command
  +<pre>
  +   set TOMCAT_OPTS=-Dlog4j.configuration=foobar.lcf#com.foo.BarConfigurator
  +</pre>
  +
  +tells log4j to use the file <code>foobar.lcf</code> as the default
  +configuration file. This file should be place under the
  +<code>WEB-INF/classes</code> directory of your web-application. Due to
  +the extra reference part, the file will be read using the
  +<code>com.foo.BarConfigurator</code> custom configurator.  Each
  +web-application will use a different default configuration file
  +because each file is relative to a web-application. <b>Support for
  +custom configurators in the reference part will be dropped in future
  +log4j versions. You should not rely on this feature.</b>
  +
  +
  +<para><b>Example 4</b>
  +
  +<para>The Windows shell command
  +<pre>
  +   set TOMCAT_OPTS=-Dlog4j.configuration=file:/c:/foobar.lcf</pre>
  +
  +tells log4j to use the file <code>c:\foobar.xml</code> as the default
  +configuration file. The configuration file is fully specified by the
  +URL <code>file:/c:/foobar.lcf</code>. Thus, the same configuration
  +file will be used for all web-applications. 
  +
  +
  +<para>Different web-applications will load the log4j classes through
  +their respective classloaderss. Thus, each image of the log4j
  +environment will act independetly and without any mutual
  +synchronization. For example, <code>FileAppenders</code> defined
  +exactly the same way in multiple web-application configurations will
  +all attempt to write the same file. The results are likely to be less
  +than satisfactory. You must make sure that log4j configurations of
  +different web-applications do not use the same underlying system
  +resource.
  +
  +
  +<para><b>Initialization servlet</b>
  +
  +<para>It is also possible to use a special servlet for log4j
  +initialization. Here is an example,
  +
  +<para><table bgcolor="CCCCCC"><tr><td>
  +<pre>
  +package com.foo;
  +
  +import org.apache.log4j.PropertyConfigurator;
  +import javax.servlet.http.HttpServlet;
  +import javax.servlet.http.HttpServletRequest;
  +import javax.servlet.http.HttpServletResponse;
  +import java.io.PrintWriter;
  +import java.io.IOException;
  +
  +public class Log4jInit extends HttpServlet {
  +  
  +  public
  +  void <b>init()</b> { 
  +    String prefix =  getServletContext().getRealPath("/");
  +    String file = getInitParameter("log4j-init-file");
  +    // if the log4j-init-file is not set, then no point in trying
  +    if(file != null) {
  +      PropertyConfigurator.configure(prefix+file);
  +    }
  +  }
  +
  +  public
  +  void doGet(HttpServletRequest req, HttpServletResponse res) {
  +  }
  +}
  +</pre>
  +</table>
  +
  +<para>Define the following servlet in the web.xml file for your web-application.
  +
  +<para><table bgcolor="CCAAAA"><tr><td>
  +<pre>
  +  &lt;servlet&gt;
  +    &lt;servlet-name&gt;log4j-init&lt;/servlet-name&gt;
  +    &lt;servlet-class&gt;com.foo.Log4jInit&lt;/servlet-class&gt;
  +
  +    &lt;init-param&gt;
  +      &lt;param-name&gt;log4j-init-file&lt;/param-name&gt;
  +      &lt;param-value&gt;WEB-INF/classes/log4j.lcf&lt;/param-value&gt;
  +    &lt;/init-param&gt;
  +
  +    <b>&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;</b>
  +  &lt;/servlet&gt;
  +</pre>
  +</table>
  +
  +<para>Writing an initialization servlet is the most flexible way for
  +initializing log4j. There are no constraints on the code you can place
  +in the <code>init()</code> method of the servlet.
  +
  +
       
     <sect1>
       <title>PropertyConfigurator</title>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-cvs-unsubscribe@jakarta.apache.org
For additional commands, e-mail: log4j-cvs-help@jakarta.apache.org