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>
+ <servlet>
+ <servlet-name>log4j-init</servlet-name>
+ <servlet-class>com.foo.Log4jInit</servlet-class>
+
+ <init-param>
+ <param-name>log4j-init-file</param-name>
+ <param-value>WEB-INF/classes/log4j.lcf</param-value>
+ </init-param>
+
+ <b><load-on-startup>1</load-on-startup></b>
+ </servlet>
+</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