ceki 01/09/09 13:20:27 Modified: src/docbook architecture.xml manual.xml Log: The architecture chapter now cleanly "compiles". Revision Changes Path 1.2 +632 -424 jakarta-log4j/src/docbook/architecture.xml Index: architecture.xml =================================================================== RCS file: /home/cvs/jakarta-log4j/src/docbook/architecture.xml,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- architecture.xml 2001/09/08 17:57:38 1.1 +++ architecture.xml 2001/09/09 20:20:26 1.2 @@ -1,40 +1,42 @@ -<chapter> + <chapter> <title>Logger, Appenders and Layouts</title> - - <para>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 priority, and to control at - runtime how these messages are formatted and where they are - reported. + + <para>Log4j has three main components: + <emphasis>loggers</emphasis>, <emphasis>appenders</emphasis> and + <emphasis>layouts</emphasis>. These three types of components + work together to enable developers to log messages according to + message type and priority, and to control at runtime how these + messages are formatted and where they are reported. </para> - - <sect1>Logger hierarchy</sect1> - <para>The first and foremost advantage of any logging API over - plain <function>System.out.println</function> 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. </para> - - <para>This observation had previously led us to choose - <emphasis>category</emphasis> as the central concept of the - package. However, since log4j version 1.2, <ulink - url="api/org/apache/log4j/Logger.html">Logger</ulink> - <classname>Logger</classname> class has replaced the - <classname>Category</classname> class. - + <sect1> + <title>Logger hierarchy</title> - <para>Loggers are named entities. Logger names are - case-sensitive and they follow the hierarchical naming rule: + <para>The first and foremost advantage of any logging API over + plain <function>System.out.println</function> 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. </para> + + <para>This observation had previously led us to choose + <emphasis>category</emphasis> as the central concept of the + package. However, since log4j version 1.2, <ulink + url="api/org/apache/log4j/Logger.html">Logger</ulink> + <classname>Logger</classname> class has replaced the + <classname>Category</classname> class. </para> + + <para>Loggers are named entities. Logger names are + case-sensitive and they follow the hierarchical naming rule: + </para> + <para> <variablelist> <varlistentry> - <term><emphasis rule="bold">Named Hierarchy Rule</emphasis></term> - + <term><emphasis role="strong">Named Hierarchy Rule</emphasis></term> + <listitem> <para>A category is said to be an <emphasis>ancestor</emphasis> of another category if @@ -49,424 +51,630 @@ </varlistentry> </variablelist> </para> - </para> - + -<para>For example, the category named <code>"com.foo"</code> is a parent -of the category 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. - -<para>The root category resides at the top of the category hierarchy. It -is exceptional in two ways: - -<ol> -<li> it always exists, -<li> it cannot be retrieved by name. -</ol> -<para>Invoking the class static <a -href="api/org/apache/log4j/Category.html#getRoot()">Category.getRoot</a> -method retrieves it. All other categories are instantiated and -retrieved with the class static <a -href="api/org/apache/log4j/Category.html#getRoot()">Category.getInstance</a> -method. This method takes the name of the desired category as a -parameter. Some of the basic methods in the Category class are listed -below. - -<para><table> -<tr bgcolor="CCCCCC"> -<td> -<pre> - package org.apache.log4j; + <para>For example, the logger named + <classname>"com.foo"</classname> is a parent of the category + named <classname>"com.foo.Bar"</classname>. Similarly, + <classname>"java"</classname> is a parent of + <classname>"java.util"</classname> and an ancestor of + <classname>"java.util.Vector"</classname>. This naming scheme + should be familiar to most developers. + </para> + + <para>The root logger resides at the top of the category + hierarchy. It is exceptional in two ways: + </para> + + <para> + <itemizedlist> + <listitem><para>it always exists,</para></listitem> + <listitem><para>it cannot be retrieved by name.</para></listitem> + </itemizedlist> + </para> + + <para>Invoking the class static <ulink + url="../api/org/apache/log4j/Logger.html#getRootLogger()">Logger.getRootLogger</ulink> + method retrieves it. All other logger are instantiated and + retrieved with the class static <ulink + url="../api/org/apache/log4j/Logger.html#geLogger()">Logger.getLogger</ulink> + method. This method takes the name of the desired logger as a + parameter. Some of the basic methods in the + <classname>Logger</classname> class are listed below. + </para> + + <para> + + <programlisting> + package org.apache.log4j; - public <b>Category</b> class { + public <emphasis role="strong">Logger</emphasis> class { - // Creation & retrieval methods: - public static Category getRoot(); - public static Category getInstance(String name); - - // printing methods: - public void debug(Object message); - public void info(Object message); - public void warn(Object message); - public void error(Object message); - - // generic printing method: - public void log(Priority p, Object message); -} -</pre> -</td> -</table> - -<para>Categories <emphasis>may</emphasis> be assigned priorities. The set of possible -priorities, that is - -<a href="api/org/apache/log4j/Priority.html#DEBUG">DEBUG</a>, -<a href="api/org/apache/log4j/Priority.html#INFO">INFO</a>, -<a href="api/org/apache/log4j/Priority.html#WARN">WARN</a>, -<a href="api/org/apache/log4j/Priority.html#ERROR">ERROR</a> and -<a href="api/org/apache/log4j/Priority.html#FATAL">FATAL</a> - -are defined in the <code><a -href="api/org/apache/log4j/Priority.html">org.apache.log4j.Priority</a></code> -class. Although we do not encourage you from doing so, you may define -your own priorities by sub-classing the <code>Priority</code> class. A -perhaps better approach is will be explained later on. - -<para>If a given category is not assigned a priority, then it inherits -one from its closest ancestor with an assigned priority. More -formally: - - -<para> -<table bgcolor="#EEEE99"> - <tr> - <td> - <dl> - <dt><b>Priority Inheritance</b> - - <dd><para>The <emphasis>inherited priority</emphasis> for a given category -<i>C</i>, is equal to the first non-null priority in the category -hierarchy, starting at <i>C</i> and proceeding upwards in the -hierarchy towards the <code>root</code> category. - - </dl> -</table> - -<para>To ensure that all categories can eventually inherit a priority, -the root category always has an assigned priority. - -<para>Below are four tables with various assigned priority values and the -resulting inherited priorities according to the above rule. - -<para> -<table border="1" > - <tr><th>Category<br>name</th><th>Assigned<br>priority</th> - <th>Inherited<br>priority</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> - -<para>In example 1 above, only the root category is assinged a -priority. This priority value, <code>Proot</code>, is inherited by the -other categories <code>X</code>, <code>X.Y</code> and -<code>X.Y.Z</code>. - - -<para> -<table border="1"> - <tr><th>Category<br>name</th><th>Assigned<br>priority</th> - <th>Inherited<br>priority</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> - -<para>In example 2, all categories have an assigned priority value. There -is no need for priority inheritence. - -<para><table border="1"> - <tr><th>Category<br>name</th><th>Assigned<br>priority</th> - <th>Inherited<br>priority</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> - -<para>In example 3, the categories <code>root</code>, <code>X</code> and -<code>X.Y.Z</code> are assigned the priorities <code>Proot</code>, -<code>Px</code> and <code>Pxyz</code> respectively. The category -<code>X.Y</code> inherits its priority value from its parent -<code>X</code>. - -<table border=1> - <tr><th>Category<br>name</th><th>Assigned<br>priority</th> - <th>Inherited<br>priority</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> - -<para>In example 4, the categories <code>root</code> and <code>X</code> -and are assigned the priorities <code>Proot</code> and <code>Px</code> -respectively. The categories <code>X.Y</code> and <code>X.Y.Z</code> -inherits their priority value from their nearest parent <code>X</code> -having an assigned priority.. - - -<para>Logging requests are made by invoking one of the printing methods -of a category instance. These printing methods are - -<code> -<a href="api/org/apache/log4j/Category.html#debug(java.lang.Object)">debug</a>, - -<a href="api/org/apache/log4j/Category.html#info(java.lang.Object)">info</a>, - -<a href="api/org/apache/log4j/Category.html#warn(java.lang.Object)">warn</a>, -<a href="api/org/apache/log4j/Category.html#error(java.lang.Object)">error</a>, -<a href="api/org/apache/log4j/Category.html#fatal(java.lang.Object)">fatal</a> - and <a href="api/org/apache/log4j/Category.html#log(org.apache.log4j.Priority, java.lang.Object)">log</a></code>. - - -<para>By definition, the printing method determines the priority of a -logging request. For example, if <code>c</code> is a category -instance, then the statement <code>c.info("..")</code> is a logging -request of priority INFO. - -<para>A logging request is said to be <emphasis>enabled</emphasis> if its priority is -higher than or equal to the priority of its category. Otherwise, the -request is said to be <emphasis>disabled</emphasis>. A category without an -assigned priority will inherit one from the hierarchy. This rule is -summarized below. - - -<para> -<a name="selectionRule"><table bgcolor="#EEEE99"> - <tr> - <td> - <dl> - <dt><b>Basic Selection Rule</b> - - <dd><para>A log request of priority <i>p</i> in a category with - inherited priority <i>q</i>, is enabled if <i> p >= - q</i>. - </dl> -</table> - -<para>This rule is at the heart of log4j. It assumes that priorities are -ordered. For the standard priorities, we have <code>DEBUG < INFO -< WARN < ERROR < FATAL</code>. - -<para>Here is an example of this rule. - -<para><table bgcolor="CCCCCC"> -<tr><td> -<pre> + // Creation & retrieval methods: + public static Category getRoot(); + public static Category getInstance(String name); + + // printing methods: + public void debug(Object message); + public void info(Object message); + public void warn(Object message); + public void error(Object message); + + // generic printing method: + public void log(Priority p, Object message); + } + + </programlisting> + </para> + + <para>Loggers <emphasis>may</emphasis> be assigned levels. The + set of possible levels, that is + + <ulink url="../api/org/apache/log4j/Level.html#DEBUG">DEBUG</ulink>, + <ulink url="../api/org/apache/log4j/Level.html#INFO">INFO</ulink>, + <ulink url="../api/org/apache/log4j/Level.html#WARN">WARN</ulink>, + <ulink url="../api/org/apache/log4j/Level.html#ERROR">ERROR</ulink> and + <ulink url="../api/org/apache/log4j/Level.html#FATAL">FATAL</ulink> + + are defined in the <ulink + url="../api/org/apache/log4j/Level.html">org.apache.log4j.Level</ulink> + class. Although we do not encourage it, you may define your + own levels by sub-classing the <classname>Level</classname> + class. Possibly a better approach is will be explained later + on. + </para> + + <para>The <emphasis>effective level</emphasis> of logger is + given by its assigned level. In case the logger has not been + assigned a level, then it inherits the level of its closest + ancestor with an assigned priority. More formally: + </para> + + + <para id="inheritanceRule"> + <variablelist> + <varlistentry> + <term><emphasis role="strong">Effective level of a Logger</emphasis></term> + + <listitem> + <para>The <emphasis>effective level</emphasis> of a given + logger <emphasis>L</emphasis>, is equal to the first + non-null level in the logger hierarchy, starting at + <emphasis>L</emphasis> and proceeding upwards in the + hierarchy towards the root category. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + + <para>To ensure that all loggers can eventually inherit a level, + the root logger always has an assigned priority.</para> + + <para>Below are four tables with various assigned levels and the + resulting effective levels according to the above rule.</para> + + <para> + <table> + <title>Example 1</title> + <tgroup cols="3" align="left"> + <thead> + <row> + <entry>Logger name</entry> + <entry>Assigned level</entry> + <entry>Effective level</entry> + </row> + </thead> + + <tbody> + <row> + <entry>root</entry> + <entry>DEBUG</entry> + <entry>DEBUG</entry></row> + + <row> + <entry>X </entry> + <entry>none</entry> + <entry>DEBUG</entry> + </row> + + <row> + <entry>X.Y </entry> + <entry>none</entry> + <entry>DEBUG</entry> + </row> + <row> + <entry>X.Y.Z</entry> + <entry>none</entry> + <entry>DEBUG</entry> + </row> + </tbody> + </tgroup> + </table> + </para> + + <para>In example 1 above, only the root logger is assigned a + level. This level, <varname>DEBUG</varname>, is inherited by + the other loggers <varname>X</varname>, <varname>X.Y</varname> + and <varname>X.Y.Z</varname>. + </para> + + + <para> + <table> + <title>Example 2</title> + <tgroup cols="3" align="left"> + <thead> + <row> + <entry>Logger name</entry> + <entry>Assigned level</entry> + <entry>Effective level</entry> + </row> + </thead> + <tbody> + + <row> + <entry>root</entry> + <entry>DEBUG</entry> + <entry>DEBUG</entry> + </row> + <row> + <entry>X </entry> + <entry>ERROR</entry> + <entry>ERROR</entry> + </row> + <row> + <entry>X.Y </entry> + <entry>INFO</entry> + <entry>INFO</entry> + </row> + <row> + <entry>X.Y.Z</entry> + <entry>DEBUG</entry> + <entry>DEBUG</entry> + </row> + </tbody> + </tgroup> + </table> + </para> + + <para>In example 2, all loggers have an assigned level. There is + no need for level inheritence.</para> + + <para> + <table> + <title>Example 3</title> + <tgroup cols="3" align="left"> + <thead> + <row> + <entry>Logger name</entry> + <entry>Assigned level</entry> + <entry>Effective level</entry> + </row> + </thead> + + <tbody> + <row> + <entry>root</entry> + <entry>INFO</entry> + <entry>INFO</entry></row> + <row> + <entry>X </entry> + <entry>DEBUG</entry> + <entry>DEBUG</entry></row> + <row> + <entry>X.Y </entry> + <entry>none</entry> + <entry>DEBUG</entry></row> + <row> + <entry>X.Y.Z</entry> + <entry>WARN</entry> + <entry>WARN</entry> + </row> + </tbody> + </tgroup> + </table> + </para> + + <para>In example 3, the loggers <varname>root</varname>, + <varname>X</varname> and <varname>X.Y.Z</varname> are + assigned the priorities <varname>INFO</varname>, + <varname>DEBUG</varname> and <varname>WARN</varname> + respectively. The logger <varname>X.Y</varname> inherits + its level value <varname>DEBUG</varname> from its parent + <varname>X</varname>. + </para> + + <table> + <title>Example 4</title> + <tgroup cols="3"> + <thead> + <row> + <entry>Logger name</entry> + <entry>Assigned level</entry> + <entry>Effective level</entry> + </row> + </thead> + + <tbody> + + <row><entry>root</entry> + <entry>DEBUG</entry> <entry>DEBUG</entry> + </row> + <row> + <entry>X </entry> + <entry>ERROR</entry> + <entry>DEBUG</entry> + </row> + <row> + <entry>X.Y </entry> + <entry>none</entry> + <entry>DEBUG</entry> + </row> + <row> + <entry>X.Y.Z</entry> + <entry>none</entry> + <entry>DEBUG</entry></row> + </tbody> + </tgroup> + </table> + + <para>In example 4, the categories <varname>root</varname> and + <varname>X</varname> and are assigned the priorities + <varname>Proot</varname> and <varname>DEBUG</varname> + respectively. The categories <varname>X.Y</varname> and + <varname>X.Y.Z</varname> inherits their priority value from their + nearest parent <varname>X</varname> having an assigned priority.. + </para> - // get a category instance named "com.foo" - Category cat = Category.getInstance(<strong>"com.foo"</strong>); + <para>Logging requests are made by invoking one of the + printing methods of a logger instance. These printing + methods are + + <ulink url="../api/org/apache/log4j/Category.html#debug(java.lang.Object)">debug</ulink>, + + <ulink url="../api/org/apache/log4j/Category.html#info(java.lang.Object)">info</ulink>, + + <ulink + url="../api/org/apache/log4j/Category.html#warn(java.lang.Object)">warn</ulink>, + <ulink + url="../api/org/apache/log4j/Category.html#error(java.lang.Object)">error</ulink>, + <ulink + url="../api/org/apache/log4j/Category.html#fatal(java.lang.Object)">fatal</ulink> + and <ulink + url="../api/org/apache/log4j/Category.html#log(org.apache.log4j.Priority, + java.lang.Object)">log</ulink>. + </para> + + + <para>By definition, the printing method determines the level of + a logging request. For example, if <varname>l</varname> is a + logger instance, then the statement + <function>l.info("..")</function> is a logging request of + priority INFO. + </para> + + <para>A logging request is said to be + <emphasis>enabled</emphasis> if its level is higher than or + equal to the level of its logger. Otherwise, the request is + said to be <emphasis>disabled</emphasis>. A logger without an + assigned level will inherit one from the hierarchy. This rule + is summarized below. + </para> + + + <para id="basicSelectionRule"> + <variablelist> + <varlistentry> + <term><emphasis role="strong">Basic Selection Rule</emphasis></term> + + <listitem> + <para>A log request of priority + <emphasis>p</emphasis> in a category with + inherited priority <emphasis>q</emphasis>, is + enabled if <emphasis> p >= q</emphasis>. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + + <para >This rule is at the heart of log4j. It is based on the + ordering of levels. For the standard levels, we the + following order <varname>DEBUG < INFO < WARN < + ERROR < FATAL</varname>. + </para> + + <para>Here is this rule in action.</para> + + <para> + <programlisting> + // get a logger instance named "com.foo" + Logger cat = Logger.getLogger("com.foo"); // Now set its priority. Normally you do not need to set the - // priority of a category progamitcally. This is usually done + // priority of a logger progamitcally. This is usually done // in configuration files. - <strong>cat</strong>.setPriority(<font - color="0000AA"><strong>Priority.INFO</strong></font>); + cat.setLevel(Level.INFO); - Category barcat = Category.getInstance(<strong>"com.foo.Bar"</strong>); + Logger barcat = Logger.getLogger("com.foo.Bar"); - // This request is enabled, because <font color="00AA00"><strong>WARN</strong></font> >= <font color="0000AA"><strong>INFO</strong></font>. - cat.<font color="00AA00"><strong>warn</strong></font>("Low fuel level."); + // This request is enabled, because WARN >= INFO. + cat.warn("Low fuel level."); - // This request is disabled, because <font color="00AA00"><strong>DEBUG</strong></font> < <font color="0000AA"><strong>INFO</strong></font>. - cat.<font color="00AA00"><strong>debug</strong></font>("Starting search for nearest gas station."); + // This request is disabled, because DEBUG < INFO. + cat.debug("Starting search for nearest gas station."); - // The category instance barcat, named "com.foo.Bar", - // will inherit its priority from the category named + // The logger instance barcat, named "com.foo.Bar", + // will inherit its priority from the logger named // "com.foo" Thus, the following request is enabled - // because <font color="00AA00"><strong>INFO</strong></font> >= <font color="0000AA"><strong>INFO</strong></font>. - barcat.<font color="00AA00"><strong>info</strong></font>("Located nearest gas station."); + // because INFO >= INFO. + barcat.info("Located nearest gas station."); - // This request is disabled, because <font color="00AA00"><strong>DEBUG</strong></font> < <font color="0000AA"><strong>INFO</strong></font>. - barcat.<font color="00AA00"><strong>debug</strong></font>("Exiting gas station search"); -</pre> -</table> - -<para>Calling the <code>getInstance</code> method with the same name will -always return a reference to the exact same category object. - -<para>For example, in - -<table bgcolor="CCCCCC"> -<tr><td> -<pre> - Categoty x = Category.getInstance("wombat"); - Categoty y = Category.getInstance("wombat");</pre> -</td> -</table> -<code>x</code> and <code>y</code> refer to <emphasis>exactly</emphasis> the same -category object. - -<para>Thus, it is possible to configure a category 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 categories can be -created and configured in any order. In particular, a "parent" -category will find and link to its descendants even if it is -instantiated after them. - -<para>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. - -<para>Log4j makes it easy to name categories by <emphasis>software -component</emphasis>. This can be accomplished by statically instantiating -a category in each class, with the category name equal to the fully -qualified name of the class. This is a useful and straightforward -method of defining categories. As the log output bears the name of the -generating category, 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 categories. Log4j does not restrict -the possible set of categories. The developer is free to name the -categories as desired. - -<para>Nevertheless, naming categories after the class where they are -located seems to be the best strategy known so far. - -<h2>Appenders and Layouts</h2> - -<para>The ability to selectively enable or disable logging requests based -on their category is only part of the picture. Log4j allows logging -requests to print to multiple destinations. In log4j speak, an output -destination is called an <emphasis>appender</emphasis>. Currently, appenders exist -for the <a href="api/org/apache/log4j/ConsoleAppender.html">console</a>, <a -href="api/org/apache/log4j/FileAppender.html">files</a>, GUI -components, <a -href="api/org/apache/log4j/net/SocketAppender.html">remote socket</a> -servers, <a -href="api/org/apache/log4j/net/JMSAppender.html">JMS</a>, - -<a href="api/org/apache/log4j/nt/NTEventLogAppender.html"> NT -Event Loggers</a>, and remote UNIX <a -href="api/org/apache/log4j/net/SyslogAppender.html">Syslog</a> -daemons. It is also possible to log <a href="api/org/apache/log4j/AsyncAppender.html">asynchronously</a>. - -<para>More than one appender can be attached to a category. + // This request is disabled, because DEBUG < INFO. + barcat.debug("Exiting gas station search"); + </programlisting> + </para> + + <para>Calling the <varname>getLogger</varname> method + with the same name will always return a reference to + the exact same logger object. + </para> -<para>The <a -href="api/org/apache/log4j/Category.html#addAppender(org.apache.log4j.Appender)">addAppender</a> -method adds an appender to a given category. - -<b>Each enabled logging -request for a given category will be forwarded to all the appenders in -that category as well as the appenders higher in the hierarchy.</b> In -other words, appenders are inherited additively from the category -hierarchy. For example, if a console appender is added to the root -category, then all enabled logging requests will at least print on the -console. If in addition a file appender is added to a category, say -<emphasis>C</emphasis>, then enabled logging requests for <emphasis>C</emphasis> and -<emphasis>C</emphasis>'s children will print on a file <emphasis>and</emphasis> on the -console. It is possible to override this default behavior so that -appender accumulation is no longer additive by <a -href="api/org/apache/log4j/Category.html#setAdditivity(boolean)">setting -the additivity flag</a> to <code>false</code>. - -<para>The rules governing appender additivity are summarized below. - -<para> -<a name="additivity"><table bgcolor="#EEEE99"> - <tr> - <td> - <dl> - <dt><b>Appender Additivity</b> - - <dd><para>The output of a log statement of category <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". - - <para>However, if an ancestor of category <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 it's ancestors upto and including <i>P</i> but - not the appenders in any of the ancestors of <i>P</i>. - - <para>Categories have their additivity flag set to - <code>true</code> by default. - </dl> -</table> - - -<para>The table below shows an example: - -<para><table align=center border=3 cellpadding=10> - <tr rowspan="2"> - <th>Category<br>Name <th>Added<br>Appenders <th>Additivity<br>Flag <th>Output Targets <th>Comment - -<tr><td>root <td>A1 <td>not applicable <td>A1 - - <td>The root category is anonymous but can be accessed with the - Category.getRoot() method. There is no default appender - attached to root. - -<tr><td>x <td>A-x1, A-x2 <td>true <td>A1, A-x1, A-x2 - <td>Appenders of "x" and root. - -<tr><td>x.y <td>none <td>true <td>A1, A-x1, A-x2 - <td>Appenders of "x" and root. - -<tr><td>x.y.z <td>A-xyz1 <td>true <td>A1, A-x1, A-x2, A-xyz1 - <td>Appenders in "x.y.z", "x" and root. - -<tr><td>security <td>A-sec <td><font color="blue">false</font> - <td>A-sec - - <td>No appender accumulation since the additivity flag is set to - <code>false</code>. - -<tr><td>security.access <td>none <td> true <td> A-sec <td>Only - appenders of "security" because the additivity flag in "security" is - set to <code>false</code>. - -</table> - - -<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 logging request according to the user's -wishes, whereas an appender takes care of sending the formatted output -to its destination. - -The <a -href="api/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. + <para>For example, in + + <programlisting> + Logger x = Logger.getLogger("wombat"); + Logger y = Logger.getLogger("wombat"); + </programlisting> + + <varname>x</varname> and <varname>y</varname> refer to + <emphasis>exactly</emphasis> the same logger object. + </para> + + <para>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 contrast 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. + </para> + + <para>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 in <xref + linkend="chap-configuration"/>. + </para> -<para>For example, the PatternLayout with the conversion pattern "%r [%t] -%-5p %c - %m%n" will output something akin to: + <para>Log4j makes it easy to name loggers by <emphasis>software + component</emphasis>. 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 impose any + restriction on the name of loggers. The user is free to name + logger as she wishes. + </para> -<pre> + <para>Nevertheless, naming loggers after the class where they + are located seems to be the best strategy known so far.</para> + + </sect1> + + <sect1> + <title>Appenders and Layouts</title> + + <para>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 <emphasis>appender</emphasis>. Currently, appenders exist + for the <ulink + url="../api/org/apache/log4j/ConsoleAppender.html">console</ulink>, + <ulink + url="../api/org/apache/log4j/FileAppender.html">files</ulink>, + GUI components, <ulink + url="../api/org/apache/log4j/net/SocketAppender.html">remote + socket</ulink> servers, <ulink + url="../api/org/apache/log4j/net/JMSAppender.html">JMS</ulink>, + + <ulink + url="../api/org/apache/log4j/nt/NTEventLogAppender.html"> NT + Event Loggers</ulink>, and remote UNIX <ulink + url="../api/org/apache/log4j/net/SyslogAppender.html">Syslog</ulink> + daemons. It is also possible to log <ulink + url="../api/org/apache/log4j/AsyncAppender.html">asynchronously</ulink>. + </para> + + <para>More than one appender can be attached to a logger.</para> + + <para>The <ulink + url="../api/org/apache/log4j/Logger.html#addAppender(org.apache.log4j.Appender)">addAppender</ulink> + method adds an appender to a given logger. + + <emphasis>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.</emphasis> 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 <emphasis>C</emphasis>, then + enabled logging requests for <emphasis>C</emphasis> and + <emphasis>C</emphasis>'s children will print on a file + <emphasis>and</emphasis> on the console. It is possible to + override this default behavior so that appender accumulation + is no longer additive by <ulink + url="../api/org/apache/log4j/Logger.html#setAdditivity(boolean)">setting + the additivity flag</ulink> to <varname>false</varname>. + </para> + + <para>The rules governing appender additivity are summarized below.</para> + + + <para id="additivityRule"> + <variablelist> + <varlistentry> + <term><emphasis role="strong">Appender Additivity</emphasis></term> + + <listitem> + <para>The output of a log statement of logger + <emphasis>C</emphasis> will go to all the appenders in + <emphasis>C</emphasis> and its ancestors. This is the + meaning of the term "appender additivity".</para> + + <para>However, if an ancestor of logger + <emphasis>C</emphasis>, say <emphasis>P</emphasis>, + has the additivity flag set to + <varname>false</varname>, then <emphasis>C</emphasis>'s + output will be directed to all the appenders in + <emphasis>C</emphasis> and it's ancestors upto and + including <emphasis>P</emphasis> but not the appenders + in any of the ancestors of + <emphasis>P</emphasis>.</para> + + <para>Categories have their additivity flag set to + <varname>true</varname> by default.</para> + </listitem> + </varlistentry> + </variablelist> + </para> + + <para>The table below shows an example:</para> + + <table> + <title></title> + <tgroup cols="5"> + <thead> + <row> + <entry>Logger Name</entry> + <entry>Added Appenders</entry> + <entry>Additivity Flag</entry> + <entry>Output Targets </entry> + <entry>Comment</entry> + </row> + </thead> + + <tbody> + <row> + <entry>root</entry> + <entry>A1</entry> + <entry>not applicable</entry> + <entry>A1</entry> + <entry>The root logger is anonymous but can be accessed with the + Logger.getRoot() method. There is no default appender + attached to root. + </entry> + </row> + + <row> + <entry>x</entry> + <entry>A-x1, A-x2</entry> + <entry>true</entry> + <entry>A1, A-x1, A-x2</entry> + <entry>Appenders of "x" and root.</entry> + </row> + + <row> + <entry>x.y</entry> + <entry>none</entry> + <entry>true</entry> + <entry>A1, A-x1, A-x2</entry> + <entry>Appenders of "x" and root.</entry> + </row> + + <row> + <entry>x.y.z</entry> + <entry>A-xyz1</entry> + <entry>true</entry> + <entry>A1, A-x1, A-x2, A-xyz1</entry> + <entry>Appenders in "x.y.z", "x" and root.</entry> + </row> + <row> + <entry>security</entry> + <entry>A-sec</entry> + <entry>false</entry> + <entry>A-sec</entry> + + <entry>No appender accumulation since the additivity flag is set to + <varname>false</varname>. + </entry> + </row> + + <row> + <entry>security.access</entry> + <entry>none</entry> + <entry> true</entry> + <entry> A-sec</entry> + + <entry>Only appenders of "security" because the additivity + flag in "security" is set to <varname>false</varname>.</entry> + </row> + </tbody> + </tgroup> + </table> + + + <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 + logging request according to the user's wishes, whereas an + appender takes care of sending the formatted output to its + destination. </para> + + <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 + similar to the C language <varname>printf</varname> + function. + </para> + + <para>For example, the PatternLayout with the conversion pattern "%r [%t] + %-5p %c - %m%n" will output something akin to:</para> + + <programlisting> 176 [main] INFO org.foo.Bar - Located nearest gas station. -</pre> + </programlisting> -<para>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 priority of the log statement. The -fourth field is the name of the category associated with the log -request. The text after the '-' is the message of the statement. - -<para>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. - -<para>Object rendering follows the class hierarchy. For example, assuming -oranges are fruits, if you register an <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>. - -<para>Object renderers have to implement the -<a href="api/org/apache/log4j/or/ObjectRenderer.html">ObjectRenderer</a> -interface. + <para>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 priority 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.</para> + + <para>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 <varname>Oranges</varname>, an object type used in + your current project, then you can register an + <varname>OrangeRenderer</varname> that will be invoked whenever an orange + needs to be logged. + </para> + <para>Object rendering follows the class hierarchy. For example, + assuming oranges are fruits, if you register an + <varname>FruitRenderer</varname>, all fruits including oranges + will be rendered by the <varname>FruitRenderer</varname>, + unless of course you registered an orange specific + <varname>OrangeRenderer</varname>. + </para> + + <para>Object renderers have to implement the <ulink + url="../api/org/apache/log4j/or/ObjectRenderer.html">ObjectRenderer</ulink> + interface. + </para> + </sect1> + <sect1> <title>Performance</title> <para></para> - </sect1> - + </sect1> </chapter> <!-- 1.5 +1 -1 jakarta-log4j/src/docbook/manual.xml Index: manual.xml =================================================================== RCS file: /home/cvs/jakarta-log4j/src/docbook/manual.xml,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- manual.xml 2001/09/08 17:57:38 1.4 +++ manual.xml 2001/09/09 20:20:26 1.5 @@ -1,7 +1,7 @@ <?xml version='1.0'?> <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" [ <!ENTITY intro SYSTEM "intro.xml"> -<!ENTITY architecture SYSTEM "archiecture.xml"> +<!ENTITY architecture SYSTEM "architecture.xml"> <!ENTITY conf SYSTEM "configuration.xml"> <!ENTITY glo SYSTEM "glossary.xml"> ]> --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]