mcatan      2004/11/03 23:00:51

  Modified:    xdocs/www/manual Introduction.html
  Log:
  added header and footer
  
  Revision  Changes    Path
  1.6       +135 -62   logging-log4cxx/xdocs/www/manual/Introduction.html
  
  Index: Introduction.html
  ===================================================================
  RCS file: /home/cvs/logging-log4cxx/xdocs/www/manual/Introduction.html,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Introduction.html 21 Oct 2004 20:58:03 -0000      1.5
  +++ Introduction.html 4 Nov 2004 07:00:51 -0000       1.6
  @@ -1,10 +1,74 @@
  -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  -<html><head><meta http-equiv="Content-Type" 
content="text/html;charset=iso-8859-1">
  -<title>log4cxx: Short introduction to log4cxx</title>
  -<link href="doxygen.css" rel="stylesheet" type="text/css">
  -</head><body>
  -<!-- Generated by Doxygen 1.3.6 -->
  -<div class="qindex"><a class="qindex" href="main.html">Main&nbsp;Page</a> | 
<a class="qindex" href="modules.html">Modules</a> | <a class="qindex" 
href="hierarchy.html">Class&nbsp;Hierarchy</a> | <a class="qindex" 
href="classes.html">Alphabetical&nbsp;List</a> | <a class="qindex" 
href="annotated.html">Class&nbsp;List</a> | <a class="qindex" 
href="functions.html">Class&nbsp;Members</a> | <a class="qindex" 
href="pages.html">Related&nbsp;Pages</a></div>
  +<html>
  +<head>
  +<title>
  +log4cxx - Documentation
  +</title>
  +<link href="../css/doxygen.css" rel="stylesheet" type="text/css"/>
  +</head>
  +
  +<body bgcolor="#ffffff" text="#000000" link="#525D76">        
  +<!-- START Header table --> 
  +<table border="0" cellspacing="0" width="90%">
  +<!-- TOP IMAGE -->
  +<tr>
  +<td colspan="2">
  +<a href="http://logging.apache.org";>
  +<img src="http://logging.apache.org/images/ls-logo.jpg"; align="left" 
border="0"/>
  +</a>
  +</td>
  +
  +</tr>
  +</table>
  +<!-- END Header table --> 
  +
  +           <!-- START main table --> 
  +            <table id="main" border="0" width="90%" cellspacing="2" 
cellpadding="0">
  +                <tr><td colspan="2">
  +                    <hr noshade="" size="1"/>
  +                </td></tr>
  +                
  +                <tr>
  +                    <!-- LEFT SIDE NAVIGATION -->
  +                    <td id="navbar" valign="top">
  +                      <!-- 
============================================================ -->
  +  <table id="navbar" border="0" cellspacing="0" cellpadding="0">
  +                      <tr >
  +              <td class="navbarHeader" nowrap="true">
  +           <strong>Apache</strong>
  +         </td>
  +       </tr>
  +                      <tr><td class="navbarItem"><small>    <a 
href="http://www.apache.org";>Apache Home</a>
  +</small></td></tr>
  +                      <tr><td class="navbarItem"><small>    <a 
href="http://logging.apache.org/";>Logging Services</a>
  +</small></td></tr>
  +                                <tr >
  +              <td class="navbarHeader" nowrap="true">
  +           <strong>log4cxx project</strong>
  +         </td>
  +       </tr>
  +                      <tr><td class="navbarItem"><small>    <a 
href="../index.html">About</a>
  +</small></td></tr>
  +                      <tr><td class="navbarItem"><small>    <a 
href="../news.html">News</a>
  +</small></td></tr>
  +                      <tr><td class="navbarItem"><small>    <a 
href="../team.html">Team</a>
  +</small></td></tr>
  +                      <tr><td class="navbarItem"><small>    <a 
href="../manual/index.html">Documentation</a>
  +</small></td></tr>
  +                      <tr><td class="navbarItem"><small>    <a 
href="../support.html">Support</a>
  +</small></td></tr>
  +                      <tr><td class="navbarItem"><small>    <a 
href="../contributing.html">Contributing</a>
  +</small></td></tr>
  +                      <tr><td class="navbarItem"><small>    <a 
href="../performance.html">Performance</a>
  +</small></td></tr>
  +                      <tr><td class="navbarItem"><small>    <a 
href="../download.html">Download</a>
  +</small></td></tr>
  +             </table> 
  +   
  +                    </td>
  +                    <td id="mainContents" align="left" valign="top">
  +<hr>
  +<!-- Generated by Doxygen 1.3.5 -->
  +<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | 
<a class="qindex" href="modules.html">Modules</a> | <a class="qindex" 
href="hierarchy.html">Class&nbsp;Hierarchy</a> | <a class="qindex" 
href="classes.html">Alphabetical&nbsp;List</a> | <a class="qindex" 
href="annotated.html">Class&nbsp;List</a> | <a class="qindex" 
href="functions.html">Class&nbsp;Members</a> | <a class="qindex" 
href="pages.html">Related&nbsp;Pages</a></div>
   <h1><a class="anchor" name="Introduction">Short introduction to 
log4cxx</a></h1>This document is largely inspired of the <a 
href="http://logging.apache.org/log4j/docs/manual.html";>Short introduction to 
log4j</a> by <em>Ceki G�lc�</em><h2><a class="anchor" name="Contents">
   Contents</a></h2>
   <ul>
  @@ -41,28 +105,28 @@
   <li>it always exists,</li><li>it cannot be retrieved by name.</li></ol>
   <p>
   Invoking the class static <a class="el" 
href="classlog4cxx_1_1Logger.html#e1">log4cxx::Logger::getRootLogger</a> method 
retrieves it. All other loggers are instantiated and retrieved with the class 
static <a class="el" 
href="classlog4cxx_1_1Logger.html#e0">log4cxx::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>
  -<pre class="fragment"><div> <span class="keyword">namespace </span>log4cxx {
  +<div class="fragment"><pre> <span class="keyword">namespace </span>log4cxx {
       <span class="keyword">typedef</span> std::string String;
  - 
  -    <span class="keyword">class </span><a class="code" 
href="classlog4cxx_1_1Logger.html">Logger</a> {
  +
  +    <span class="keyword">class </span>Logger {
       <span class="keyword">public</span>:
           <span class="comment">// Creation &amp; retrieval methods:</span>
  -        <span class="keyword">static</span> <a class="code" 
href="classlog4cxx_1_1helpers_1_1ObjectPtrT.html">LoggerPtr</a> <a class="code" 
href="classlog4cxx_1_1Logger.html#e1">getRootLogger</a>();
  -        <span class="keyword">static</span> <a class="code" 
href="classlog4cxx_1_1helpers_1_1ObjectPtrT.html">LoggerPtr</a> <a class="code" 
href="classlog4cxx_1_1Logger.html#e0">getLogger</a>(<span 
class="keyword">const</span> String&amp; name);
  - 
  +        <span class="keyword">static</span> LoggerPtr <a class="code" 
href="classlog4cxx_1_1Logger.html#e1">getRootLogger</a>();
  +        <span class="keyword">static</span> LoggerPtr <a class="code" 
href="classlog4cxx_1_1Logger.html#e0">getLogger</a>(<span 
class="keyword">const</span> String&amp; name);
  +
           <span class="comment">// printing methods:</span>
           <span class="keywordtype">void</span> <a class="code" 
href="classlog4cxx_1_1Logger.html#a5">debug</a>(<span 
class="keyword">const</span> String&amp; message, <span 
class="keyword">const</span> <span class="keywordtype">char</span>* file = 0, 
<span class="keywordtype">int</span> line = -1);
           <span class="keywordtype">void</span> <a class="code" 
href="classlog4cxx_1_1Logger.html#a18">info</a>(<span 
class="keyword">const</span> String&amp; message, <span 
class="keyword">const</span> <span class="keywordtype">char</span>* file = 0, 
<span class="keywordtype">int</span> line = -1);
           <span class="keywordtype">void</span> <a class="code" 
href="classlog4cxx_1_1Logger.html#a34">warn</a>(<span 
class="keyword">const</span> String&amp; message, <span 
class="keyword">const</span> <span class="keywordtype">char</span>* file = 0, 
<span class="keywordtype">int</span> line = -1);
           <span class="keywordtype">void</span> <a class="code" 
href="classlog4cxx_1_1Logger.html#a6">error</a>(<span 
class="keyword">const</span> String&amp; message, <span 
class="keyword">const</span> <span class="keywordtype">char</span>* file = 0, 
<span class="keywordtype">int</span> line = -1);
           <span class="keywordtype">void</span> <a class="code" 
href="classlog4cxx_1_1Logger.html#a7">fatal</a>(<span 
class="keyword">const</span> String&amp; message, <span 
class="keyword">const</span> <span class="keywordtype">char</span>* file = 0, 
<span class="keywordtype">int</span> line = -1);
  - 
  +
           <span class="comment">// generic printing method:</span>
  -        <span class="keywordtype">void</span> <a class="code" 
href="classlog4cxx_1_1Logger.html#a27">log</a>(<span 
class="keyword">const</span> <a class="code" 
href="classlog4cxx_1_1helpers_1_1ObjectPtrT.html">LevelPtr</a>&amp; l, <span 
class="keyword">const</span> String&amp; message,
  +        <span class="keywordtype">void</span> <a class="code" 
href="classlog4cxx_1_1Logger.html#a27">log</a>(<span 
class="keyword">const</span> LevelPtr&amp; l, <span 
class="keyword">const</span> String&amp; message,
               <span class="keyword">const</span> <span 
class="keywordtype">char</span>* file = 0, <span class="keywordtype">int</span> 
line = -1);
       };
    }
  - 
  +
    <span class="comment">//</span>
    <span class="comment">//    Use these instead of calling Logger methods 
directly.</span>
    <span class="comment">//</span>
  @@ -71,7 +135,7 @@
   <span class="preprocessor"></span><span class="preprocessor"> #define 
LOG4CXX_WARN(logger, msg) ...</span>
   <span class="preprocessor"></span><span class="preprocessor"> #define 
LOG4CXX_ERROR(logger, msg) ...</span>
   <span class="preprocessor"> #define LOG4CXX_FATAL(logger, msg) ...</span>
  -</div></pre><p>
  +</pre></div><p>
   Loggers may be assigned levels. The set of possible levels, that is <a 
class="el" href="classlog4cxx_1_1Level.html#s5">DEBUG</a>, <a class="el" 
href="classlog4cxx_1_1Level.html#s4">INFO</a>, <a class="el" 
href="classlog4cxx_1_1Level.html#s3">WARN</a>, <a class="el" 
href="classlog4cxx_1_1Level.html#s2">ERROR</a> and <a class="el" 
href="classlog4cxx_1_1Level.html#s1">FATAL</a> are defined in the <a class="el" 
href="classlog4cxx_1_1Level.html">log4cxx::Level</a> class. Although we do not 
encourage you to do so, you may define your own levels by sub-classing the 
Level class. A perhaps better approach will be explained later on.<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>
   <table bgcolor="#EEEE99" border="1" cellspacing="3" cellpadding="3">
  @@ -177,7 +241,7 @@
   <p>
   This rule is at the heart of log4cxx. It assumes that levels are ordered. 
For the standard levels, we have DEBUG &lt; INFO &lt; WARN &lt; ERROR &lt; 
FATAL.<p>
   Here is an example of this rule.<p>
  -<pre class="fragment"><div><span class="comment">// get a logger instance 
named "com.foo"</span>
  +<div class="fragment"><pre><span class="comment">// get a logger instance 
named "com.foo"</span>
   <a class="code" 
href="classlog4cxx_1_1helpers_1_1ObjectPtrT.html">log4cxx::LoggerPtr</a> 
logger(log4cxx::Logger::getLogger(<span 
class="stringliteral">"com.foo"</span>));
   
   <span class="comment">// Now set its level. Normally you do not need to set 
the</span>
  @@ -201,11 +265,11 @@
   
   <span class="comment">// This request is disabled, because DEBUG &lt; 
INFO.</span>
   <a class="code" 
href="group__LoggingMacros.html#ga2">LOG4CXX_DEBUG</a>(barlogger, <span 
class="stringliteral">"Exiting gas station search"</span>);
  -</div></pre><p>
  +</pre></div><p>
   Calling the <code>getLogger</code> method with the same name will always 
return a reference to the exact same logger object.<p>
  -For example, in <pre class="fragment"><div><a class="code" 
href="classlog4cxx_1_1helpers_1_1ObjectPtrT.html">LoggerPtr</a> x = <a 
class="code" href="classlog4cxx_1_1Logger.html#e0">Logger::getLogger</a>(<span 
class="stringliteral">"wombat"</span>);
  -<a class="code" 
href="classlog4cxx_1_1helpers_1_1ObjectPtrT.html">LoggerPtr</a> y = <a 
class="code" href="classlog4cxx_1_1Logger.html#e0">Logger::getLogger</a>(<span 
class="stringliteral">"wombat"</span>);
  -</div></pre><code>x</code> and <code>y</code> refer to <em>exactly</em> the 
same logger object.<p>
  +For example, in <div class="fragment"><pre>LoggerPtr x = 
Logger::getLogger(<span class="stringliteral">"wombat"</span>);
  +LoggerPtr y = Logger::getLogger(<span class="stringliteral">"wombat"</span>);
  +</pre></div><code>x</code> and <code>y</code> refer to <em>exactly</em> the 
same logger object.<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, log4cxx 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>
   Configuration of the log4cxx environment is typically done at application 
initialization. The preferred way is by reading a configuration file. This 
approach will be discussed shortly.<p>
   Log4cxx 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. Log4cxx does not restrict the 
possible set of loggers. The developer is free to name the loggers as 
desired.<p>
  @@ -237,7 +301,7 @@
   </th></tr>
   <tr>
   <td>root </td><td>A1 </td><td>not applicable </td><td>A1<p>
  -</td><td>The root logger is anonymous but can be accessed with the <a 
class="el" href="classlog4cxx_1_1Logger.html#e1">Logger::getRootLogger()</a> 
method. There is no default appender attached to root.<p>
  +</td><td>The root logger is anonymous but can be accessed with the 
Logger::getRootLogger() method. There is no default appender attached to 
root.<p>
   </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.<p>
  @@ -267,7 +331,7 @@
   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>
   The log4cxx environment is fully configurable programmatically. However, it 
is far more flexible to configure log4cxx using configuration files. Currently, 
configuration files can be written in XML or in properties (key=value) 
format.<p>
   Let us give a taste of how this is done with the help of an imaginary 
application <code>MyApp</code> that uses log4cxx.<p>
  -<pre class="fragment"><div><span class="comment">// file MyApp.cpp</span>
  +<div class="fragment"><pre><span class="comment">// file MyApp.cpp</span>
   
   <span class="preprocessor">#include "com/foo/bar.h"</span>
   <span class="keyword">using</span> <span class="keyword">namespace 
</span>com::foo;
  @@ -282,7 +346,7 @@
   
   <span class="comment">// Define a static logger variable so that it 
references the</span>
   <span class="comment">// Logger instance named "MyApp".</span>
  -<a class="code" 
href="classlog4cxx_1_1helpers_1_1ObjectPtrT.html">LoggerPtr</a> 
logger(Logger::getLogger(<span class="stringliteral">"MyApp"</span>));
  +LoggerPtr logger(Logger::getLogger(<span 
class="stringliteral">"MyApp"</span>));
   
   <span class="keywordtype">int</span> main(<span 
class="keywordtype">int</span> argc, <span class="keywordtype">char</span> 
**argv)
   {
  @@ -290,7 +354,7 @@
           <span class="keywordflow">try</span>
           {
                   <span class="comment">// Set up a simple configuration that 
logs on the console.</span>
  -                <a class="code" 
href="classlog4cxx_1_1BasicConfigurator.html#e0">BasicConfigurator::configure</a>();
  +                BasicConfigurator::configure();
   
                   <a class="code" 
href="group__LoggingMacros.html#ga3">LOG4CXX_INFO</a>(logger, <span 
class="stringliteral">"Entering application."</span>);
                   Bar bar;
  @@ -304,10 +368,10 @@
   
           <span class="keywordflow">return</span> result;
   }
  -</div></pre><p>
  +</pre></div><p>
   <code>MyApp</code> begins by including log4cxx related headers. 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>
   <code>MyApp</code> uses the <code>Bar</code> class defined in the header 
file <code>com/foo/bar.h</code> and the source file <code>bar.cpp</code>.<p>
  -<pre class="fragment"><div><span class="comment">// file 
&lt;com/foo/bar.h&gt;</span>
  +<div class="fragment"><pre><span class="comment">// file 
&lt;com/foo/bar.h&gt;</span>
   
   <span class="preprocessor">#include &lt;log4cxx/logger.h&gt;</span>
   
  @@ -324,31 +388,31 @@
                   };
           };
   };
  -</div></pre><p>
  -<pre class="fragment"><div><span class="comment">// file 
&lt;bar.cpp&gt;</span>
  +</pre></div><p>
  +<div class="fragment"><pre><span class="comment">// file 
&lt;bar.cpp&gt;</span>
   
   <span class="preprocessor">#include "com/foo/bar.h"</span>
   
   <span class="keyword">using</span> <span class="keyword">namespace 
</span>com::foo;
   <span class="keyword">using</span> <span class="keyword">namespace 
</span>log4cxx;
   
  -<a class="code" 
href="classlog4cxx_1_1helpers_1_1ObjectPtrT.html">LoggerPtr</a> 
Bar::logger(Logger::getLogger(<span 
class="stringliteral">"com.foo.bar"</span>));
  +LoggerPtr Bar::logger(Logger::getLogger(<span 
class="stringliteral">"com.foo.bar"</span>));
   
   <span class="keywordtype">void</span> Bar::doIt()
   {
           <a class="code" 
href="group__LoggingMacros.html#ga2">LOG4CXX_DEBUG</a>(logger, <span 
class="stringliteral">"Did it again!"</span>);
   }
  -</div></pre><p>
  +</pre></div><p>
   The invocation of the <a class="el" 
href="classlog4cxx_1_1BasicConfigurator.html#e0">BasicConfigurator::configure</a>
 method creates a rather simple log4cxx setup. This method is hardwired to add 
to the root logger <a class="el" 
href="classlog4cxx_1_1ConsoleAppender.html">ConsoleAppender</a>. The output 
will be formatted using a <a class="el" 
href="classlog4cxx_1_1PatternLayout.html">PatternLayout</a> set to the pattern 
"\%-4r [\%t] \%-5p \%c \%x - \%m\%n".<p>
  -Note that by default, the root logger is assigned to <code><a class="el" 
href="classlog4cxx_1_1Level.html#s5">Level::DEBUG</a></code>.<p>
  +Note that by default, the root logger is assigned to 
<code>Level::DEBUG</code>.<p>
   The output of MyApp is: <pre><div>0    [12345] INFO  MyApp  - Entering 
application.
   36   [12345] DEBUG com.foo.Bar  - Did it again!
   51   [12345] INFO  MyApp  - Exiting application.
   </pre></div><p>
   As a side note, let me mention that in log4cxx 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 log4cxx's memory 
footprint.<p>
  -The <code>MyApp</code> class configures log4cxx by invoking <code><a 
class="el" 
href="classlog4cxx_1_1BasicConfigurator.html#e0">BasicConfigurator::configure</a></code>
 method. Other classes only need to include the 
<code>&lt;log4cxx/logger.h&gt;</code> header file, retrieve the loggers they 
wish to use, and log away.<p>
  +The <code>MyApp</code> class configures log4cxx by invoking 
<code>BasicConfigurator::configure</code> method. Other classes only need to 
include the <code>&lt;log4cxx/logger.h&gt;</code> header file, retrieve the 
loggers they wish to use, and log away.<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>
  -<pre class="fragment"><div><span class="comment">// file MyApp2.cpp</span>
  +<div class="fragment"><pre><span class="comment">// file MyApp2.cpp</span>
   
   <span class="preprocessor">#include "com/foo/bar.h"</span>
   <span class="keyword">using</span> <span class="keyword">namespace 
</span>com::foo;
  @@ -364,7 +428,7 @@
   
   <span class="comment">// Define a static logger variable so that it 
references the</span>
   <span class="comment">// Logger instance named "MyApp".</span>
  -<a class="code" 
href="classlog4cxx_1_1helpers_1_1ObjectPtrT.html">LoggerPtr</a> 
logger(Logger::getLogger(<span class="stringliteral">"MyApp"</span>));
  +LoggerPtr logger(Logger::getLogger(<span 
class="stringliteral">"MyApp"</span>));
   
   <span class="keywordtype">int</span> main(<span 
class="keywordtype">int</span> argc, <span class="keywordtype">char</span> 
**argv)
   {
  @@ -374,11 +438,11 @@
                   <span class="keywordflow">if</span> (argc &gt; 1)
                   {
                           <span class="comment">// BasicConfigurator replaced 
with PropertyConfigurator.</span>
  -                        <a class="code" 
href="classlog4cxx_1_1PropertyConfigurator.html#e0">PropertyConfigurator::configure</a>(argv[1]);
  +                        PropertyConfigurator::configure(argv[1]);
                   }
                   <span class="keywordflow">else</span>
                   {
  -                        <a class="code" 
href="classlog4cxx_1_1BasicConfigurator.html#e0">BasicConfigurator::configure</a>();
  +                        BasicConfigurator::configure();
                   }
   
                   <a class="code" 
href="group__LoggingMacros.html#ga3">LOG4CXX_INFO</a>(logger, <span 
class="stringliteral">"Entering application."</span>);
  @@ -393,7 +457,7 @@
   
           <span class="keywordflow">return</span> result;
   }
  -</div></pre><p>
  +</pre></div><p>
   This version of <code>MyApp</code> instructs 
<code>PropertyConfigurator</code> to parse a configuration file and set up 
logging accordingly.<p>
   Here is a sample configuration file that results in exactly same output as 
the previous <code>BasicConfigurator</code> based example.<p>
   <table bgcolor="CCAAAA" border="1" cellspacing="3" cellpadding="3">
  @@ -456,34 +520,30 @@
   The log4cxx library does not make any assumptions about its environment. In 
particular, there are no default log4cxx appenders. Under certain well-defined 
circumstances however, the initialization of the logger hierarchy will attempt 
to automatically configure log4cxx.<p>
   The exact default initialization algorithm is defined as follows:<p>
   <ol>
  -<li>Set the <code>configurationOptionStr</code> string variable to the value 
of the <b>log4j.configuration</b> environment variable. <em>The preferred way 
to specify the default initialization file is through the 
<b>log4j.configuration</b> environment variable.</em> In case the environment 
variable <b>log4j.configuration</b> is not defined, then set the string 
variable <code>configurationOptionStr</code> to its default value 
"log4j.properties". <br>
  +<li>Set the <code>configurationOptionStr</code> string variable to the value 
of the <b>LOG4CXX_CONFIGURATION</b> environment variable if set, otherwise the 
value of the <b>log4j.configuration</b> environment variable if set, otherwise 
the first of the following file names which exist in the current working 
directory, "log4cxx.properties", "log4j.properties", "log4cxx.xml" and 
"log4j.xml". If <code>configurationOptionStr</code> has not been set, then 
disable logging. <br>
    <br>
  -</li><li>Attempt to convert the <code>configurationOptionStr</code> variable 
to a valid file name. <br>
  - <br>
  -</li><li>If no file could be found, abort default initialization. Otherwise, 
configure log4cxx from the file name. <br>
  - <br>
  - The <a class="el" 
href="classlog4cxx_1_1PropertyConfigurator.html">PropertyConfigurator</a> will 
be used to parse the file to configure log4cxx unless the file name ends with 
the ".xml" extension, in which case the <a class="el" 
href="">DOMConfigurator</a> will be used. You can optionaly specify a custom 
configurator. The value of the <b>log4j.configuratorClass</b> environment 
variable is taken as the fully qualified class name of your custom 
configurator. The custom configurator you specify <em>must</em> implement the 
<a class="el" href="classlog4cxx_1_1spi_1_1Configurator.html">Configurator</a> 
interface.</li></ol>
  + Unless a custom configurator is specified using the 
<b>LOG4CXX_CONFIGURATOR_CLASS</b> or <b>log4j.configuratorClass</b> environment 
variable, the <a class="el" 
href="classlog4cxx_1_1PropertyConfigurator.html">PropertyConfigurator</a> will 
be used to configure log4cxx unless the file name ends with the ".xml" 
extension, in which case the <a class="el" href="">DOMConfigurator</a> will be 
used. If a custom configurator is specified, the environment variable should 
contain a fully qualified class name of a class that implements the <a 
class="el" href="classlog4cxx_1_1spi_1_1Configurator.html">Configurator</a> 
interface.</li></ol>
   <h2><a class="anchor" name="NDC">
   Nested Diagnostic Contexts</a></h2>
   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>
   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>
   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.<p>
  -<pre class="fragment"><div><span class="keyword">class </span><a 
class="code" href="classlog4cxx_1_1NDC.html">NDC</a>
  +<div class="fragment"><pre><span class="keyword">class </span>NDC
   {
   <span class="keyword">public</span>:
       <span class="comment">// Used when printing the diagnostic</span>
  -    <span class="keyword">static</span> String <a class="code" 
href="classlog4cxx_1_1NDC.html#e3">get</a>();
  +    <span class="keyword">static</span> String get();
   
       <span class="comment">// Remove the top of the context from the 
NDC.</span>
  -    <span class="keyword">static</span> String <a class="code" 
href="classlog4cxx_1_1NDC.html#e5">pop</a>();
  +    <span class="keyword">static</span> String pop();
   
       <span class="comment">// Add diagnostic context for the current 
thread.</span>
  -    <span class="keyword">static</span> <span 
class="keywordtype">void</span> <a class="code" 
href="classlog4cxx_1_1NDC.html#e7">push</a>(<span class="keyword">const</span> 
String&amp; message);
  +    <span class="keyword">static</span> <span 
class="keywordtype">void</span> push(<span class="keyword">const</span> 
String&amp; message);
   
       <span class="comment">// Remove the diagnostic context for this 
thread.</span>
  -    <span class="keyword">static</span> <span 
class="keywordtype">void</span> <a class="code" 
href="classlog4cxx_1_1NDC.html#e8">remove</a>();
  +    <span class="keyword">static</span> <span 
class="keywordtype">void</span> remove();
    };
  -</div></pre><p>
  +</pre></div><p>
   The NDC is managed per thread as a <em>stack</em> of contextual information. 
Note that all methods of the <code><a class="el" 
href="classlog4cxx_1_1NDC.html">log4cxx::NDC</a></code> class are static. 
Assuming that NDC printing is turned on, every time a log request is made, the 
appropriate log4cxx 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>
   To illustrate this point, let us take the example of a server delivering 
content to numerous clients. The server 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 
caller identity. Hence, even if the server 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>
   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 log4cxx 
releases support multiple hierarchy trees. This enhancement allows each virtual 
host to possess its own copy of the logger hierarchy.<h2><a class="anchor" 
name="Performance">
  @@ -497,18 +557,18 @@
    <br>
    However, The method invocation involves the "hidden" cost of parameter 
construction. <br>
    <br>
  - For example, for some logger <code>logger</code>, writing, <pre 
class="fragment"><div>logger-&gt;debug(<span class="stringliteral">"The user 
named ["</span> + strName + <span class="stringliteral">"] is logged"</span>, 
__FILE__, __LINE__);
  -</div></pre>incurs the cost of constructing the message parameter, i.e. 
concatenating intermediate strings, regardless of whether the message will be 
logged or not. <br>
  + For example, for some logger <code>logger</code>, writing, <div 
class="fragment"><pre>logger-&gt;debug(<span class="stringliteral">"The user 
named ["</span> + strName + <span class="stringliteral">"] is logged"</span>, 
__FILE__, __LINE__);
  +</pre></div>incurs the cost of constructing the message parameter, i.e. 
concatenating intermediate strings, regardless of whether the message will be 
logged or not. <br>
    <br>
    This cost of parameter construction can be quite high and it depends on the 
size of the parameters involved. <br>
    <br>
  - To avoid the parameter construction cost write: <pre 
class="fragment"><div><span 
class="keywordflow">if</span>(logger-&gt;isDebugEnabled()
  + To avoid the parameter construction cost write: <div 
class="fragment"><pre><span 
class="keywordflow">if</span>(logger-&gt;isDebugEnabled()
   {
  -        logger-&gt;forcedLog(Level::DEBUG, 
  +        logger-&gt;forcedLog(Level::DEBUG,
                   <span class="stringliteral">"The user named ["</span> + 
strName + <span class="stringliteral">"] is logged"</span>, __FILE__, __LINE__);
   }
  -</div></pre>or better yet: <pre class="fragment"><div><a class="code" 
href="group__LoggingMacros.html#ga2">LOG4CXX_DEBUG</a>(logger, <span 
class="stringliteral">"The user named ["</span> + strName + <span 
class="stringliteral">"] is logged"</span>);
  -</div></pre></li></ol>
  +</pre></div>or better yet: <div class="fragment"><pre><a class="code" 
href="group__LoggingMacros.html#ga2">LOG4CXX_DEBUG</a>(logger, <span 
class="stringliteral">"The user named ["</span> + strName + <span 
class="stringliteral">"] is logged"</span>);
  +</pre></div></li></ol>
   <p>
   <br>
    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. <br>
  @@ -527,8 +587,21 @@
   Although log4cxx has many features, its first design goal was speed. Some 
log4cxx 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 class="el" 
href="classlog4cxx_1_1SimpleLayout.html">SimpleLayout</a> performance tests 
have shown log4cxx to log as quickly as <code>std::cout</code>.<h2><a 
class="anchor" name="Conclusion">
   Conclusion</a></h2>
   Log4cxx is a popular logging package written in C++. 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>
  -One of the advantages of the log4cxx 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 log4cxx 
package is designed so that log statements can remain in shipped code without 
incurring a heavy performance cost. <hr size="1"><address style="align: 
right;"><small>Generated on Thu Oct 21 15:43:56 2004 for log4cxx by
  -<a href="http://www.doxygen.org/index.html";>
  -<img src="doxygen.png" alt="doxygen" align="middle" border=0 > </a>1.3.6 
</small></address>
  -</body>
  -</html>
  +One of the advantages of the log4cxx 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 log4cxx 
package is designed so that log statements can remain in shipped code without 
incurring a heavy performance cost.                                             
    
  +                    </td>
  +                </tr>
  +             
  +                <!-- FOOTER -->
  +                <tr><td colspan="2">
  +                    <hr noshade="" size="1"/>
  +                </td></tr>
  +                <tr><td colspan="2">
  +                    <div align="center"><font color="#525D76" size="-1"><em>
  +                    Copyright &#169; 1999-2004, Apache Software Foundation
  +                    </em></font></div>
  +                </td></tr>
  +            </table>
  +           <!-- END main table --> 
  +        </body>
  +    </html>
  +<!-- end the processing -->
  
  
  

Reply via email to