You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by ca...@apache.org on 2004/10/21 22:58:03 UTC

cvs commit: logging-log4cxx/xdocs/www/manual Introduction.html

carnold     2004/10/21 13:58:03

  Modified:    xdocs/www/manual Introduction.html
  Log:
  LOGCXX16: Misleading statements in Introduction to log4cxx
  
  Revision  Changes    Path
  1.5       +96 -161   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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Introduction.html	15 Jun 2004 20:19:30 -0000	1.4
  +++ Introduction.html	21 Oct 2004 20:58:03 -0000	1.5
  @@ -1,74 +1,10 @@
  -<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>
  +<!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>
   <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>
  @@ -105,26 +41,37 @@
   <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>
  -<div class="fragment"><pre><span class="preprocessor">#include &lt;log4cxx/logger.h&gt;</span>
  -
  -<span class="keyword">class </span>Logger
  -{
  -<span class="keyword">public</span>:
  -    <span class="comment">// Creation &amp; retrieval methods:</span>
  -    <span class="keyword">static</span> LoggerPtr getRootLogger();
  -    <span class="keyword">static</span> LoggerPtr getLogger(<span class="keyword">const</span> String&amp; name);
  -
  -    <span class="comment">// printing methods:</span>
  -    <span class="keywordtype">void</span> debug(<span class="keyword">const</span> String&amp; message);
  -    <span class="keywordtype">void</span> info(<span class="keyword">const</span> String&amp; message);
  -    <span class="keywordtype">void</span> warn(<span class="keyword">const</span> String&amp; message);
  -    <span class="keywordtype">void</span> error(<span class="keyword">const</span> String&amp; message);
  -    <span class="keywordtype">void</span> fatal(<span class="keyword">const</span> String&amp; message);
  -
  -    <span class="comment">// generic printing method:</span>
  -    <span class="keywordtype">void</span> log(<span class="keyword">const</span> LevelPtr&amp; l, <span class="keyword">const</span> String&amp; message);
  -};
  -</pre></div><p>
  +<pre class="fragment"><div> <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">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="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="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>
  +<span class="preprocessor"> #define LOG4CXX_DEBUG(logger, msg) ...</span>
  +<span class="preprocessor"></span><span class="preprocessor"> #define LOG4CXX_INFO(logger, msg) ...</span>
  +<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>
   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">
  @@ -230,35 +177,35 @@
   <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>
  -<div class="fragment"><pre><span class="comment">// get a logger instance named "com.foo"</span>
  -LoggerPtr logger = Logger::getLogger(_T(<span class="stringliteral">"com.foo"</span>));
  +<pre class="fragment"><div><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>
   <span class="comment">// level of a logger programmatically. This is usually done</span>
   <span class="comment">// in configuration files.</span>
  -logger-&gt;setLevel(Level::INFO);
  +logger-&gt;setLevel(log4cxx::Level::INFO);
   
  -LoggerPtr barlogger = Logger::getLogger(_T(<span class="stringliteral">"com.foo.Bar"</span>));
  +<a class="code" href="classlog4cxx_1_1helpers_1_1ObjectPtrT.html">log4cxx::LoggerPtr</a> barlogger(Logger::getLogger((<span class="stringliteral">"com.foo.Bar"</span>));
   
   <span class="comment">// This request is enabled, because WARN &gt;= INFO.</span>
  -logger-&gt;warn(_T(<span class="stringliteral">"Low fuel level."</span>));
  +<a class="code" href="group__LoggingMacros.html#ga4">LOG4CXX_WARN</a>(logger, <span class="stringliteral">"Low fuel level."</span>);
   
   <span class="comment">// This request is disabled, because DEBUG &lt; INFO.</span>
  -logger-&gt;debug(_T(<span class="stringliteral">"Starting search for nearest gas station."</span>));
  +<a class="code" href="group__LoggingMacros.html#ga2">LOG4CXX_DEBUG</a>(logger-, <span class="stringliteral">"Starting search for nearest gas station."</span>);
   
   <span class="comment">// The logger instance barlogger, named "com.foo.Bar",</span>
   <span class="comment">// will inherit its level from the logger named</span>
   <span class="comment">// "com.foo" Thus, the following request is enabled</span>
   <span class="comment">// because INFO &gt;= INFO.</span>
  -barlogger-&gt;info(_T(<span class="stringliteral">"Located nearest gas station."</span>));
  +<a class="code" href="group__LoggingMacros.html#ga3">LOG4CXX_INFO</a>(barlogger, <span class="stringliteral">"Located nearest gas station."</span>);
   
   <span class="comment">// This request is disabled, because DEBUG &lt; INFO.</span>
  -barlogger-&gt;debug(_T(<span class="stringliteral">"Exiting gas station search"</span>));
  -</pre></div><p>
  +<a class="code" href="group__LoggingMacros.html#ga2">LOG4CXX_DEBUG</a>(barlogger, <span class="stringliteral">"Exiting gas station search"</span>);
  +</div></pre><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 <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>
  +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>
   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>
  @@ -290,7 +237,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 Logger::getRootLogger() method. There is no default appender attached to root.<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></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>
  @@ -320,7 +267,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>
  -<div class="fragment"><pre><span class="comment">// file MyApp.cpp</span>
  +<pre class="fragment"><div><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;
  @@ -335,7 +282,7 @@
   
   <span class="comment">// Define a static logger variable so that it references the</span>
   <span class="comment">// Logger instance named "MyApp".</span>
  -LoggerPtr logger = Logger::getLogger(_T(<span class="stringliteral">"MyApp"</span>));
  +<a class="code" href="classlog4cxx_1_1helpers_1_1ObjectPtrT.html">LoggerPtr</a> 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)
   {
  @@ -343,12 +290,12 @@
           <span class="keywordflow">try</span>
           {
                   <span class="comment">// Set up a simple configuration that logs on the console.</span>
  -                BasicConfigurator::configure();
  +                <a class="code" href="classlog4cxx_1_1BasicConfigurator.html#e0">BasicConfigurator::configure</a>();
   
  -                logger-&gt;info(_T(<span class="stringliteral">"Entering application."</span>));
  +                <a class="code" href="group__LoggingMacros.html#ga3">LOG4CXX_INFO</a>(logger, <span class="stringliteral">"Entering application."</span>);
                   Bar bar;
                   bar.doIt();
  -                logger-&gt;info(_T(<span class="stringliteral">"Exiting application."</span>));
  +                <a class="code" href="group__LoggingMacros.html#ga3">LOG4CXX_INFO</a>(logger, <span class="stringliteral">"Exiting application."</span>);
           }
           <span class="keywordflow">catch</span>(Exception&amp;)
           {
  @@ -357,10 +304,10 @@
   
           <span class="keywordflow">return</span> result;
   }
  -</pre></div><p>
  +</div></pre><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>
  -<div class="fragment"><pre><span class="comment">// file &lt;com/foo/bar.h&gt;</span>
  +<pre class="fragment"><div><span class="comment">// file &lt;com/foo/bar.h&gt;</span>
   
   <span class="preprocessor">#include &lt;log4cxx/logger.h&gt;</span>
   
  @@ -377,31 +324,31 @@
                   };
           };
   };
  -</pre></div><p>
  -<div class="fragment"><pre><span class="comment">// file &lt;bar.cpp&gt;</span>
  +</div></pre><p>
  +<pre class="fragment"><div><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;
   
  -LoggerPtr Bar::logger = Logger::getLogger(_T(<span class="stringliteral">"com.foo.bar"</span>));
  +<a class="code" href="classlog4cxx_1_1helpers_1_1ObjectPtrT.html">LoggerPtr</a> Bar::logger(Logger::getLogger(<span class="stringliteral">"com.foo.bar"</span>));
   
   <span class="keywordtype">void</span> Bar::doIt()
   {
  -        logger-&gt;debug(_T(<span class="stringliteral">"Did it again!"</span>));
  +        <a class="code" href="group__LoggingMacros.html#ga2">LOG4CXX_DEBUG</a>(logger, <span class="stringliteral">"Did it again!"</span>);
   }
  -</pre></div><p>
  +</div></pre><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>Level::DEBUG</code>.<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>
   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>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 <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 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>
  -<div class="fragment"><pre><span class="comment">// file MyApp2.cpp</span>
  +<pre class="fragment"><div><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;
  @@ -417,7 +364,7 @@
   
   <span class="comment">// Define a static logger variable so that it references the</span>
   <span class="comment">// Logger instance named "MyApp".</span>
  -LoggerPtr logger = Logger::getLogger(_T(<span class="stringliteral">"MyApp"</span>));
  +<a class="code" href="classlog4cxx_1_1helpers_1_1ObjectPtrT.html">LoggerPtr</a> 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)
   {
  @@ -427,19 +374,17 @@
                   <span class="keywordflow">if</span> (argc &gt; 1)
                   {
                           <span class="comment">// BasicConfigurator replaced with PropertyConfigurator.</span>
  -                        USES_CONVERSION;
  -                        String propertyFileName = A2W(argv[1]);
  -                        PropertyConfigurator::configure(propertyFileName);
  +                        <a class="code" href="classlog4cxx_1_1PropertyConfigurator.html#e0">PropertyConfigurator::configure</a>(argv[1]);
                   }
                   <span class="keywordflow">else</span>
                   {
  -                        BasicConfigurator::configure();
  +                        <a class="code" href="classlog4cxx_1_1BasicConfigurator.html#e0">BasicConfigurator::configure</a>();
                   }
   
  -                logger-&gt;info(_T(<span class="stringliteral">"Entering application."</span>));
  +                <a class="code" href="group__LoggingMacros.html#ga3">LOG4CXX_INFO</a>(logger, <span class="stringliteral">"Entering application."</span>);
                   Bar bar
                   bar.doIt();
  -                logger-&gt;info(_T(<span class="stringliteral">"Exiting application."</span>));
  +                <a class="code" href="group__LoggingMacros.html#ga3">LOG4CXX_INFO</a>(logger, <span class="stringliteral">"Exiting application."</span>);
           }
           <span class="keywordflow">catch</span>(Exception&amp;)
           {
  @@ -448,7 +393,7 @@
   
           <span class="keywordflow">return</span> result;
   }
  -</pre></div><p>
  +</div></pre><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">
  @@ -517,28 +462,28 @@
    <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="classlog4cxx_1_1xml_1_1DOMConfigurator.html">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>
  + 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>
   <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>
  -<div class="fragment"><pre><span class="keyword">class </span>NDC
  +<pre class="fragment"><div><span class="keyword">class </span><a class="code" href="classlog4cxx_1_1NDC.html">NDC</a>
   {
   <span class="keyword">public</span>:
       <span class="comment">// Used when printing the diagnostic</span>
  -    <span class="keyword">static</span> String get();
  +    <span class="keyword">static</span> String <a class="code" href="classlog4cxx_1_1NDC.html#e3">get</a>();
   
       <span class="comment">// Remove the top of the context from the NDC.</span>
  -    <span class="keyword">static</span> String pop();
  +    <span class="keyword">static</span> String <a class="code" href="classlog4cxx_1_1NDC.html#e5">pop</a>();
   
       <span class="comment">// Add diagnostic context for the current thread.</span>
  -    <span class="keyword">static</span> <span class="keywordtype">void</span> push(<span class="keyword">const</span> String&amp; message);
  +    <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="comment">// Remove the diagnostic context for this thread.</span>
  -    <span class="keyword">static</span> <span class="keywordtype">void</span> remove();
  +    <span class="keyword">static</span> <span class="keywordtype">void</span> <a class="code" href="classlog4cxx_1_1NDC.html#e8">remove</a>();
    };
  -</pre></div><p>
  +</div></pre><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">
  @@ -548,25 +493,28 @@
   <ol>
   <li><b>Logging performance when logging is turned off.</b> <br>
    <br>
  - When logging is turned off entirely or just for a <a class="el" href="classlog4cxx_1_1Hierarchy.html#a6">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. <br>
  + When logging is turned off entirely or just for a <a class="el" href="classlog4cxx_1_1Hierarchy.html#a6">set of levels</a>, the cost of a log request consists of a method invocation plus an integer comparison. <br>
    <br>
    However, The method invocation involves the "hidden" cost of parameter construction. <br>
    <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>);
  -</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>
  + 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>
    <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: <div class="fragment"><pre><span class="keywordflow">if</span>(logger-&gt;isDebugEnabled()
  + To avoid the parameter construction cost write: <pre class="fragment"><div><span class="keywordflow">if</span>(logger-&gt;isDebugEnabled()
   {
           logger-&gt;forcedLog(Level::DEBUG, 
  -                <span class="stringliteral">"The user named ["</span> + strName + <span class="stringliteral">"] is logged"</span>);
  +                <span class="stringliteral">"The user named ["</span> + strName + <span class="stringliteral">"] is logged"</span>, __FILE__, __LINE__);
   }
  -</pre></div>or in a simpler way: <div class="fragment"><pre><a class="code" href="group__LoggingMacros.html#ga1">LOG4CXX_DEBUG</a>(logger, <span class="stringliteral">"The user named ["</span> + strName + <span class="stringliteral">"] is logged"</span>);
  -</pre></div><br>
  +</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>
  +<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>
    <br>
  -</li><li><b>The performance of deciding whether to log or not to log when logging is turned on.</b> <br>
  +<ol>
  +<li><b>The performance of deciding whether to log or not to log when logging is turned on.</b> <br>
    <br>
    This is essentially the performance of walking the logger hierarchy. When logging is turned on, log4cxx 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. <br>
    <br>
  @@ -574,26 +522,13 @@
    <br>
    The typical cost of walking the hierarchy is typically 3 times slower than when logging is turned off entirely. <br>
    <br>
  -</li><li><b>Actually outputting log messages</b> 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.</li></ol>
  +</li><li><b>Actually outputting log messages</b> 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.</li></ol>
   <p>
   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.                                                 
  -                    </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 -->
  +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>