logging-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From grobme...@apache.org
Subject svn commit: r1334587 - in /logging/log4j/trunk: BUILD-INFO.txt src/site/site.xml src/site/xdoc/building.xml
Date Sun, 06 May 2012 10:08:27 GMT
Author: grobmeier
Date: Sun May  6 10:08:26 2012
New Revision: 1334587

URL: http://svn.apache.org/viewvc?rev=1334587&view=rev
Log:
moved building info to an own site page, some clean ups

Added:
    logging/log4j/trunk/src/site/xdoc/building.xml
      - copied, changed from r1334576, logging/log4j/trunk/src/site/xdoc/manual.xml
Removed:
    logging/log4j/trunk/BUILD-INFO.txt
Modified:
    logging/log4j/trunk/src/site/site.xml

Modified: logging/log4j/trunk/src/site/site.xml
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/site/site.xml?rev=1334587&r1=1334586&r2=1334587&view=diff
==============================================================================
--- logging/log4j/trunk/src/site/site.xml (original)
+++ logging/log4j/trunk/src/site/site.xml Sun May  6 10:08:26 2012
@@ -51,6 +51,7 @@
 		<item name="Introduction" href="/manual.html"/>
 		<item name="JavaDoc" href="/apidocs/index.html"/>
 		<item name="Publications" href="/publications.html"/>
+        <item name="Building" href="/building.html"/>
 		<item name="Wiki" href="http://wiki.apache.org/logging-log4j"/>
 	</menu>
 	

Copied: logging/log4j/trunk/src/site/xdoc/building.xml (from r1334576, logging/log4j/trunk/src/site/xdoc/manual.xml)
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/site/xdoc/building.xml?p2=logging/log4j/trunk/src/site/xdoc/building.xml&p1=logging/log4j/trunk/src/site/xdoc/manual.xml&r1=1334576&r2=1334587&rev=1334587&view=diff
==============================================================================
--- logging/log4j/trunk/src/site/xdoc/manual.xml (original)
+++ logging/log4j/trunk/src/site/xdoc/building.xml Sun May  6 10:08:26 2012
@@ -18,1222 +18,170 @@
 <document>
 
   <properties>
-    <author email="not@disclosed">Ceki G&#xfc;lc&#xfc;</author>
-    <title>Short introduction to log4j</title>
+    <author email="log4j-dev@logging.apache.org">The Apache log4j team</author>
+    <title>How to build Apache log4j</title>
   </properties>
   <body>
-<section name="Short introduction to log4j: Ceki G&#xfc;lc&#xfc;, March 2002">
-    <p>
-      Copyright &#xa9; 2000-2002 The Apache Software Foundation. All
-      rights reserved.  This software is published under the terms of
-      the Apache Software License version 2.0, a copy of which has
-      been included in the LICENSE file shipped with the log4j
-      distribution. This document is based on the article <a
-      href="http://www.javaworld.com/jw-11-2000/jw-1122-log4j.html">"Log4j
-      delivers control over logging"</a> published in November 2000
-      edition of JavaWorld. However, the present article contains more
-      detailed and up to date information. The present short manual
-      also borrows some text from <a
-      href="https://www.qos.ch/shop/products/eclm/">"<em>The
-      complete log4j manual</em>"</a> by the same author (yours
-      truly).</p>
-
-<h2>Abstract</h2>
-
-<p>This document describes the log4j API, its unique features and
-design rationale. Log4j is an open source project based on the work of
-many authors.  It allows the developer to control which log statements
-are output with arbitrary granularity. It is fully configurable at
-runtime using external configuration files.  Best of all, log4j has a
-gentle learning curve. Beware: judging from user feedback, it is also
-quite addictive.</p>
+<section name="Building Apache log4j">
 
 <h2>Introduction</h2>
 
-<p>Almost every large application includes its own logging or tracing
-API. In conformance with this rule, the E.U.  <a
-href="http://www.semper.org">SEMPER</a> project decided to write its
-own tracing API. This was in early 1996. After countless enhancements,
-several incarnations and much work that API has evolved to become
-log4j, a popular logging package for Java. The package is distributed
-under the <a href="license.html">Apache Software License</a>, a
-fully-fledged open source license certified by the <a
-href="http://www.opensource.org">open source</a> initiative. The
-latest log4j version, including full-source code, class files and
-documentation can be found at <a
-href="http://logging.apache.org/log4j/"><b>http://logging.apache.org/log4j/</b></a>.
-By the way, log4j has been ported to the C, C++, C#, Perl, Python,
-Ruby, and Eiffel languages.</p>
-
-<p>Inserting log statements into code is a low-tech method for
-debugging it. It may also be the only way because debuggers are not
-always available or applicable. This is usually the case for
-multithreaded applications and distributed applications at large.</p>
-
-<p>Experience indicates that logging was an important component of the
-development cycle. It offers several advantages. It provides precise
-<em>context</em> about a run of the application. Once inserted into
-the code, the generation of logging output requires no human
-intervention.  Moreover, log output can be saved in persistent medium
-to be studied at a later time. In addition to its use in the
-development cycle, a sufficiently rich logging package can also be
-viewed as an auditing tool.</p>
+<p>This is a detailed instruction to reproduce the log4j distribution
+either to verify that the release is reproducable or to prepare
+a hot-fix.</p>
 
-<p>As Brian W. Kernighan and Rob Pike put it in their truly excellent
-book <i>"The Practice of Programming"</i>
-<pre>
-  As personal choice, we tend not to use debuggers beyond getting a
-  stack trace or the value of a variable or two. One reason is that it
-  is easy to get lost in details of complicated data structures and
-  control flow; we find stepping through a program less productive
-  than thinking harder and adding output statements and self-checking
-  code at critical places. Clicking over statements takes longer than
-  scanning the output of judiciously-placed displays. It takes less
-  time to decide where to put print statements than to single-step to
-  the critical section of code, even assuming we know where that
-  is. More important, debugging statements stay with the program;
-  debugging sessions are transient.
-</pre></p>
-
-<p>Logging does have its drawbacks. It can slow down an
-application. If too verbose, it can cause scrolling blindness. To
-alleviate these concerns, log4j is designed to be reliable, fast and
-extensible. Since logging is rarely the main focus of an application,
-the log4j API strives to be simple to understand and to use.</p>
-
-<h2>Loggers, Appenders and Layouts</h2>
-
-<p>Log4j has three main components: <em>loggers</em>,
-<em>appenders</em> and <em>layouts</em>. These three types of
-components work together to enable developers to log messages according
-to message type and level, and to control at runtime how these
-messages are formatted and where they are reported.</p>
-
-<h3>Logger hierarchy</h3>
-
-<p>The first and foremost advantage of any logging API over plain
-<code>System.out.println</code> resides in its ability to disable
-certain log statements while allowing others to print unhindered. This
-capability assumes that the logging space, that is, the space of all
-possible logging statements, is categorized according to some
-developer-chosen criteria. This observation had previously led us to
-choose <em>category</em> as the central concept of the
-package. However, since log4j version 1.2, <code>Logger</code> class
-has replaced the <code>Category</code> class. For those familiar with
-earlier versions of log4j, the <code>Logger</code> class can be
-considered as a mere alias to the <code>Category</code> class.</p>
+<p>The log4j build is platform dependent. The best is to setup a VM using virtualbox (or similar),
+install Ubuntu and follow the steps here.</p>
 
-<p>Loggers are named entities. Logger names are case-sensitive and
-they follow the hierarchical naming rule:</p>
+<h2>Preparation of environment</h2>
 
-<p>
-<table bgcolor="#EEEE99">
- <tr>
-  <td>
-   <dl>
-     <dt><b>Named Hierarchy</b></dt>
-
-     <dd>A logger is said to be an <em>ancestor</em> of another
-     logger if its name followed by a dot is a prefix of the
-     <em>descendant</em> logger name. A logger is said to be a
-     <em>parent</em> of a <em>child</em> logger if there are no
-     ancestors between itself and the descendant logger.</dd>
-
-
-   </dl>
-</td></tr></table></p>
-
-
-<p>For example, the logger named <code>"com.foo"</code> is a parent
-of the logger named <code>"com.foo.Bar"</code>.  Similarly,
-<code>"java"</code> is a parent of <code>"java.util"</code> and an
-ancestor of <code>"java.util.Vector"</code>.  This naming scheme
-should be familiar to most developers.</p>
-
-<p>The root logger resides at the top of the logger hierarchy. It
-is exceptional in two ways:
-
-<ol>
-<li> it always exists,</li>
-<li> it cannot be retrieved by name.</li>
-</ol></p>
-<p>Invoking the class static <a
-href="apidocs/org/apache/log4j/Logger.html#getRootLogger()">Logger.getRootLogger</a>
-method retrieves it. All other loggers are instantiated and
-retrieved with the class static <a
-href="apidocs/org/apache/log4j/Logger.html#getLogger(java.lang.String)">Logger.getLogger</a>
-method. This method takes the name of the desired logger as a
-parameter. Some of the basic methods in the Logger class are listed
-below.</p>
-
-<p><table>
-<tr bgcolor="CCCCCC">
-<td>
+<h3>Install Sun Java 6</h3>
 <pre>
-  package org.apache.log4j;
-
-  public class <b>Logger</b> {
-
-    // Creation &amp; retrieval methods:
-    public static Logger getRootLogger();
-    public static Logger getLogger(String name);
-
-    // printing methods:
-    public void trace(Object message);
-    public void debug(Object message);
-    public void info(Object message);
-    public void warn(Object message);
-    public void error(Object message);
-    public void fatal(Object message);
-
-    // generic printing method:
-    public void log(Level l, Object message);
-}
+$> sudo sed  's/restricted/restricted universe multiverse/' -i /etc/apt/sources.list
+$> sudo apt-get update &amp;&amp; sudo apt-get -y update
+$> sudo apt-get install openjdk-6-jdk
 </pre>
-</td>
-</tr>
-</table></p>
-
-<p>Loggers <em>may</em> be assigned levels. The set of possible
-levels, that is:<br/><br/>
-
-<a href="apidocs/org/apache/log4j/Level.html#TRACE">TRACE</a>,<br/>
-<a href="apidocs/org/apache/log4j/Level.html#DEBUG">DEBUG</a>,<br/>
-<a href="apidocs/org/apache/log4j/Level.html#INFO">INFO</a>,<br/>
-<a href="apidocs/org/apache/log4j/Level.html#WARN">WARN</a>,<br/>
-<a href="apidocs/org/apache/log4j/Level.html#ERROR">ERROR</a> and<br/>
-<a href="apidocs/org/apache/log4j/Level.html#FATAL">FATAL</a><br/>
-<br/>
-
-are defined in the <code><a
-href="apidocs/org/apache/log4j/Level.html">org.apache.log4j.Level</a></code>
-class. Although we do not encourage you to do so, you may define
-your own levels by sub-classing the <code>Level</code> class. A
-perhaps better approach will be explained later on.</p>
-
-<p>If a given logger is not assigned a level, then it inherits
-one from its closest ancestor with an assigned level. More
-formally:</p>
-
-
-<p>
-<table bgcolor="#EEEE99">
-  <tr>
-  <td>
-   <dl>
-     <dt><b>Level Inheritance</b></dt>
-
-     <dd><p>The <em>inherited level</em> for a given logger
-<i>C</i>, is equal to the first non-null level in the logger
-hierarchy, starting at <i>C</i> and proceeding upwards in the
-hierarchy towards the <code>root</code> logger.</p></dd>
-
-   </dl>
-   </td>
-   </tr>
-</table></p>
-
-<p>To ensure that all loggers can eventually inherit a level,
-the root logger always has an assigned level.</p>
-
-<p>Below are four tables with various assigned level values and the
-resulting inherited levels according to the above rule.</p>
-
-<p>
-<table border="1" >
-  <tr><th>Logger<br/>name</th><th>Assigned<br/>level</th>
-    <th>Inherited<br/>level</th></tr>
-    <tr align="left"><td>root</td>    <td>Proot</td> <td>Proot</td></tr>
-    <tr align="left"><td>X </td>      <td>none</td>  <td>Proot</td></tr>
-    <tr align="left"><td>X.Y </td>    <td>none</td>  <td>Proot</td></tr>
-    <tr align="left"><td>X.Y.Z</td>   <td>none</td>  <td>Proot</td></tr>
-    <caption align="bottom">Example 1</caption>
-</table></p>
-
-<p>In example 1 above, only the root logger is assigned a
-level. This level value, <code>Proot</code>, is inherited by the
-other loggers <code>X</code>, <code>X.Y</code> and
-<code>X.Y.Z</code>.</p>
-
-
-<p>
-<table border="1">
-    <tr><th>Logger<br/>name</th><th>Assigned<br/>level</th>
-    <th>Inherited<br/>level</th></tr>
-    <tr align="left"><td>root</td>    <td>Proot</td> <td>Proot</td></tr>
-    <tr align="left"><td>X </td>      <td>Px</td>    <td>Px</td></tr>
-    <tr align="left"><td>X.Y </td>    <td>Pxy</td>   <td>Pxy</td></tr>
-    <tr align="left"><td>X.Y.Z</td>   <td>Pxyz</td>  <td>Pxyz</td></tr>
-    <caption align="bottom">Example 2</caption>
-  </table></p>
-
-<p>In example 2, all loggers have an assigned level value. There
-is no need for level inheritence.</p>
-
-<p><table border="1">
-    <tr><th>Logger<br/>name</th><th>Assigned<br/>level</th>
-    <th>Inherited<br/>level</th></tr>
-    <tr align="left"><td>root</td>    <td>Proot</td> <td>Proot</td></tr>
-    <tr align="left"><td>X </td>      <td>Px</td>    <td>Px</td></tr>
-    <tr align="left"><td>X.Y </td>    <td>none</td>  <td>Px</td></tr>
-    <tr align="left"><td>X.Y.Z</td>   <td>Pxyz</td>  <td>Pxyz</td></tr>
-    <caption align="bottom">Example 3</caption>
-</table></p>
-
-<p>In example 3, the loggers <code>root</code>, <code>X</code> and
-<code>X.Y.Z</code> are assigned the levels <code>Proot</code>,
-<code>Px</code> and <code>Pxyz</code> respectively. The logger
-<code>X.Y</code> inherits its level value from its parent
-<code>X</code>.</p>
-
-<table border="1">
-    <tr><th>Logger<br/>name</th><th>Assigned<br/>level</th>
-    <th>Inherited<br/>level</th></tr>
-    <tr align="left"><td>root</td>    <td>Proot</td> <td>Proot</td></tr>
-    <tr align="left"><td>X </td>      <td>Px</td>    <td>Px</td></tr>
-    <tr align="left"><td>X.Y </td>    <td>none</td>  <td>Px</td></tr>
-    <tr align="left"><td>X.Y.Z</td>   <td>none</td>  <td>Px</td></tr>
-    <caption align="bottom">Example 4</caption>
-</table>
-
-<p>In example 4, the loggers <code>root</code> and <code>X</code>
-and are assigned the levels <code>Proot</code> and <code>Px</code>
-respectively. The loggers <code>X.Y</code> and <code>X.Y.Z</code>
-inherits their level value from their nearest parent <code>X</code>
-having an assigned level..</p>
-
-
-<p>Logging requests are made by invoking one of the printing methods
-of a logger instance. These printing methods are
-
-<code>
-<a href="apidocs/org/apache/log4j/Category.html#debug(java.lang.Object)">debug</a>,
-
-<a href="apidocs/org/apache/log4j/Category.html#info(java.lang.Object)">info</a>,
-
-<a href="apidocs/org/apache/log4j/Category.html#warn(java.lang.Object)">warn</a>,
-<a href="apidocs/org/apache/log4j//Category.html#error(java.lang.Object)">error</a>,
-<a href="apidocs/org/apache/log4j/Category.html#fatal(java.lang.Object)">fatal</a>
- and <a href="apidocs/org/apache/log4j/Category.html#log(org.apache.log4j.Priority, java.lang.Object)">log</a></code>.</p>
-
-
-<p>By definition, the printing method determines the level of a
-logging request. For example, if <code>c</code> is a logger
-instance, then the statement <code>c.info("..")</code> is a logging
-request of level INFO.</p>
-
-<p>A logging request is said to be <em>enabled</em> if its level is
-higher than or equal to the level of its logger. Otherwise, the
-request is said to be <em>disabled</em>. A logger without an
-assigned level will inherit one from the hierarchy. This rule is
-summarized below.</p>
-
 
-<p>
-<a name="selectionRule"/><table bgcolor="#EEEE99">
-  <tr>
-  <td>
-      <dl>
-	<dt><b>Basic Selection Rule</b></dt>
-
-	<dd><p>A log request of level <i>p</i> in a logger with
-	(either assigned or inherited, whichever is appropriate) level <i>q</i>, is enabled if <i> p &gt;=
-	q</i>.</p></dd>
-      </dl>
-</td></tr></table></p>
-
-<p>This rule is at the heart of log4j. It assumes that levels are
-ordered. For the standard levels, we have <code>DEBUG &lt; INFO
-&lt; WARN &lt; ERROR &lt; FATAL</code>.</p>
 
-<p>Here is an example of this rule.</p>
+<h3>Install Maven 2, Subversion, mingw and xemacs21, openssh-server:</h3>
 
-<p><table bgcolor="CCCCCC">
-<tr><td>
 <pre>
-
-   // get a logger instance named "com.foo"
-   Logger  logger = Logger.getLogger(<strong>"com.foo"</strong>);
-
-   // Now set its level. Normally you do not need to set the
-   // level of a logger programmatically. This is usually done
-   // in configuration files.
-   <strong>logger</strong>.setLevel(<font
-   color="0000AA"><strong>Level.INFO</strong></font>);
-
-   Logger barlogger = Logger.getLogger(<strong>"com.foo.Bar"</strong>);
-
-   // This request is enabled, because <font color="00AA00"><strong>WARN</strong></font> &gt;= <font color="0000AA"><strong>INFO</strong></font>.
-   logger.<font color="00AA00"><strong>warn</strong></font>("Low fuel level.");
-
-   // This request is disabled, because <font color="00AA00"><strong>DEBUG</strong></font> &lt; <font color="0000AA"><strong>INFO</strong></font>.
-   logger.<font color="00AA00"><strong>debug</strong></font>("Starting search for nearest gas station.");
-
-   // The logger instance barlogger, named "com.foo.Bar",
-   // will inherit its level from the logger named
-   // "com.foo" Thus, the following request is enabled
-   // because <font color="00AA00"><strong>INFO</strong></font> &gt;= <font color="0000AA"><strong>INFO</strong></font>.
-   barlogger.<font color="00AA00"><strong>info</strong></font>("Located nearest gas station.");
-
-   // This request is disabled, because <font color="00AA00"><strong>DEBUG</strong></font> &lt; <font color="0000AA"><strong>INFO</strong></font>.
-   barlogger.<font color="00AA00"><strong>debug</strong></font>("Exiting gas station search");
+$> sudo apt-get install maven2 subversion mingw32 xemacs21 openssh-server
 </pre>
-</td></tr>
-</table></p>
-
-<p>Calling the <code>getLogger</code> method with the same name will
-always return a reference to the exact same logger object.</p>
-
-<p>For example, in
-
-<table bgcolor="CCCCCC">
-<tr><td>
-<pre>
-   Logger x = Logger.getLogger("wombat");
-   Logger y = Logger.getLogger("wombat");</pre>
-</td></tr>
-</table>
-<code>x</code> and <code>y</code> refer to <em>exactly</em> the same
-logger object.</p>
-
-<p>Thus, it is possible to configure a logger and then to retrieve
-the same instance somewhere else in the code without passing around
-references. In fundamental contradiction to biological parenthood,
-where parents always preceed their children, log4j loggers can be
-created and configured in any order. In particular, a "parent"
-logger will find and link to its descendants even if it is
-instantiated after them.</p>
-
-<p>Configuration of the log4j environment is typically done at
-application initialization. The preferred way is by reading a
-configuration file. This approach will be discussed shortly.</p>
-
-<p>Log4j makes it easy to name loggers by <em>software
-component</em>.  This can be accomplished by statically instantiating
-a logger in each class, with the logger name equal to the fully
-qualified name of the class. This is a useful and straightforward
-method of defining loggers. As the log output bears the name of the
-generating logger, this naming strategy makes it easy to identify
-the origin of a log message.  However, this is only one possible,
-albeit common, strategy for naming loggers. Log4j does not restrict
-the possible set of loggers. The developer is free to name the
-loggers as desired.</p>
-
-<p>Nevertheless, naming loggers after the class where they are
-located seems to be the best strategy known so far.</p>
-
-<h2>Appenders and Layouts</h2>
-
-<p>The ability to selectively enable or disable logging requests based
-on their logger is only part of the picture. Log4j allows logging
-requests to print to multiple destinations. In log4j speak, an output
-destination is called an <em>appender</em>. Currently, appenders exist
-for the <a href="apidocs/org/apache/log4j/ConsoleAppender.html">console</a>, <a
-href="apidocs/org/apache/log4j/FileAppender.html">files</a>, GUI
-components, <a
-href="apidocs/org/apache/log4j/net/SocketAppender.html">remote socket</a>
-servers,  <a
-href="apidocs/org/apache/log4j/net/JMSAppender.html">JMS</a>,
-
-<a href="apidocs/org/apache/log4j/nt/NTEventLogAppender.html"> NT
-Event Loggers</a>, and remote UNIX <a
-href="apidocs/org/apache/log4j/net/SyslogAppender.html">Syslog</a>
-daemons. It is also possible to log <a href="apidocs/org/apache/log4j/AsyncAppender.html">asynchronously</a>.</p>
-
-<p>More than one appender can be attached to a logger.</p>
-
-<p>The <a
-href="apidocs/org/apache/log4j/Category.html#addAppender(org.apache.log4j.Appender)">addAppender</a>
-method adds an appender to a given logger.
-
-<b>Each enabled logging
-request for a given logger will be forwarded to all the appenders in
-that logger as well as the appenders higher in the hierarchy.</b> In
-other words, appenders are inherited additively from the logger
-hierarchy. For example, if a console appender is added to the root
-logger, then all enabled logging requests will at least print on the
-console. If in addition a file appender is added to a logger, say
-<em>C</em>, then enabled logging requests for <em>C</em> and
-<em>C</em>'s children will print on a file <em>and</em> on the
-console. It is possible to override this default behavior so that
-appender accumulation is no longer additive by <a
-href="apidocs/org/apache/log4j/Category.html#setAdditivity(boolean)">setting
-the additivity flag</a> to <code>false</code>.</p>
-
-<p>The rules governing appender additivity are summarized below.</p>
-
-<p>
-<a name="additivity"/><table bgcolor="#EEEE99">
-  <tr>
-  <td>
-      <dl>
-	<dt><b>Appender Additivity</b></dt>
 
-	<dd><p>The output of a log statement of logger <i>C</i> will
-	go to all the appenders in <i>C</i> and its ancestors. This is
-	the meaning of the term "appender additivity".</p>
-
-	<p>However, if an ancestor of logger <i>C</i>, say <i>P</i>,
-	has the additivity flag set to <code>false</code>, then
-	<i>C</i>'s output will be directed to all the appenders in
-	<i>C</i> and its ancestors upto and including <i>P</i> but
-	not the appenders in any of the ancestors of <i>P</i>.</p>
-
-	<p>Loggers have their additivity flag set to
-	<code>true</code> by default.</p></dd>
-      </dl></td></tr>
-</table></p>
-
-
-<p>The table below shows an example:</p>
-
-<p><table align="center" border="3" cellpadding="10">
-  <tr rowspan="2">
-  <th>Logger<br/>Name </th><th>Added<br/>Appenders</th> <th>Additivity<br/>Flag</th> <th>Output Targets</th> <th>Comment</th>
-  </tr>
-<tr><td>root    </td><td>A1         </td><td>not applicable </td><td>A1</td>
-
-    <td>The root logger is anonymous but can be accessed with the
-        Logger.getRootLogger() method. There is no default appender
-        attached to root.</td></tr>
-
-<tr><td>x       </td><td>A-x1, A-x2 </td><td>true </td><td>A1, A-x1, A-x2</td>
-    <td>Appenders of "x" and root.</td></tr>
-
-<tr><td>x.y     </td><td>none       </td><td>true </td><td>A1, A-x1, A-x2</td>
-    <td>Appenders of "x" and root.</td></tr>
-
-<tr><td>x.y.z   </td><td>A-xyz1     </td><td>true </td><td>A1, A-x1, A-x2, A-xyz1</td>
-    <td>Appenders in "x.y.z", "x" and root.</td></tr>
-
-<tr><td>security        </td><td>A-sec	   </td><td><font color="blue">false</font></td>
-                                           <td>A-sec</td>
-
-    <td>No appender accumulation since the additivity flag is set to
-        <code>false</code>.</td></tr>
-
-<tr><td>security.access </td><td>none </td><td> true </td><td> A-sec </td><td>Only
-    appenders of "security" because the additivity flag in "security" is
-    set to <code>false</code>.</td></tr>
-
-</table>
-
-
-<p>More often than not, users wish to customize not only the output
-destination but also the output format. This is accomplished by
-associating a <em>layout</em> with an appender. The layout is
-responsible for formatting the logging request according to the user's
-wishes, whereas an appender takes care of sending the formatted output
-to its destination.</p>
-
-The <a
-href="apidocs/org/apache/log4j/PatternLayout.html">PatternLayout</a>, part
-of the standard log4j distribution, lets the user specify the output
-format according to conversion patterns similar to the C language
-<code>printf</code> function.</p>
-
-<p>For example, the PatternLayout with the conversion pattern "%r [%t]
-%-5p %c - %m%n" will output something akin to:<br/>
+<h3>Copy Win32 version of jni_md.h for NTEventLogAppender.dll</h3>
 
 <pre>
-176 [main] INFO  org.foo.Bar - Located nearest gas station.
-</pre></p>
-
-<p>The first field is the number of milliseconds elapsed since the
-start of the program.  The second field is the thread making the log
-request.  The third field is the level of the log statement. The
-fourth field is the name of the logger associated with the log
-request. The text after the '-' is the message of the statement.</p>
-
-<p>Just as importantly, log4j will render the content of the log
-message according to user specified criteria. For example, if you
-frequently need to log <code>Oranges</code>, an object type used in
-your current project, then you can register an
-<code>OrangeRenderer</code> that will be invoked whenever an orange
-needs to be logged.</p>
-
-<p>Object rendering follows the class hierarchy. For example, assuming
-oranges are fruits, if you register a <code>FruitRenderer</code>, all
-fruits including oranges will be rendered by the
-<code>FruitRenderer</code>, unless of course you registered an orange
-specific <code>OrangeRenderer</code>.</p>
-
-<p>Object renderers have to implement the
-<a href="apidocs/org/apache/log4j/or/ObjectRenderer.html">ObjectRenderer</a>
-interface.</p>
-
-
-<h2>Configuration</h2>
-
-<p>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.</p>
-
-<p>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.</p>
-
-<p>Let us give a taste of how this is done with the help of an
-imaginary application <code>MyApp</code> that uses log4j.</p>
-
-<p><table bgcolor="CCCCCC"><tr><td>
-<pre>
- import com.foo.Bar;
-
- // Import log4j classes.
- <b>import org.apache.log4j.Logger;
- import org.apache.log4j.BasicConfigurator;</b>
-
- public class MyApp {
-
-   // Define a static logger variable so that it references the
-   // Logger instance named "MyApp".
-   <strong>static</strong> Logger logger = <strong>Logger.getLogger(MyApp.class);</strong>
-
-   public static void main(String[] args) {
-
-     // Set up a simple configuration that logs on the console.
-     <strong>BasicConfigurator.configure();</strong>
+c:\>cd "\Program Files\Java\jdk_1.6.0_16\include\win32
+c:\>scp jni_md.h username@hostname:
 
-     logger.info("Entering application.");
-     Bar bar = new Bar();
-     bar.doIt();
-     logger.info("Exiting application.");
-   }
- }
+$> export JNI_WIN32_INCLUDE_DIR=/home/username
 </pre>
-</td></tr>
-</table></p>
 
-<p><code>MyApp</code> begins by importing log4j related classes.  It
-then defines a static logger variable with the name
-<code>MyApp</code> which happens to be the fully qualified name of the
-class.</p>
+<h3>Signing &amp; Deploying</h3>
 
-<p><code>MyApp</code> uses the <code>Bar</code> class defined in the
-package <code>com.foo</code>.</p>
+<p>Create a local ssh key with no passphrase to enable 
+"deployment" of site back to the local machine using scp.</p>
 
-<p><table bgcolor="CCCCCC"><tr><td>
 <pre>
- <b>package com.foo;</b>
- import org.apache.log4j.Logger;
-
- public class Bar {
-   <strong>static</strong> Logger logger = <strong>Logger.getLogger(Bar.class);</strong>
-
-   public void doIt() {
-     logger.debug("Did it again!");
-   }
- }
+$> ssh-keygen
+$> cd ~/.ssh
+$> cat id_rsa.pub >> authorized_keys
+$> ssh localhost
+$> exit
 </pre>
-</td></tr>
-</table></p>
-
-<p>The invocation of the <a
-href="apidocs/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 logger a <a
-href="apidocs/org/apache/log4j/ConsoleAppender.html">
-ConsoleAppender</a>. The output will be formatted using a <a
-href="apidocs/org/apache/log4j/PatternLayout.html">PatternLayout</a> set
-to the pattern "%-4r [%t] %-5p %c %x - %m%n".</p>
-
-<p>Note that by default, the root logger is assigned to
-<code>Level.DEBUG</code>.</p>
 
-<p>The output of MyApp is:
-<pre>
-0    [main] INFO  MyApp  - Entering application.
-36   [main] DEBUG com.foo.Bar  - Did it again!
-51   [main] INFO  MyApp  - Exiting application.
-</pre></p>
-
-<p>The figure below depicts the object diagram of <code>MyApp</code>
-after just having called the <code>BasicConfigurator.configure</code>
-method.</p>
-
-<p>
-<center>
-<img src="images/od.gif" align="center" />
-</center></p>
-
-<p>As a side note, let me mention that in log4j child loggers link
-only to their existing ancestors. In particular, the logger named
-<code>com.foo.Bar</code> is linked directly to the <code>root</code>
-logger, thereby circumventing the unused <code>com</code> or
-<code>com.foo</code> loggers. This significantly increases
-performance and reduces log4j's memory footprint.</p>
-
-
-<p>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.Logger</code> class,
-retrieve the loggers they wish to use, and log away.</p>
-
-<p>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.</p>
+<p>It's important to add localhost and people.a.o to the list of permanent allowed hosts.
+Besides the above, this should have been runned at least once:</p>
 
-<p><table bgcolor="CCCCCC"><tr><td>
 <pre>
- import com.foo.Bar;
-
- import org.apache.log4j.Logger;
- <b>import org.apache.log4j.PropertyConfigurator;</b>
-
- public class MyApp {
-
-   static Logger logger = Logger.getLogger(MyApp.class.getName());
-
-   public static void main(String[] args) {
-
-
-     // BasicConfigurator replaced with PropertyConfigurator.
-     <strong>PropertyConfigurator.configure(args[0]);</strong>
-
-     logger.info("Entering application.");
-     Bar bar = new Bar();
-     bar.doIt();
-     logger.info("Exiting application.");
-   }
- }
+$> ssh people.apache.org
 </pre>
-</td></tr>
-</table>
-
-<p>This version of <code>MyApp</code> instructs
-<code>PropertyConfigurator</code> to parse a configuration file and
-set up logging accordingly.</p>
 
-<p>Here is a sample configuration file that results in identical
-output as the previous <code>BasicConfigurator</code> based example.</p>
+<p>If you intended to deploy jars to the repo or update the site,
+you need to set up ssh to use private keys to access people.apache.org
+and create or modify ~/.m2/settings.xml to specify user name and key location.
+</p>
 
-<p><table bgcolor="CCAAAA"><tr><td>
 <pre>
-# Set root logger level to DEBUG and its only appender to A1.
-log4j.rootLogger=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
+&lt;settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 
+              http://maven.apache.org/xsd/settings-1.0.0.xsd"&gt;
+   &lt;servers&gt;
+    &lt;server&gt;
+      &lt;id&gt;logging.repo&lt;/id&gt;
+      &lt;username&gt;USERNAME for people.apache.org&lt;/username&gt;
+      &lt;privateKey&gt;/home/username/.ssh/id_rsa&lt;/privateKey&gt;
+      &lt;passphrase&gt;&lt;/passphrase&gt;
+    &lt;/server&gt;
+   &lt;/servers&gt;
+&lt;/settings&gt;
 </pre>
-</td></tr></table></p>
-<!-- <p>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.
--->
-
-<p>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.</p>
 
-<p><table bgcolor="CCAAAA"><tr><td>
-<pre>
-log4j.rootLogger=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 level WARN or above in the package com.foo.
-<strong>log4j.logger.com.foo=WARN</strong>
-</pre>
-</td></tr></table></p>
-
-<p>The output of <code>MyApp</code> configured with this file is shown below.</p>
+<p>You should test your ssh connection to people.apache.org 
+and localhost before attempting a deployment like:</p>
 
 <pre>
-<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.
+$ ssh -l USERNAME people.apache.org
+$ ssh localhost
 </pre>
 
-<p>As the logger <code>com.foo.Bar</code> does not have an assigned
-level, it inherits its level 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 level DEBUG, lower than the
-logger level WARN. Consequently, <code>doIt()</code> method's log
-request is suppressed.</p>
+<h2>Building release artifacts</h2>
 
-<p>Here is another configuration file that uses multiple appenders.</p>
+<p>Before you build, please make sure you have a nonblocking editor set as SVN editor. Like:</p>
 
-<p><table bgcolor="CCAAAA"><tr><td>
 <pre>
-log4j.rootLogger=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
+$ export SVN_EDITOR=xemacs
 </pre>
-</td></tr></table></p>
-
-<p>Calling the enhanced MyApp with the this configuration file will
-output the following on the console.</p>
-
-<pre>
- INFO [main] <strong>(MyApp2.java:12)</strong> - Entering application.
-DEBUG [main] (Bar.java:8) - Doing it again!
- INFO [main] (MyApp2.java:15) - Exiting application.
-</pre></p>
-
-<p>In addition, as the root logger 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>.</p>
-
-<p>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.</p>
-
-<a name="defaultInit"/><h2>Default Initialization Procedure</h2>
-
-<p>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>Logger</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.</p>
-
-<p>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.</p>
-
-<p>The exact default initialization algorithm is defined as follows:</p>
-
-<ol>
-
- <li>Setting the <b>log4j.defaultInitOverride</b> system property to
- any other value then "false" will cause log4j to skip the default
- initialization procedure (this procedure).</li>
-
- <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 through 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".</li>
-
- <li>Attempt to convert the <code>resource</code> variable to a
- URL.</li>
-
- <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,
- Logger.class)</code> which returns a URL.  Note that the string
- "log4j.properties" constitutes a malformed URL.
-
- <p>See <a
- href="apidocs/org/apache/log4j/helpers/Loader.html#getResource(java.lang.String)">Loader.getResource(java.lang.String)</a>
- for the list of searched locations.</p></li>
-
- <li>If no URL could not be found, abort default
- initialization. Otherwise, configure log4j from the URL.
-
- <p>The <a
-  href="apidocs/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="apidocs/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="apidocs/org/apache/log4j/spi/Configurator.html">Configurator</a>
-  interface.</p></li>
-
-</ol>
-
-<h2>Example Configurations</h2>
-
-
-
-<h2>Default Initialization under Tomcat</h2>
-
-<p>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.</p>
-
-<p>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>.</p>
 
-<p><b>Example 1</b></p>
+<p>The release artifacts were originally built by:</p>
 
-<p>The Unix shell command
 <pre>
-   export TOMCAT_OPTS="-Dlog4j.configuration=foobar.txt"
+$> svn co http://svn.apache.org/repos/asf/logging/log4j/trunk log4j
+$> cd log4j
+$> mvn package release:prepare
+$> mvn release:perform
 </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="apidocs/org/apache/log4j/PropertyConfigurator.html">PropertyConfigurator</a>. Each
-web-application will use a different default configuration file because
-each file is relative to a web-application.</p>
+<p>Note: you'll be ask for a SVN tagname. Please use the following pattern: v1.2.17-RC1.</p>
 
+<p>
+Attention: this is an non-interactive build. In some cases it is necessary
+to add: -Dusername=paouser -Dpassword=paopassword 
+to the release plugin commands. This is surely not safe because your password
+can be seen clearly. 
+</p>
 
-<p><b>Example 2</b></p>
+<p>The release artifacts can be rebuilt by:</p>
 
-<p>The Unix shell command
 <pre>
-   export TOMCAT_OPTS="-Dlog4j.debug -Dlog4j.configuration=foobar.xml"
+$ mvn release:perform -DconnectionUrl=scm:svn:https://svn.apache.org/repos/asf/logging/log4j/tags/v1_2_16
 </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="apidocs/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.</p>
-
-<p><b>Example 3</b></p>
+<p>Building site and artifacts from a tag:</p>
 
-<p>The Windows shell command
 <pre>
-   set TOMCAT_OPTS=-Dlog4j.configuration=foobar.lcf -Dlog4j.configuratorClass=com.foo.BarConfigurator
+$ svn co https://svn.apache.org/repos/asf/logging/log4j/tags/v1_2_16
+$ cd v1_2_16
+$ mvn site assembly:assembly
 </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 definition of the <b>log4j.configuratorClass</b> system property,
-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.</p>
-
-<p><b>Example 4</b></p>
+<p>TODO: the following section describes site staging. This must be altered: the staging must not happen in SVN.</p>
 
-<p>The Windows shell command
-<pre>
-   set TOMCAT_OPTS=-Dlog4j.configuration=file:/c:/foobar.lcf</pre>
+<p>
+The website content will automatically be staged to the ASF SVN repo by "mvn site-deploy".
+This phase checks out https://svn.apache.org/repos/asf/logging/site/trunk/docs/log4j/1.2 
+into target/site-deploy, copys the generated documentation to that directory using
+scp to localhost and then commits the changed content.  You will be prompted for an
+SVN commit message using the configured SVN_EDITOR.  A commit message must be entered or the
+site commit will be aborted.
+</p>
 
-tells log4j to use the file <code>c:\foobar.lcf</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.</p>
+<p>
+The staged content can be tested by opening 
+http://svn.apache.org/repos/asf/logging/site/trunk/docs/1.2/index.html, 
+however some links may be broken due to the staged location.  
+The staged version can be published to the main public site by executing 
+"svn update" in /www/logging.apache.org/log4j/1.2 on people.apache.org.
+</p>
 
+<h2>If a vote has failed</h2>
 
-<p>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.</p>
+<p>Delete the RC artifacts from:<pre>http://people.apache.org/builds/logging/repo/log4j/log4j/</pre></p>
 
 
-<p><b>Initialization servlet</b></p>
+<h2>If a vote has passed</h2>
 
-<p>It is also possible to use a special servlet for log4j
-initialization. Here is an example,</p>
+<p>If a RC has passed the vote, these steps are necessary:</p>
 
-<p><table bgcolor="CCCCCC"><tr><td>
+<p>Rename the tag:</p>
 <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) {
-  }
-}
+$> svn mv https://svn.apache.org/repos/asf/logging/log4j/tags/log4j-1.2.17-RC1 https://svn.apache.org/repos/asf/logging/log4j/tags/log4j-1.2.17
 </pre>
-</td></tr></table></p>
-
-<p>Define the following servlet in the web.xml file for your web-application.</p>
 
-<p><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;
+<p>Change the pom.xml version to the prior version number.</p>
 
-    <b>&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;</b>
-  &lt;/servlet&gt;
-</pre>
-</td></tr></table></p>
-
-<p>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.</p>
-
-
-
-<h2> Nested Diagnostic Contexts</h2>
-
-<p>Most real-world systems have to deal with multiple clients
-simultaneously. In a typical multithreaded implementation of such a
-system, different threads will handle different clients. Logging is
-especially well suited to trace and debug complex distributed
-applications. A common approach to differentiate the logging output of
-one client from another is to instantiate a new separate logger for
-each client. This promotes the proliferation of loggers and
-increases the management overhead of logging.</p>
-
-<p>A lighter technique is to uniquely stamp each log request initiated
-from the same client interaction. Neil Harrison described this method
-in the book "Patterns for Logging Diagnostic Messages," in <em>Pattern
-Languages of Program Design 3</em>, edited by R. Martin, D.  Riehle,
-and F. Buschmann (Addison-Wesley, 1997).</p>
-
-
-
-<p> To uniquely stamp each request, the
-user pushes contextual information into the NDC, the abbreviation of
-<em>Nested Diagnostic Context</em>. The NDC class is shown below.
-
-<pre>
-  public class NDC {
-    // Used when printing the diagnostic
-    public <strong>static</strong> String get();
-
-    // Remove the top of the context from the NDC.
-    public <strong>static</strong> String pop();
-
-    // Add diagnostic context for the current thread.
-    public <strong>static</strong> void push(String message);
-
-    // Remove the diagnostic context for this thread.
-    public <strong>static</strong> void remove();
-  }
-</pre></p>
-
-<p>The NDC is managed per thread as a <em>stack</em> of contextual
-information. Note that all methods of the <code>org.apache.log4j.NDC</code>
-class are static. Assuming that NDC printing is turned on, every time
-a log request is made, the appropriate log4j component will include
-the <em>entire</em> NDC stack for the current thread in the log
-output. This is done without the intervention of the user, who is
-responsible only for placing the correct information in the NDC by
-using the <code>push</code> and <code>pop</code> methods at a few
-well-defined points in the code.  In contrast, the per-client logger
-approach commands extensive changes in the code.</p>
-
-<p>To illustrate this point, let us take the example of a servlet
-delivering content to numerous clients. The servlet can build the NDC
-at the very beginning of the request before executing other code. The
-contextual information can be the client's host name and other
-information inherent to the request, typically information contained
-in cookies. Hence, even if the servlet is serving multiple clients
-simultaneously, the logs initiated by the same code, i.e. belonging to
-the same logger, can still be distinguished because each client
-request will have a different NDC stack. Contrast this with the
-complexity of passing a freshly instantiated logger to all code
-exercised during the client's request.</p>
-
-<p>Nevertheless, some sophisticated applications, such as virtual
-hosting web servers, must log differently depending on the virtual
-host context and also depending on the software component issuing the
-request. Recent log4j releases support multiple hierarchy trees. This
-enhancement allows each virtual host to possess its own copy of the
-logger hierarchy.</p>
-
-
-<a name="performance"/><h2>Performance</h2>
-
-<p>One of the often-cited arguments against logging is its
-computational cost. This is a legitimate concern as even moderately
-sized applications can generate thousands of log requests.  Much
-effort was spent measuring and tweaking logging performance. Log4j
-claims to be fast and flexible: speed first, flexibility second.</p>
-
-<p>The user should be aware of the following performance issues.</p>
-
-<ol>
-  <li><b>Logging performance when logging is turned off.</b><br/>
-
-   <p>When logging is turned
-   off entirely or just for a <a
-   href="apidocs/org/apache/log4j/Hierarchy.html#setThreshold(java.lang.String)">set
-   of levels</a>, the cost of a log request consists of a method
-   invocation plus an integer comparison.  On a 233 MHz Pentium II
-   machine this cost is typically in the 5 to 50 nanosecond range.</p>
-
-   <p>However, The method invocation involves the "hidden" cost of
-   parameter construction.</p>
-
-   <p>For example, for some logger <code>cat</code>, writing,
-    <pre>
-     logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
-    </pre>
-
-      incurs the cost of constructing the message parameter, i.e.
-      converting both integer <code>i</code> and <code>entry[i]</code>
-      to a String, and concatenating intermediate strings,
-      regardless of whether the message will be logged or not.
-
-      This cost of parameter construction can be quite high and it
-      depends on the size of the parameters involved.</p>
-
-
-      <p>To avoid the parameter construction cost write:
-    <pre>
-      if(logger.isDebugEnabled() {
-        logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
-      }
-   </pre></p>
-
-      <p>This will not incur the cost of parameter
-      construction if debugging is disabled.  On the other hand, if
-      the logger is debug-enabled, it will incur twice the cost of
-      evaluating whether the logger is enabled or not: once
-      in <code>debugEnabled</code> and once in
-      <code>debug</code>. This is an insignificant
-      overhead because evaluating a logger takes about 1%
-      of the time it takes to actually log.</p>
-
-   <p>In log4j, logging requests are made to instances of the Logger
-   class. Logger is a class and not an interface. This measurably
-   reduces the cost of method invocation at the cost of some
-   flexibility.</p>
-
-
-   <p>Certain users resort to preprocessing or compile-time
-   techniques to compile out all log statements. This leads to perfect
-   performance efficiency with respect to logging. However, since the
-   resulting application binary does not contain any log statements,
-   logging cannot be turned on for that binary. In my opinion this is
-   a disproportionate price to pay in exchange for a small performance
-   gain.</p></li>
-
-   <li><b>The performance of deciding whether to log or not to log when
-       logging is turned on.</b><br/>
-
-   <p>This is essentially the performance of walking the logger
-   hierarchy. When logging is turned on, log4j still needs to compare
-       the level of the log request with the level of the request
-   logger. However, loggers may not have an assigned
-   level; they can inherit them from the logger hierarchy. Thus,
-   before inheriting a level, the logger may need to search its
-   ancestors.</p>
-
-   <p>There has been a serious effort to make this hierarchy walk to
-be as fast as possible. For example, child loggers link only to
-their existing ancestors. In the <code>BasicConfigurator</code>
-example shown earlier, the logger named <code>com.foo.Bar</code> is
-linked directly to the root logger, thereby circumventing the
-nonexistent <code>com</code> or <code>com.foo</code> loggers. This
-significantly improves the speed of the walk, especially in "sparse"
-hierarchies.</p>
-
-       <p>The typical cost of walking the hierarchy is typically 3
-       times slower than when logging is turned off entirely.</p></li>
-
-   <li><b>Actually outputting log messages</b><br/>
-
-   <p>This is the cost of formatting the log output and sending it to
-   its target destination. Here again, a serious effort was made to
-   make layouts (formatters) perform as quickly as possible. The same
-   is true for appenders. The typical cost of actually logging is
-   about 100 to 300 microseconds.</p>
-
-   See <a
-   href="apidocs/org/apache/log4j/performance/Logging.html">org.apache.log4.performance.Logging</a>
-   for actual figures.
-   </li>
-
-</ol>
-
-<p>Although log4j has many features, its first design goal was speed.
-Some log4j components have been rewritten many times to improve
-performance.  Nevertheless, contributors frequently come up with new
-optimizations. You should be pleased to know that when configured with
-the <a
-href="apidocs/org/apache/log4j/SimpleLayout.html">SimpleLayout</a>
-performance tests have shown log4j to log as quickly as
-<code>System.out.println</code>.</p>
-
-<h2>Conclusions</h2>
-
-<p>Log4j is a popular logging package written in Java.  One of its
-distinctive features is the notion of inheritance in loggers. Using
-a logger hierarchy it is possible to control which log statements
-are output at arbitrary granularity. This helps reduce the volume of
-logged output and minimize the cost of logging.</p>
-
-<p>One of the advantages of the log4j API is its manageability. Once
-the log statements have been inserted into the code, they can be
-controlled with configuration files. They can be selectively enabled
-or disabled, and sent to different and multiple output targets in
-user-chosen formats. The log4j package is designed so that log
-statements can remain in shipped code without incurring a heavy
-performance cost.</p>
-
-<h2>Acknowledgments</h2>
-
-Many thanks to N. Asokan for reviewing the article. He is also one of
-the originators of the logger concept. I am indebted to Nelson Minar
-for encouraging me to write this article. He has also made many useful
-suggestions and corrections to this article. Log4j is the result of a
-collective effort. My special thanks go to all the authors who have
-contributed to the project.  Without exception, the best features in
-the package have all originated in the user community.
 </section>
 </body>
 </document>
\ No newline at end of file



Mime
View raw message