This is an automated email from the ASF dual-hosted git repository.

swebb2066 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git


The following commit(s) were added to refs/heads/master by this push:
     new 563bbd8c Improve the structure, clarity and correctness of 
documentation (#238)
563bbd8c is described below

commit 563bbd8ca2db356fc2c2f7098b62a673a1b2fa1f
Author: Stephen Webb <[email protected]>
AuthorDate: Wed Jul 26 13:33:57 2023 +1000

    Improve the structure, clarity and correctness of documentation (#238)
---
 src/examples/config/async-example.xml              |  31 +
 src/main/include/log4cxx/logger.h                  |  34 +-
 src/main/include/log4cxx/net/smtpappender.h        |  34 +-
 src/site/doxy/Doxyfile.in                          |   2 +-
 src/site/markdown/1-usage.md                       |  18 +-
 src/site/markdown/{usage.md => concepts.md}        | 797 +++++++++------------
 .../markdown/{multiprocess.md => conclusions.md}   |  25 +-
 src/site/markdown/configuration-samples.md         |  93 +--
 src/site/markdown/environment-variables.md         |   4 +-
 src/site/markdown/example-programs.md              | 193 +++++
 src/site/markdown/extending.md                     |   2 +-
 src/site/markdown/faq.md                           |   6 +-
 src/site/markdown/filters/filters.md               |  42 +-
 .../markdown/{1-usage.md => internal-debugging.md} |  30 +-
 src/site/markdown/macros-influencing-log4cxx.md    |   4 +-
 src/site/markdown/multiprocess.md                  |   8 +-
 src/site/markdown/nested-diagnostic-contexts.md    |  69 --
 src/site/markdown/performance.md                   |   3 -
 src/site/markdown/stacktrace.md                    |   1 -
 src/site/markdown/threading.md                     |   2 -
 20 files changed, 676 insertions(+), 722 deletions(-)

diff --git a/src/examples/config/async-example.xml 
b/src/examples/config/async-example.xml
new file mode 100644
index 00000000..07a9357d
--- /dev/null
+++ b/src/examples/config/async-example.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/";>
+  <appender name="A1" class="RollingFileAppender">
+    <param name="File"   value="${TEMP}/SomeApplicationName.log" />
+    <param name="Append" value="true" />
+    <layout class="PatternLayout">
+      <param name="ConversionPattern" value="%d %-5p %c{2} - %m%n"/>
+    </layout>
+  </appender>
+  <appender name="SENDMAIL" class="SMTPAppender">
+    <param name="from"   value="[email protected]" />
+    <param name="to" value="[email protected]" />
+    <param name="subject" value="Service error detected" />
+    <param name="SMTPHost" value="smtp.example.com"/>
+    <layout class="PatternLayout">
+               <param name="ConversionPattern" value="%-5p %c{2} - %m%n"/>
+    </layout>
+    <!-- triggeringPolicy class="SpecialTriggeringEventEvaluator" -->
+    <!-- param name="evaluatorClass" value="SpecialTriggeringEventEvaluator" 
-->
+  </appender>
+  <appender name="ASYNC" class="AsyncAppender">
+    <param name="BufferSize" value="1000"/>
+    <param name="Blocking" value="false"/>
+    <appender-ref ref="SENDMAIL"/>
+  </appender>
+  <root>
+    <priority value ="INFO" />
+    <appender-ref ref="A1" />
+    <appender-ref ref="ASYNC" />
+  </root>
+</log4j:configuration>
diff --git a/src/main/include/log4cxx/logger.h 
b/src/main/include/log4cxx/logger.h
index db61db42..3b822ee0 100644
--- a/src/main/include/log4cxx/logger.h
+++ b/src/main/include/log4cxx/logger.h
@@ -2021,7 +2021,7 @@ Add a new logging event containing \c message to attached 
appender(s) if this lo
 
 @param logger the logger to be used.
 @param level The logging event level.
-@param message the message string to log.
+@param message a valid r-value expression of an 
<code>operator<<(std::ostream&. ...)</code> overload.
 */
 #define LOG4CXX_LOG(logger, level, message) do { \
                if (logger->isEnabledFor(level)) {\
@@ -2033,7 +2033,7 @@ Add a new logging event containing libfmt formatted 
<code>...</code> to attached
 
 @param logger the logger to be used.
 @param level The logging event level.
-@param ... The format string and message to log
+@param ... The format string and parameters that define the log message.
 */
 #define LOG4CXX_LOG_FMT(logger, level, ...) do { \
                if (logger->isEnabledFor(level)) {\
@@ -2044,7 +2044,7 @@ Add a new logging event containing \c message to attached 
appender(s) if this lo
 
 @param logger the logger to be used.
 @param level The logging event level.
-@param message the message string to log in the internal encoding.
+@param message a valid r-value expression of an 
<code>operator<<(std::ostream&. ...)</code> overload. in the internal encoding.
 */
 #define LOG4CXX_LOGLS(logger, level, message) do { \
                if (logger->isEnabledFor(level)) {\
@@ -2056,7 +2056,7 @@ Add a new logging event containing \c message to attached 
appender(s) if this lo
 Add a new logging event containing \c message to attached appender(s) if \c 
logger is enabled for <code>DEBUG</code> events.
 
 @param logger the logger that has the enabled status.
-@param message a valid r-value expression of an 
<code>operator<<(std::basic::ostream&. ...)</code> overload.
+@param message a valid r-value expression of an 
<code>operator<<(std::ostream&. ...)</code> overload.
 
 <p>Example:
 ~~~{.cpp}
@@ -2079,7 +2079,7 @@ LOG4CXX_DEBUG(m_log, "AddMesh:"
 Add a new logging event containing libfmt formatted <code>...</code> to 
attached appender(s) if \c logger is enabled for <code>DEBUG</code> events.
 
 @param logger the logger to be used.
-@param ... The format string and message to log
+@param ... The format string and parameters that define the log message.
 */
 #define LOG4CXX_DEBUG_FMT(logger, ...) do { \
                if 
(LOG4CXX_UNLIKELY(::log4cxx::Logger::isDebugEnabledFor(logger))) {\
@@ -2094,7 +2094,7 @@ Add a new logging event containing libfmt formatted 
<code>...</code> to attached
 Add a new logging event containing \c message to attached appender(s) if \c 
logger is enabled for <code>TRACE</code> events.
 
 @param logger the logger that has the enabled status.
-@param message a valid r-value expression of an 
<code>operator<<(std::basic::ostream&. ...)</code> overload.
+@param message a valid r-value expression of an 
<code>operator<<(std::ostream&. ...)</code> overload.
 
 <p>Example:
 ~~~{.cpp}
@@ -2111,7 +2111,7 @@ Add a new logging event containing \c message to attached 
appender(s) if \c logg
 Add a new logging event containing libfmt formatted <code>...</code> to 
attached appender(s) if \c logger is enabled for <code>TRACE</code> events.
 
 @param logger the logger to be used.
-@param ... The format string and message to log
+@param ... The format string and parameters that define the log message.
 */
 #define LOG4CXX_TRACE_FMT(logger, ...) do { \
                if 
(LOG4CXX_UNLIKELY(::log4cxx::Logger::isTraceEnabledFor(logger))) {\
@@ -2126,7 +2126,7 @@ Add a new logging event containing libfmt formatted 
<code>...</code> to attached
 Add a new logging event containing \c message to attached appender(s) if \c 
logger is enabled for <code>INFO</code> events.
 
 @param logger the logger that has the enabled status.
-@param message a valid r-value expression of an 
<code>operator<<(std::basic::ostream&. ...)</code> overload.
+@param message a valid r-value expression of an 
<code>operator<<(std::ostream&. ...)</code> overload.
 
 <p>Example:
 ~~~{.cpp}
@@ -2147,7 +2147,7 @@ LOG4CXX_INFO(m_log, surface->GetName()
 Add a new logging event containing libfmt formatted <code>...</code> to 
attached appender(s) if \c logger is enabled for <code>INFO</code> events.
 
 @param logger the logger to be used.
-@param ... The format string and message to log
+@param ... The format string and parameters that define the log message.
 */
 #define LOG4CXX_INFO_FMT(logger, ...) do { \
                if (::log4cxx::Logger::isInfoEnabledFor(logger)) {\
@@ -2162,7 +2162,7 @@ Add a new logging event containing libfmt formatted 
<code>...</code> to attached
 Add a new logging event containing \c message to attached appender(s) if \c 
logger is enabled for <code>WARN</code> events.
 
 @param logger the logger to be used.
-@param message the message string to log.
+@param message a valid r-value expression of an 
<code>operator<<(std::ostream&. ...)</code> overload.
 
 <p>Example:
 ~~~{.cpp}
@@ -2181,7 +2181,7 @@ catch (const std::exception& ex)
 Add a new logging event containing libfmt formatted <code>...</code> to 
attached appender(s) if \c logger is enabled for <code>WARN</code> events.
 
 @param logger the logger to be used.
-@param ... The format string and message to log
+@param ... The format string and parameters that define the log message.
 */
 #define LOG4CXX_WARN_FMT(logger, ...) do { \
                if (::log4cxx::Logger::isWarnEnabledFor(logger)) {\
@@ -2196,7 +2196,7 @@ Add a new logging event containing libfmt formatted 
<code>...</code> to attached
 Add a new logging event containing \c message to attached appender(s) if \c 
logger is enabled for <code>ERROR</code> events.
 
 @param logger the logger to be used.
-@param message the message string to log.
+@param message a valid r-value expression of an 
<code>operator<<(std::ostream&. ...)</code> overload.
 
 <p>Example:
 ~~~{.cpp}
@@ -2215,7 +2215,7 @@ catch (std::exception& ex)
 Add a new logging event containing libfmt formatted <code>...</code> to 
attached appender(s) if \c logger is enabled for <code>ERROR</code> events.
 
 @param logger the logger to be used.
-@param ... The format string and message to log
+@param ... The format string and parameters that define the log message.
 */
 #define LOG4CXX_ERROR_FMT(logger, ...) do { \
                if (::log4cxx::Logger::isErrorEnabledFor(logger)) {\
@@ -2226,7 +2226,7 @@ If \c condition is not true, add a new logging event 
containing \c message to at
 
 @param logger the logger to be used.
 @param condition condition
-@param message the message string to log.
+@param message a valid r-value expression of an 
<code>operator<<(std::ostream&. ...)</code> overload.
 */
 #define LOG4CXX_ASSERT(logger, condition, message) do { \
                if (!(condition) && 
::log4cxx::Logger::isErrorEnabledFor(logger)) {\
@@ -2239,7 +2239,7 @@ If \c condition is not true, add a new logging event 
containing libfmt formatted
 
 @param logger the logger to be used.
 @param condition condition
-@param ... The format string and message to log
+@param ... The format string and parameters that define the log message.
 */
 #define LOG4CXX_ASSERT_FMT(logger, condition, ...) do { \
                if (!(condition) && 
::log4cxx::Logger::isErrorEnabledFor(logger)) {\
@@ -2258,7 +2258,7 @@ If \c condition is not true, add a new logging event 
containing libfmt formatted
 Add a new logging event containing \c message to attached appender(s) if \c 
logger is enabled for <code>FATAL</code> events.
 
 @param logger the logger to be used.
-@param message the message string to log.
+@param message a valid r-value expression of an 
<code>operator<<(std::ostream&. ...)</code> overload.
 
 <p>Example:
 ~~~{.cpp}
@@ -2274,7 +2274,7 @@ LOG4CXX_FATAL(m_log, m_renderSystem->getName() << " is 
not supported");
 Add a new logging event containing libfmt formatted <code>...</code> to 
attached appender(s) if \c logger is enabled for <code>FATAL</code> events.
 
 @param logger the logger to be used.
-@param ... The format string and message to log
+@param ... The format string and parameters that define the log message.
 */
 #define LOG4CXX_FATAL_FMT(logger, ...) do { \
                if (::log4cxx::Logger::isFatalEnabledFor(logger)) {\
diff --git a/src/main/include/log4cxx/net/smtpappender.h 
b/src/main/include/log4cxx/net/smtpappender.h
index 81d32650..39add9ec 100644
--- a/src/main/include/log4cxx/net/smtpappender.h
+++ b/src/main/include/log4cxx/net/smtpappender.h
@@ -65,38 +65,8 @@ The following <b>param</b> elements  are optional:
   is greater or equal to <b>ERROR</b>.
 
   An example configuration is:
-~~~{.xml}
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/";>
-  <appender name="A1" class="RollingFileAppender">
-    <param name="File"   value="${TEMP}/SomeApplicationName.log" />
-    <param name="Append" value="true" />
-    <layout class="PatternLayout">
-      <param name="ConversionPattern" value="%d %-5p %c{2} - %m%n"/>
-    </layout>
-  </appender>
-  <appender name="SENDMAIL" class="SMTPAppender">
-    <param name="from"   value="[email protected]" />
-    <param name="to" value="[email protected]" />
-    <param name="subject" value="Service error detected" />
-    <param name="SMTPHost" value="smtp.example.com"/>
-    <layout class="PatternLayout">
-               <param name="ConversionPattern" value="%-5p %c{2} - %m%n"/>
-    </layout>
-    <!-- triggeringPolicy class="SpecialTriggeringEventEvaluator" -->
-    <!-- param name="evaluatorClass" value="SpecialTriggeringEventEvaluator" 
-->
-  </appender>
-  <appender name="ASYNC" class="AsyncAppender">
-    <param name="BufferSize" value="1000"/>
-    <param name="Blocking" value="false"/>
-    <appender-ref ref="SENDMAIL"/>
-  </appender>
-  <root>
-    <priority value ="INFO" />
-    <appender-ref ref="A1" />
-    <appender-ref ref="ASYNC" />
-  </root>
-</log4j:configuration>
-~~~
+  \include async-example.xml
+
 */
 class LOG4CXX_EXPORT SMTPAppender : public AppenderSkeleton
 {
diff --git a/src/site/doxy/Doxyfile.in b/src/site/doxy/Doxyfile.in
index 5526f61c..2809aa80 100644
--- a/src/site/doxy/Doxyfile.in
+++ b/src/site/doxy/Doxyfile.in
@@ -1065,7 +1065,7 @@ EXCLUDE_SYMBOLS        =
 # that contain example code fragments that are included (see the \include
 # command).
 
-EXAMPLE_PATH           = src/examples/cpp
+EXAMPLE_PATH           = src/examples/cpp src/examples/config
 
 # If the value of the EXAMPLE_PATH tag contains directories, you can use the
 # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
diff --git a/src/site/markdown/1-usage.md b/src/site/markdown/1-usage.md
index 4cb5694e..ee88b2e2 100644
--- a/src/site/markdown/1-usage.md
+++ b/src/site/markdown/1-usage.md
@@ -23,16 +23,18 @@ Usage {#usage-overview}
 
 See the following pages for usage information:
 
-* @subpage usage
-* @subpage nested-diagnostic-contexts
-* @subpage filters
-* @subpage threading
-* @subpage extending-log4cxx
-* @subpage stacktrace-support
-* @subpage faq
+* @subpage quick-start
+* @subpage concepts
 * @subpage configuration-samples
+* @subpage filters
 * @subpage qt-support
-* @subpage performance
+* @subpage stacktrace-support
+* @subpage extending-log4cxx
+* @subpage threading
 * @subpage multiprocess-logging
 * @subpage environment-variables
 * @subpage macros-influencing-log4cxx
+* @subpage internal-debugging
+* @subpage performance
+* @subpage conclusions
+* @subpage faq
diff --git a/src/site/markdown/usage.md b/src/site/markdown/concepts.md
similarity index 59%
rename from src/site/markdown/usage.md
rename to src/site/markdown/concepts.md
index 2450fdbb..835158d3 100644
--- a/src/site/markdown/usage.md
+++ b/src/site/markdown/concepts.md
@@ -1,4 +1,4 @@
-Loggers, Appenders and Layouts {#usage}
+Loggers, Appenders and Layouts {#concepts}
 ===
 <!--
  Note: License header cannot be first, as doxygen does not generate
@@ -27,19 +27,37 @@ These three types of components work together to enable 
developers to
 log messages according to message type and level, and to control at
 runtime how these messages are formatted and where they are reported.
 
+Configuration of the Log4cxx environment is typically done at
+application initialization. The preferred way is by reading a
+configuration file. This approach was discussed in [Runtime Configuration].
+
 # Loggers {#loggers}
 
 The first and foremost advantage of any logging API over plain
 `std::cout` 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.
+while allowing others to print unhindered. This capability is provided
+by assigning each logging request to a category.
+A Log4cxx category is a name and it is held by a log4cxx::Logger instance.
+The name of the class in which the logging request appears
+is a commonly used naming scheme
+but any category naming scheme may be used.
+Logging category names (or equivalently logger name)
+are case-sensitive.
 
-Loggers are named entities. Logger names are case-sensitive and they
-follow the hierarchical naming rule:
+Log4cxx makes it easy to name loggers by *software component*. 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.
 
-## Hierarchy {#hierarchy}
+Nevertheless, naming loggers after the class where they are located
+seems to be the best strategy known so far.
 
+Logger names follow a hierarchical naming rule.
 A logger is said to be an *ancestor* of another logger if its name
 followed by a dot is a prefix of the *descendant* logger name. A logger
 is said to be a *parent* of a *child* logger if there are no ancestors
@@ -50,17 +68,25 @@ named `com.foo.Bar`. Similarly, `java` is a parent of 
`java.util`
 and an ancestor of `java.util.Vector`. This naming scheme should be
 familiar to most developers.
 
-The root logger resides at the top of the logger hierarchy. It is
+The root logger resides at the top of the hierarchy. It is
 exceptional in two ways:
 
 1.  it always exists,
 2.  it cannot be retrieved by name.
 
-Invoking the class static
-log4cxx::Logger::getRootLogger method retrieves it. All other loggers are 
instantiated and retrieved
-with the class static log4cxx::Logger::getLogger
-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.
+Use the class static method
+log4cxx::Logger::getRootLogger or
+log4cxx::LogManager::getRootLogger to retrieve it.
+
+All other loggers are held in a log4cxx::spi::LoggerRepository singleton.
+They can be retrieved by calling a log4cxx::Logger::getLogger
+static class method which takes the name of the desired logger as an argument.
+An instance of log4cxx::Logger is instantiated
+if a logger of that name is not already held
+by the log4cxx::spi::LoggerRepository instance.
+
+The core Log4cxx API is made available by <code>\#include 
<log4cxx/logger.h></code>.
+The commonly used log4cxx/logger.h methods and macros are listed below.
 
 ~~~{.cpp}
     namespace log4cxx {
@@ -76,8 +102,8 @@ Some of the basic methods in the Logger class are listed 
below.
     //
     // Use these macros instead of calling Logger methods directly.
     // Macros will handle char or wchar_t pointers or strings
-    // or most right-hand side expressions of an
-    // std::basic_string::operator<<.
+    // and any object that provides a
+    // <code>operator<<(std::ostream&, ...)</code> overload.
     //
     #define LOG4CXX_TRACE(logger, expression) ...
     #define LOG4CXX_DEBUG(logger, expression) ...
@@ -87,105 +113,284 @@ Some of the basic methods in the Logger class are listed 
below.
     #define LOG4CXX_FATAL(logger, expression) ...
 ~~~
 
+Calling the *getLogger* method with the same name will always return a
+reference to the exact same logger object.
+
+For example, in
+
+~~~{.cpp}
+    auto x = log4cxx::Logger::getLogger("wombat");
+    auto y = log4cxx::Logger::getLogger("wombat");
+~~~
+
+*x* and *y* refer to *exactly* the same logger object.
+
+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.
+
+## Requests {#requests}
+
+Logging requests are made by invoking a method of a logger instance,
+preferrably through the use of LOG4CXX\_INFO or similar macros which
+support short-circuiting if the threshold is not satisfied and use of
+the insertion operator (\<\<) in the message parameter.
+
+~~~{.cpp}
+    log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("com.foo"));
+    const char* region = "World";
+    LOG4CXX_INFO(logger, "Simple message text.");
+    LOG4CXX_INFO(logger, "Hello, " << region);
+    LOG4CXX_DEBUG(logger, L"Iteration " << i);
+    LOG4CXX_DEBUG(logger, "e^10 = " << std::scientific << exp(10.0));
+    //
+    // Use a wchar_t first operand to force use of wchar_t based stream.
+    //
+    LOG4CXX_WARN(logger, L"" << i << L" is the number of the iteration.");
+~~~
+
+### Logging Custom Types {#custom-types}
+
+Often, the data that needs to be logged is not just standard data types
+(such as int, string, etc), but amalgamations of those types in a data
+structure such as a class or struct.  In order to log these custom types,
+simply override an `operator<<` function, the same as if you would
+print the custom type to `std::cout`.  This can be accomplished by
+doing the following:
+
+~~~{.cpp}
+struct MyStruct {
+       int x;
+};
+
+std::ostream& operator<<( std::ostream& stream, const MyStruct& mystruct ){
+       stream << "[MyStruct x:" << mystruct.x << "]";
+       return stream;
+}
+
+void someMethod(){
+       MyStruct mine;
+       mine.x = 90;
+       LOG4CXX_INFO( logger, "Some important information: " << mine );
+}
+~~~
+
+This will output data similar to the following:
+
+~~~
+0 [0x7fd1eed63bc0] INFO root null - Some important information: [MyStruct x:90]
+~~~
+
+### Using {fmt} style requests {#logging-with-fmt}
+
+One issue with utilizing Log4cxx and its ostream style of logging is that log
+statements can be very awkward if you need to precisely format something:
+
+~~~{.cpp}
+LOG4CXX_INFO( rootLogger, "Numbers can be formatted with excessive operator<<: 
"
+                         << std::setprecision(3) << 22.456
+                         << " And as hex: "
+                         << std::setbase( 16 ) << 123 );
+~~~
+
+This leads to very awkward code to read and write, especially as iostreams 
don't
+support positional arguments at all.
+
+In order to get around this, one popular library(that has been standardized as
+part of C++20) is [{fmt}](https://fmt.dev/latest/index.html).  Supporting
+positional arguments and printf-like formatting, it makes for much clearer
+code like the following:
+
+~~~{.cpp}
+LOG4CXX_INFO_FMT( rootLogger, "Numbers can be formatted with a format string 
{:.1f} and as hex: {:x}", 22.456, 123 );
+~~~
+
+Note that Log4cxx does not include a copy of {fmt}, so you must include the
+correct headers and linker flags in order to use the `LOG4CXX_[level]_FMT`
+family of macros.
+
+As with the standard logger macros, these macros will also be compiled out
+if the `LOG4CXX_THRESHOLD` macro is set to a level that will compile out
+the non-FMT macros.
+
+A full example can be seen in the \ref format-string.cpp file.
+
+### Overhead {#request-cost}
+
+One of the often-cited arguments against logging is its computational
+cost. This is a legitimate concern as even moderately sized applications
+can generate thousands of log requests. Much effort was spent measuring
+and tweaking logging performance. Log4cxx claims to be fast and
+flexible: speed first, flexibility second.
+
+For performance sensitive applications, you should be aware of the following.
+
+1.  **Logging performance when logging is turned off.**
+
+    The LOG4CXX\_DEBUG and similar macros have a
+    cost of an in-lined null pointer check plus an integer comparison
+    when the logger not currently enabled for that level.
+    The other terms inside the macro are not evaluated.
+
+    When the level is enabled for a logger but the logging hierarchy is turned 
off
+    entirely or just for a set of levels, the cost of a log request consists
+    of a method invocation plus an integer comparison.
+
+2.  **Actually outputting log messages**
+
+    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.
+
+3.  **The cost of changing a logger's level.**
+
+    The threshold value stored in any child logger is updated.
+    This is done iterating over the map of all known logger objects
+    and walking the hierarchy of each.
+
+    There has been a serious effort to make this hierarchy walk to be as
+    fast as possible. For example, child loggers link only to their
+    existing ancestors. In the *BasicConfigurator* example shown
+    earlier, the logger named *com.foo.Bar* is linked directly to the
+    root logger, thereby circumventing the nonexistent *com* or
+    *com.foo* loggers. This significantly improves the speed of the
+    walk, especially in "sparse" hierarchies.
+
+### Removing log requests {#removing-log-statements}
+
+Sometimes, you may want to remove all log statements from your program,
+either for speed purposes or to remove sensitive information.  This can easily
+be accomplished at build-time when using the standard `LOG4CXX_[level]` macros
+(`LOG4CXX_TRACE`, `LOG4CXX_DEBUG`, `LOG4CXX_INFO`, `LOG4CXX_WARN`,
+`LOG4CXX_ERROR`, `LOG4CXX_FATAL`)
+or their {fmt} library equivalents
+(`LOG4CXX_TRACE_FMT`, `LOG4CXX_DEBUG_FMT`, `LOG4CXX_INFO_FMT`, 
`LOG4CXX_WARN_FMT`,
+`LOG4CXX_ERROR_FMT`, `LOG4CXX_FATAL_FMT`).
+
+Log statements can be removed either above a certain level, or they
+can be disabled entirely.
+
+For example, if we want to remove all log statements within our program
+that use the `LOG4CXX_[level]` family of macros, add a preprocessor
+definition `LOG4CXX_THRESHOLD` set to 50001
+or greater.  This will ensure that any log statement that uses the
+`LOG4CXX_[level]`-macro will be compiled out of the program.  To remove
+all log statements at `DEBUG` or below, set `LOG4CXX_THRESHOLD` to a
+value between 10001-20000.
+
+The levels are set as follows:
+
+|Logger Level|Integer Value|
+|------------|-------------|
+|TRACE       |5000         |
+|DEBUG       |10000        |
+|INFO        |20000        |
+|WARN        |30000        |
+|ERROR(1)    |40000        |
+|FATAL       |50000        |
+
+(1) The `LOG4CXX_ASSERT` macro is the same level as `LOG4CXX_ERROR`
+
+Note that this has no effect on other macros, such as using the
+`LOG4CXX_LOG`, `LOG4CXX_LOGLS`, or `LOG4CXX_L7DLOG` family of macros.
+
+### Removing location information {#removing-location-information}
+
+Whenever you log a message with Log4cxx, metadata about the location of the
+logging statement is captured as well through the preprocessor.  This includes
+the file name, the method name, and the line number.  If you would not like to
+include this information in your build but you still wish to keep the log
+statements, define `LOG4CXX_DISABLE_LOCATION_INFO` in your build system.  This
+will allow log messages to still be created, but the location information
+will be invalid.
+
 ## Levels {#levels}
 
-Loggers *may* be assigned levels. The pre-defined levels: TRACE, DEBUG,
-INFO, WARN, ERROR and FATAL are defined in the
-log4cxx::Level class which provides accessor functions.
+A log4cxx::Logger instance *may* be assigned a specific level
+otherwise it will inherit it from the
+closest ancestor with an assigned level.
+The root logger always has an assigned level.
+
+The pre-defined levels: TRACE, DEBUG,
+INFO, WARN, ERROR and FATAL are available.
+These are defined in the log4cxx/level.h file.
+Additional levels may be registered by the application
+but this is not recommended (See [Custom_levels]).
 
-If a given logger is not assigned a level, then it inherits one from its
-closest ancestor with an assigned level. More formally:
+A logging request is said to be *enabled* if its level is higher than or
+equal to the level of its logger. Otherwise, the request is said to be
+*disabled*. A logger without an assigned level will inherit one from the
+hierarchy. This rule is summarized below.
 
 ### Level Inheritance {#level-inheritance}
 
-The *inherited level* for a given logger *C*, is equal to the first
-non-null level in the logger hierarchy, starting at *C* and proceeding
+The *effective level* for a given logger *X.Y.Z*, is equal to the first
+assigned in the logger hierarchy, starting at *X.Y.Z* and proceeding
 upwards in the hierarchy towards the *root* logger.
 
 To ensure that all loggers can eventually inherit a level, the root
 logger always has an assigned level.
 
 Below are four tables with various assigned level values and the
-resulting inherited levels according to the above rule.
+resulting effective levels according to the above rule.
 
-| Logger name | Assigned level | Inherited level |
+| Logger name | Assigned level | Effective level |
 | ----------- | -------------- | --------------- |
-| root        | Proot          | Proot           |
-| X           | none           | Proot           |
-| X.Y         | none           | Proot           |
-| X.Y.Z       | none           | Proot           |
+| root        | INFO           | INFO            |
+| X           | none           | INFO            |
+| X.Y         | none           | INFO            |
+| X.Y.Z       | none           | INFO            |
 
 Example 1
 
 In example 1 above, only the root logger is assigned a level. This level
-value, *Proot*, is inherited by the other loggers *X*, *X.Y* and
+value, *INFO*, is inherited by the other loggers *X*, *X.Y* and
 *X.Y.Z*.
 
-| Logger name | Assigned level | Inherited level |
+| Logger name | Assigned level | Effective level |
 | ----------- | -------------- | --------------- |
-| root        | Proot          | Proot           |
-| X           | Px             | Px              |
-| X.Y         | Pxy            | Pxy             |
-| X.Y.Z       | Pxyz           | Pxyz            |
+| root        | INFO           | INFO            |
+| X           | WARN           | WARN            |
+| X.Y         | DEBUG          | DEBUG           |
+| X.Y.Z       | TRACE          | TRACE           |
 
 Example 2
 
-In example 2, all loggers have an assigned level value. There is no need
-for level inheritence.
+In example 2, all loggers have an assigned level value. There is no
+use of level inheritence.
 
-| Logger name | Assigned level | Inherited level |
+| Logger name | Assigned level | Effective level |
 | ----------- | -------------- | --------------- |
-| root        | Proot          | Proot           |
-| X           | Px             | Px              |
-| X.Y         | none           | Px              |
-| X.Y.Z       | Pxyz           | Pxyz            |
+| root        | INFO           | INFO            |
+| X           | DEBUG          | DEBUG           |
+| X.Y         | none           | DEBUG           |
+| X.Y.Z       | WARN           | WARN            |
 
 Example 3
 
 In example 3, the loggers *root*, *X* and *X.Y.Z* are assigned the
-levels *Proot*, *Px* and *Pxyz* respectively. The logger *X.Y* inherits
-its level value from its parent *X*.
+levels *INFO*, *DEBUG* and *WARN* respectively. The logger *X.Y* inherits
+its level from its parent *X*.
 
-| Logger name | Assigned level | Inherited level |
+| Logger name | Assigned level | Effective level |
 | ----------- | -------------- | --------------- |
-| root        | Proot          | Proot           |
-| X           | Px             | Px              |
-| X.Y         | none           | Px              |
-| X.Y.Z       | none           | Px              |
+| root        | INFO           | INFO            |
+| X           | DEBUG          | DEBUG           |
+| X.Y         | none           | DEBUG           |
+| X.Y.Z       | none           | DEBUG           |
 
 Example 4
 
 In example 4, the loggers *root* and *X* and are assigned the levels
-*Proot* and *Px* respectively. The loggers *X.Y* and *X.Y.Z* inherits
-their level value from their nearest parent *X* having an assigned
-level.
-
-## Requests {#requests}
-
-Logging requests are made by invoking a method of a logger instance,
-preferrably through the use of LOG4CXX\_INFO or similar macros which
-support short-circuiting if the threshold is not satisfied and use of
-the insertion operator (\<\<) in the message parameter.
-
-~~~{.cpp}
-    log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("com.foo"));
-    const char* region = "World";
-    LOG4CXX_INFO(logger, "Simple message text.");
-    LOG4CXX_INFO(logger, "Hello, " << region);
-    LOG4CXX_DEBUG(logger, L"Iteration " << i);
-    LOG4CXX_DEBUG(logger, "e^10 = " << std::scientific << exp(10.0));
-    //
-    // Use a wchar_t first operand to force use of wchar_t based stream.
-    //
-    LOG4CXX_WARN(logger, L"" << i << L" is the number of the iteration.");
-~~~
-
-A logging request is said to be *enabled* if its level is higher than or
-equal to the level of its logger. Otherwise, the request is said to be
-*disabled*. A logger without an assigned level will inherit one from the
-hierarchy. This rule is summarized below.
+*INFO* and *DEBUG* respectively. The loggers *X.Y* and *X.Y.Z* inherit
+their level from their nearest parent having an assigned
+level, *X*.
 
-## Basic Selection Rule {#selection-rule}
+### Basic Selection Rule {#selection-rule}
 
 A log request of level *p* in a logger with (either assigned or
 inherited, whichever is appropriate) level *q*, is enabled if *p \>= q*.
@@ -223,42 +428,6 @@ Here is an example of this rule.
     LOG4CXX_DEBUG(barlogger, "Exiting gas station search");
 ~~~
 
-Calling the *getLogger* method with the same name will always return a
-reference to the exact same logger object.
-
-For example, in
-
-~~~{.cpp}
-    auto x = log4cxx::Logger::getLogger("wombat");
-    auto y = log4cxx::Logger::getLogger("wombat");
-~~~
-
-*x* and *y* refer to *exactly* the same logger object.
-
-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.
-
-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.
-
-Log4cxx makes it easy to name loggers by *software component*. 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.
-
-Nevertheless, naming loggers after the class where they are located
-seems to be the best strategy known so far.
-
 # Appenders {#appenders}
 
 The ability to selectively enable or disable logging requests based on
@@ -279,6 +448,7 @@ If the same file receives log requests concurrently from 
multiple process,
 use [this appender](@ref log4cxx.rolling.MultiprocessRollingFileAppender).
 It is also possible to log [asynchronously](@ref log4cxx.AsyncAppender)
 to another appender.
+See \ref async-example.xml
 
 The [addAppender](@ref log4cxx.Logger.addAppender)
 method adds an appender to a given logger.
@@ -351,395 +521,84 @@ third field is the level of the log statement. The 
fourth field is the
 name of the logger associated with the log request. The text after the
 '-' is the message of the statement.
 
-The other layouts provided in Log4cxx are:
-
-- [libfmt patterns](@ref log4cxx.FMTLayout)
-- [a HTML table](@ref log4cxx.HTMLLayout)
-- [a JSON dictionary](@ref log4cxx.JSONLayout)
-- [level - message](@ref log4cxx.SimpleLayout)
-- [log4j event elements](@ref log4cxx.xml.XMLLayout)
-
-# Example Programs {#coding}
-
-Creating useful log information 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.
-
-Let us give a taste of how this is done with the help of an imaginary
-application *MyApp* that uses Log4cxx.
-
-## A Simple Example {#example1}
-
-In order to start using Log4cxx, a simple example program is shown below.
-This program does nothing useful, but it shows the basics of how to start 
using Log4cxx.
-Using the [BasicConfigurator](@ref log4cxx.BasicConfigurator) class, we are 
able to quickly configure the library
-to output DEBUG, INFO, etc level messages to standard output.
-\include MyApp1.cpp
-
-The above application does nothing useful except to show how to initialize 
logging
-with the BasicConfigurator and do logging with different loggers.
-Note that file based configurations are also possible -
-see [DOMConfigurator](@ref log4cxx.xml.DOMConfigurator.configure)
-and [PropertyConfigurator](@ref log4cxx.PropertyConfigurator.configure).
-
-Configuring Log4cxx in the main function has the limitation that
-any logging statements in static initialization code will not generate output.
-Log4cxx must be configured before it is used and
-in this example Log4cxx is not configured until the main() function starts.
-
-## A Less Simple Example {#example2}
-
-In this example we use a *getLogger()* wrapper function
-which configures Log4cxx on the first usage.
-The advantages of this approach are:
-
-- Log4cxx configuration can be reused in multiple applications.
-- The structure exhibits better [separation of 
concerns](https://en.wikipedia.org/wiki/Separation_of_concerns).
-- Log statements in static initialization code will generate output.
-
-This program (*MyApp*) begins by including the file
-that defines the com::foo::getLogger() function.
-It obtains a logger named *MyApp*
-(which in this example is the fully qualified name)
-from the com::foo::getLogger() function.
-
-*MyApp* uses the *com::foo::Bar* class defined in header file *com/foo/bar.h*.
-\include MyApp2.cpp
-
-The *com::foo::Bar* class is defined in header file *com/foo/bar.h*.
-\include com/foo/bar.h
-
-The *com::foo::Bar* class is implemented in the file *com/foo/bar.cpp*.
-\include com/foo/bar.cpp
-
-The header file *com/foo/config.h* defines the com::foo::getLogger() function
-and a *LoggerPtr* type for convenience.
-\include com/foo/config.h
-
-The file *com/foo/config.cpp* which implements the com::foo::getLogger() 
function
-defines *initAndShutdown* as a *static struct* so its constructor
-is invoked on the first call to the com::foo::getLogger() function
-and its destructor is automatically called during application exit.
-\include com/foo/config1.cpp
+The following examples show how you might configure the PatternLayout in order 
to
+achieve the results shown.
+Each example has two blocks of code: the layout for the PatternLayout,
+and a sample output message.
 
-The invocation of the
-[BasicConfigurator::configure](@ref log4cxx.BasicConfigurator.configure)
-method creates a rather simple Log4cxx setup. This method is hardwired
-to add to the root logger a [ConsoleAppender](@ref log4cxx.ConsoleAppender).
-The output will be formatted using a
-[PatternLayout](@ref log4cxx.PatternLayout)
-set to the pattern `%%r [%%t] %%p %%c %%x - %%m%%n`.
+## Pattern 1 {#pattern1}
 
-Note that by default, the root logger is assigned a *DEBUG* level.
-
-The output of MyApp is:
+This pattern contains the date in an ISO-8601 format(without fractional 
seconds),
+followed by the logger name, the level, and then the message.
 
 ~~~
-    0 [12345] INFO MyApp null - Entering application.
-    0 [12345] DEBUG com.foo.Bar null - Did it again!
-    0 [12345] INFO MyApp null - Exiting application.
+[%d{yyyy-MM-dd HH:mm:ss}] %c %-5p - %m%n
 ~~~
 
-## Runtime Configuration {#configuration}
-
-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 Java
-properties (key=value) format.
-
-The previous example always outputs the same log information.
-Fortunately, it is easy to modify *config.cpp* so that the log output can be
-controlled at runtime. Here is a slightly modified version.
-\include com/foo/config2.cpp
-
-This version of *config.cpp* instructs [PropertyConfigurator](@ref 
log4cxx.PropertyConfigurator.configure)
-to use the *MyApp.properties* file to configure Log4cxx.
-A more realistic approach would (for example)
-use the current module name to select the configuration file
-(see the \ref com/foo/config3.cpp file for how to do this).
-
-Here is a sample *MyApp.properties* configuration file that results in exactly 
same output
-as the previous [BasicConfigurator::configure](@ref 
log4cxx.BasicConfigurator.configure) based example.
-
 ~~~
-    # Set root logger level to DEBUG and its only appender to A1.
-    log4j.rootLogger=DEBUG, A1
-
-    # A1 is set to be a ConsoleAppender.
-    log4j.appender.A1=org.apache.log4j.ConsoleAppender
-
-    # A1 uses PatternLayout.
-    log4j.appender.A1.layout=org.apache.log4j.PatternLayout
-    log4j.appender.A1.layout.ConversionPattern=%r [%t] %-5p %c %x - %m%n
+[2020-12-24 15:31:46] root INFO  - Hello there!
 ~~~
 
-It can be noticed that the PropertyConfigurator file format is the same
-as log4j.
+## Pattern 2 {#pattern2}
 
-Suppose we are no longer interested in seeing the output of any
-component belonging to the *com::foo* package. The following
-configuration file shows one possible way of achieving this.
+Similar to Pattern 1, except using ISO-8601 with fractional seconds
 
 ~~~
-    log4j.rootLogger=DEBUG, A1
-    log4j.appender.A1=org.apache.log4j.ConsoleAppender
-    log4j.appender.A1.layout=org.apache.log4j.PatternLayout
-
-    # Print the date in ISO 8601 format
-    log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
-
-    # Print only messages of level WARN or above in the package com.foo.
-    log4j.logger.com.foo=WARN
+[%d] %c %-5p - %m%n
 ~~~
 
-The output of *MyApp* configured with this file is shown below.
-
 ~~~
-    2022-12-13 11:01:45,091 [12345] INFO  MyApp - Entering application.
-    2022-12-13 11:01:45,091 [12345] INFO  MyApp - Exiting application.
+[2020-12-24 15:35:39,225] root INFO  - Hello there!
 ~~~
 
-As the logger *com.foo.Bar* does not have an assigned level, it inherits
-its level from *com.foo*, which was set to WARN in the configuration
-file. The log statement from the *Bar::doIt* method has the level *DEBUG*,
-lower than the logger level WARN. Consequently, *doIt()* method's log
-request is suppressed.
-
-Here is another configuration file that uses multiple appenders.
-\include MyApp.properties
+## Pattern 3 {#pattern3}
 
-Calling the enhanced MyApp with the this configuration file will output
-the following on the console.
+Prints out the number of milliseconds since the start of the application,
+followed by the level(5 character width), followed by the logger name
+(20 character width), followed by the message.
 
 ~~~
-     INFO [12345] (MyApp.cpp:8) - Entering application.
-    DEBUG [12345] (bar.cpp:8) - Did it again!
-     INFO [12345] (MyApp.cpp:11) - Exiting application.
-~~~
-
-In addition, as the root logger has been allocated a second appender,
-output will also be directed to the *example.log* file. This file will
-be rolled over when it reaches 100KB. When roll-over occurs, the old
-version of *example.log* is automatically moved to *example.log.1*.
-
-Note that to obtain these different logging behaviors we did not need to
-recompile code. We could just as easily have logged to a UNIX Syslog
-daemon, redirected all *com.foo* output to an NT Event logger, or
-forwarded logging events to a remote Log4cxx server, which would log
-according to local server policy, for example by forwarding the log
-event to a second Log4cxx server.
-
-# Default Initialization {#default-initialization}
-
-The Log4cxx library does not make any assumptions about its environment.
-In particular, when initially created the root [Logger](@ref log4cxx.Logger) 
has no appender.
-However the library will attempt automatic configuration.
-
-If the LoggerRepositoy is not yet configured on the first call to
-[getLogger](@ref log4cxx.LogManager.getLogger) of [LogManager](@ref 
log4cxx.LogManager),
-the [configure](@ref log4cxx.DefaultConfigurator.configure) method
-of [DefaultConfigurator](@ref log4cxx.DefaultConfigurator) is called
-via [ensureIsConfigured](@ref log4cxx.spi.LoggerRepository.ensureIsConfigured) 
method
-of [LoggerRepository](@ref log4cxx.spi.LoggerRepository).
-
-To use automatic configuration with a non-standard file name
-create and use your own wrapper for [getLogger](@ref 
log4cxx.LogManager.getLogger).
-A full example can be seen in the \ref com/foo/config3.cpp file.
-
-# Logging Custom Types {#custom-types}
-
-Often, the data that needs to be logged is not just standard data types
-(such as int, string, etc), but amalgamations of those types in a data
-structure such as a class or struct.  In order to log these custom types,
-simply override an `operator<<` function, the same as if you would
-print the custom type to `std::cout`.  This can be accomplished by
-doing the following:
-
-~~~{.cpp}
-struct MyStruct {
-       int x;
-};
-
-std::ostream& operator<<( std::ostream& stream, const MyStruct& mystruct ){
-       stream << "[MyStruct x:" << mystruct.x << "]";
-       return stream;
-}
-
-void someMethod(){
-       MyStruct mine;
-       mine.x = 90;
-       LOG4CXX_INFO( logger, "Some important information: " << mine );
-}
+%r %-5p %-20c %m%n
 ~~~
 
-This will output data similar to the following:
-
 ~~~
-0 [0x7fd1eed63bc0] INFO root null - Some important information: [MyStruct x:90]
+0 INFO  root                 Hello there!
 ~~~
 
-# Logging with {fmt} {#logging-with-fmt}
+## Pattern 4 {#pattern4}
 
-One issue with utilizing Log4cxx and its ostream style of logging is that log
-statements can be very awkward if you need to precisely format something:
+If you have no idea where a log message is coming from, it's possible to print
+out more information about the place the log statement is coming from.  For 
example,
+we can get the filename, class name, method name, and line number in one log
+message.  This utilises the %%F(file name), %%C(class name), %%M(method name), 
%%L(line number)
+patterns to output more information:
 
-~~~{.cpp}
-LOG4CXX_INFO( rootLogger, "Numbers can be formatted with excessive operator<<: 
"
-                         << std::setprecision(3) << 22.456
-                         << " And as hex: "
-                         << std::setbase( 16 ) << 123 );
 ~~~
-
-This leads to very awkward code to read and write, especially as iostreams 
don't
-support positional arguments at all.
-
-In order to get around this, one popular library(that has been standardized as
-part of C++20) is [{fmt}](https://fmt.dev/latest/index.html).  Supporting
-positional arguments and printf-like formatting, it makes for much clearer
-code like the following:
-
-~~~{.cpp}
-LOG4CXX_INFO_FMT( rootLogger, "Numbers can be formatted with a format string 
{:.1f} and as hex: {:x}", 22.456, 123 );
+(%F:%C[%M]:%L) %m%n
 ~~~
 
-Note that Log4cxx does not include a copy of {fmt}, so you must include the
-correct headers and linker flags in order to use the `LOG4CXX_[level]_FMT`
-family of macros.
-
-As with the standard logger macros, these macros will also be compiled out
-if the `LOG4CXX_THRESHOLD` macro is set to a level that will compile out
-the non-FMT macros.
-
-A full example can be seen in the \ref format-string.cpp file.
-
-# Internal Debugging {#internal-debugging}
-
-Because Log4cxx is a logging library, we can't use it to output errors from
-the library itself.  There are several ways to activate internal logging:
-
-1. Configure the library directly by calling the
-[LogLog::setInternalDebugging](@ref 
log4cxx.helpers.LogLog.setInternalDebugging)
-method
-2. If using a properties file, set the value `log4j.debug=true` in your 
configuration file
-3. If using an XML file, set the attribute `internalDebug=true` in the root 
node
-4. From the environment: `LOG4CXX_DEBUG=true`
-
-All error and warning messages are sent to stderr.
-
-# Overhead {#request-cost}
-
-One of the often-cited arguments against logging is its computational
-cost. This is a legitimate concern as even moderately sized applications
-can generate thousands of log requests. Much effort was spent measuring
-and tweaking logging performance. Log4cxx claims to be fast and
-flexible: speed first, flexibility second.
-
-For performance sensitive applications, you should be aware of the following.
-
-1.  **Logging performance when logging is turned off.**
-
-    The LOG4CXX\_DEBUG and similar macros have a
-    cost of an in-lined null pointer check plus an integer comparison
-    when the logger not currently enabled for that level.
-    The other terms inside the macro are not evaluated.
-
-    When the level is enabled for a logger but the logging hierarchy is turned 
off
-    entirely or just for a set of levels, the cost of a log request consists
-    of a method invocation plus an integer comparison.
-
-2.  **Actually outputting log messages**
-
-    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.
-
-3.  **The cost of changing a logger's level.**
-
-    The threshold value stored in any child logger is updated.
-    This is done iterating over the map of all known logger objects
-    and walking the hierarchy of each.
-
-    There has been a serious effort to make this hierarchy walk to be as
-    fast as possible. For example, child loggers link only to their
-    existing ancestors. In the *BasicConfigurator* example shown
-    earlier, the logger named *com.foo.Bar* is linked directly to the
-    root logger, thereby circumventing the nonexistent *com* or
-    *com.foo* loggers. This significantly improves the speed of the
-    walk, especially in "sparse" hierarchies.
-
-## Removing log statements {#removing-log-statements}
-
-Sometimes, you may want to remove all log statements from your program,
-either for speed purposes or to remove sensitive information.  This can easily
-be accomplished at build-time when using the standard `LOG4CXX_[level]` macros
-(`LOG4CXX_TRACE`, `LOG4CXX_DEBUG`, `LOG4CXX_INFO`, `LOG4CXX_WARN`,
-`LOG4CXX_ERROR`, `LOG4CXX_FATAL`).
-
-Log statements can be removed either above a certain level, or they
-can be disabled entirely.
-
-For example, if we want to remove all log statements within our program
-that use the `LOG4CXX_[level]` family of macros, add a preprocessor
-definition `LOG4CXX_THRESHOLD` set to 50001
-or greater.  This will ensure that any log statement that uses the
-`LOG4CXX_[level]`-macro will be compiled out of the program.  To remove
-all log statements at `DEBUG` or below, set `LOG4CXX_THRESHOLD` to a
-value between 10001-20000.
-
-The levels are set as follows:
-
-|Logger Level|Integer Value|
-|------------|-------------|
-|TRACE       |5000         |
-|DEBUG       |10000        |
-|INFO        |20000        |
-|WARN        |30000        |
-|ERROR(1)    |40000        |
-|FATAL       |50000        |
-
-(1) The `LOG4CXX_ASSERT` macro is the same level as `LOG4CXX_ERROR`
-
-Note that this has no effect on other macros, such as using the
-`LOG4CXX_LOG`, `LOG4CXX_LOGLS`, or `LOG4CXX_L7DLOG` family of macros.
-
-## Removing location information {#removing-location-information}
-
-Whenever you log a message with Log4cxx, metadata about the location of the
-logging statement is captured as well through the preprocessor.  This includes
-the file name, the method name, and the line number.  If you would not like to
-include this information in your build but you still wish to keep the log
-statements, define `LOG4CXX_DISABLE_LOCATION_INFO` in your build system.  This
-will allow log messages to still be created, but the location information
-will be invalid.
-
-# Conclusions {#conclusions}
-
-Apache 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.
-
-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.
+Possible output:
+~~~
+(/home/robert/log4cxx-test-programs/fooclass.cpp:FooClass[FooClass]:9) 
Constructor running
+(/home/robert/log4cxx-test-programs/fooclass.cpp:FooClass[doFoo]:13) Doing foo
+~~~
 
-\example trivial.cpp
-This example shows how to add a context string to each logging message using 
the NDC.
+Note that unlike Java logging, the location information is free(as it utilizes
+macros to determine this information at compile-time).
 
-\example auto-configured.cpp
-This is an example of logging in static initialization code and
-using the current module name to select the Log4cxx configuration file.
+The other layouts provided in Log4cxx are:
 
-\example com/foo/config3.cpp
-This file is an example of how to use the current module name to select the 
Log4cxx configuration file.
+- [libfmt patterns](@ref log4cxx.FMTLayout)
+- [a HTML table](@ref log4cxx.HTMLLayout)
+- [a JSON dictionary](@ref log4cxx.JSONLayout)
+- [level - message](@ref log4cxx.SimpleLayout)
+- [log4j event elements](@ref log4cxx.xml.XMLLayout)
 
 \example format-string.cpp
 This example shows logging using the 
[{fmt}](https://fmt.dev/latest/index.html) library.
+
+\example async-example.xml
+This example shows a configuration using the [asynchronous appender](@ref 
log4cxx.AsyncAppender).
+
+[Custom_levels]:faq.html#custom_levels
+[Runtime Configuration]:quick-start.html#configuration
diff --git a/src/site/markdown/multiprocess.md 
b/src/site/markdown/conclusions.md
similarity index 53%
copy from src/site/markdown/multiprocess.md
copy to src/site/markdown/conclusions.md
index 5c7e7100..4e3046ad 100644
--- a/src/site/markdown/multiprocess.md
+++ b/src/site/markdown/conclusions.md
@@ -1,4 +1,4 @@
-Multiprocess Logging {#multiprocess-logging}
+Conclusions {#conclusions}
 ===
 <!--
  Note: License header cannot be first, as doxygen does not generate
@@ -21,16 +21,15 @@ Multiprocess Logging {#multiprocess-logging}
  limitations under the License.
 -->
 
-# Logging With Multiple Processes
-
-If you have multiple applications that all log to the same file, it is often
-desirable that the file that these applications write to will roll over when
-required.  In order for that to happen, Log4cxx supplies a
-`MultiprocessRollingFileAppender` that will check the size of the file when
-writing to the file and roll it over appropriately.
-
-This is an optional feature, and thus must be explicitly enabled when building
-Log4cxx.  This feature is also only supported on Linux at the moment.
-Because this feature is non-standard, it may not work properly in all
-circumstances.
+Apache 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.
 
+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.
diff --git a/src/site/markdown/configuration-samples.md 
b/src/site/markdown/configuration-samples.md
index e11a3389..cdecdae8 100644
--- a/src/site/markdown/configuration-samples.md
+++ b/src/site/markdown/configuration-samples.md
@@ -21,79 +21,26 @@ Configuration Samples {#configuration-samples}
  limitations under the License.
 -->
 
-The following snippets show various ways of configuring Log4cxx.
-
 [TOC]
 
-# Patterns {#patterns}
-
-The basic way of outputing messages is by using a [PatternLayout](@ref 
log4cxx.PatternLayout),
-and then sending the messages to stderr/stdout/file.  The following
-examples show how you might configure the PatternLayout in order to
-achieve the results shown.
-
-Each example has two blocks of code: the layout for the PatternLayout,
-and a sample output message.
-
-## Pattern 1 {#pattern1}
-
-This pattern contains the date in an ISO-8601 format(without fractional 
seconds),
-followed by the logger name, the level, and then the message.
-
-~~~
-[%d{yyyy-MM-dd HH:mm:ss}] %c %-5p - %m%n
-~~~
-
-~~~
-[2020-12-24 15:31:46] root INFO  - Hello there!
-~~~
-
-## Pattern 2 {#pattern2}
-
-Similar to Pattern 1, except using ISO-8601 with fractional seconds
-
-~~~
-[%d] %c %-5p - %m%n
-~~~
-
-~~~
-[2020-12-24 15:35:39,225] root INFO  - Hello there!
-~~~
-
-## Pattern 3 {#pattern3}
-
-Prints out the number of milliseconds since the start of the application,
-followed by the level(5 character width), followed by the logger name
-(20 character width), followed by the message.
-
-~~~
-%r %-5p %-20c %m%n
-~~~
-
-~~~
-0 INFO  root                 Hello there!
-~~~
+The following snippets show various ways of configuring Log4cxx.
 
-## Pattern 4 {#pattern4}
+# Default Initialization Behaviour {#default-initialization}
 
-If you have no idea where a log message is coming from, it's possible to print
-out more information about the place the log statement is coming from.  For 
example,
-we can get the filename, class name, method name, and line number in one log
-message.  This utilises the %%F(file name), %%C(class name), %%M(method name), 
%%L(line number)
-patterns to output more information:
+The Log4cxx library does not make any assumptions about its environment.
+In particular, when initially created the root [Logger](@ref log4cxx.Logger) 
has no appender.
+However the library will attempt automatic configuration.
 
-~~~
-(%F:%C[%M]:%L) %m%n
-~~~
+If the LoggerRepositoy is not yet configured on the first call to
+[getLogger](@ref log4cxx.LogManager.getLogger) of [LogManager](@ref 
log4cxx.LogManager),
+the [configure](@ref log4cxx.DefaultConfigurator.configure) method
+of [DefaultConfigurator](@ref log4cxx.DefaultConfigurator) is called
+via [ensureIsConfigured](@ref log4cxx.spi.LoggerRepository.ensureIsConfigured) 
method
+of [LoggerRepository](@ref log4cxx.spi.LoggerRepository).
 
-Possible output:
-~~~
-(/home/robert/log4cxx-test-programs/fooclass.cpp:FooClass[FooClass]:9) 
Constructor running
-(/home/robert/log4cxx-test-programs/fooclass.cpp:FooClass[doFoo]:13) Doing foo
-~~~
-
-Note that unlike Java logging, the location information is free(as it utilizes
-macros to determine this information at compile-time).
+To use automatic configuration with a non-standard file name
+create and use your own wrapper for [getLogger](@ref 
log4cxx.LogManager.getLogger).
+A full example can be seen in the \ref com/foo/config3.cpp file.
 
 # XML Files {#xmlfiles}
 
@@ -132,9 +79,8 @@ Hello there!
 
 ## XML Example 2 {#xml-example-2}
 
-This example sends data to both stdout, as well as to a file.  In this case,
-the file will be in our working directory.  The pattern has also been updated
-to match with pattern example 1
+This example sends data to both stdout, as well as to a file.
+With this configuration the "example.log" file will be created in our working 
directory.
 
 ~~~{.xml}
 <?xml version="1.0" encoding="UTF-8" ?>
@@ -189,6 +135,7 @@ Assume that our loggers are in our code as such:
 For this configuration, we have set any logger that is at the `com` level or 
below
 to be debug.  However, we have also set the logger `com.example` to have a more
 verbose `trace` level to see more information from that particular logger.
+The "example.log" file will be created in our temporary directory.
 
 ~~~{.xml}
 <?xml version="1.0" encoding="UTF-8" ?>
@@ -202,7 +149,7 @@ verbose `trace` level to see more information from that 
particular logger.
   </appender>
 
   <appender name="FileAppender" class="org.apache.log4j.FileAppender">
-    <param name="file" value="example.log" />
+    <param name="file" value="${TMP}/example.log" />
     <layout class="org.apache.log4j.PatternLayout">
       <param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss}] %c %-5p 
- %m%n" />
     </layout>
@@ -288,3 +235,7 @@ Sample output:
 
 Note that even though we have the root logger set to the most verbose 
level(trace),
 the only messages that we saw were the ones with "specific" in them.
+
+\example auto-configured.cpp
+This is an example of logging in static initialization code and
+using the current module name to select the Log4cxx configuration file.
diff --git a/src/site/markdown/environment-variables.md 
b/src/site/markdown/environment-variables.md
index aeed4697..8da4b75c 100644
--- a/src/site/markdown/environment-variables.md
+++ b/src/site/markdown/environment-variables.md
@@ -1,4 +1,4 @@
-Environment Variables {#environment-variables}
+Environment Variables Used by Log4cxx {#environment-variables}
 ===
 <!--
  Note: License header cannot be first, as doxygen does not generate
@@ -21,8 +21,6 @@ Environment Variables {#environment-variables}
  limitations under the License.
 -->
 
-# Environment Variables Used by Log4cxx
-
 There are several environment variables that can be set in order to influence 
how
 Log4cxx works.  They are summarized in the following table:
 
diff --git a/src/site/markdown/example-programs.md 
b/src/site/markdown/example-programs.md
new file mode 100644
index 00000000..dfbbb83e
--- /dev/null
+++ b/src/site/markdown/example-programs.md
@@ -0,0 +1,193 @@
+Quick Start {#quick-start}
+===
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+[TOC]
+
+Creating useful log information 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.
+
+Let us give a taste of how this is done with the help of an imaginary
+application *MyApp* that uses Log4cxx.
+
+# A Simple Example {#example1}
+
+In order to start using Log4cxx, a simple example program is shown below.
+This program does nothing useful, but it shows the basics of how to start 
using Log4cxx.
+Using the [BasicConfigurator](@ref log4cxx.BasicConfigurator) class, we are 
able to quickly configure the library
+to output DEBUG, INFO, etc level messages to standard output.
+\include MyApp1.cpp
+
+The above application does nothing useful except to show how to initialize 
logging
+with the BasicConfigurator and do logging with different loggers.
+Note that file based configurations are also possible -
+see [DOMConfigurator](@ref log4cxx.xml.DOMConfigurator.configure)
+and [PropertyConfigurator](@ref log4cxx.PropertyConfigurator.configure).
+
+Configuring Log4cxx in the main function has the limitation that
+any logging statements in static initialization code will not generate output.
+Log4cxx must be configured before it is used and
+in this example Log4cxx is not configured until the main() function starts.
+
+# A Less Simple Example {#example2}
+
+In this example we use a *getLogger()* wrapper function
+which configures Log4cxx on the first usage.
+The advantages of this approach are:
+
+- Log4cxx configuration can be reused in multiple applications.
+- The structure exhibits better [separation of 
concerns](https://en.wikipedia.org/wiki/Separation_of_concerns).
+- Log statements in static initialization code will generate output.
+
+This program (*MyApp*) begins by including the file
+that defines the com::foo::getLogger() function.
+It obtains a logger named *MyApp*
+(which in this example is the fully qualified name)
+from the com::foo::getLogger() function.
+
+*MyApp* uses the *com::foo::Bar* class defined in header file *com/foo/bar.h*.
+\include MyApp2.cpp
+
+The *com::foo::Bar* class is defined in header file *com/foo/bar.h*.
+\include com/foo/bar.h
+
+The *com::foo::Bar* class is implemented in the file *com/foo/bar.cpp*.
+\include com/foo/bar.cpp
+
+The header file *com/foo/config.h* defines the com::foo::getLogger() function
+and a *LoggerPtr* type for convenience.
+\include com/foo/config.h
+
+The file *com/foo/config.cpp* which implements the com::foo::getLogger() 
function
+defines *initAndShutdown* as a *static struct* so its constructor
+is invoked on the first call to the com::foo::getLogger() function
+and its destructor is automatically called during application exit.
+\include com/foo/config1.cpp
+
+The invocation of the
+[BasicConfigurator::configure](@ref log4cxx.BasicConfigurator.configure)
+method creates a rather simple Log4cxx setup. This method is hardwired
+to add to the root logger a [ConsoleAppender](@ref log4cxx.ConsoleAppender).
+The output will be formatted using a
+[PatternLayout](@ref log4cxx.PatternLayout)
+set to the pattern `%%r [%%t] %%p %%c %%x - %%m%%n`.
+
+Note that by default, the root logger is assigned a *DEBUG* level.
+
+The output of MyApp is:
+
+~~~
+    0 [12345] INFO MyApp null - Entering application.
+    0 [12345] DEBUG com.foo.Bar null - Did it again!
+    0 [12345] INFO MyApp null - Exiting application.
+~~~
+
+# Runtime Configuration {#configuration}
+
+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 Java
+properties (key=value) format.
+
+The previous example always outputs the same log information.
+Fortunately, it is easy to modify *config.cpp* so that the log output can be
+controlled at runtime. Here is a slightly modified version.
+\include com/foo/config2.cpp
+
+This version of *config.cpp* instructs [PropertyConfigurator](@ref 
log4cxx.PropertyConfigurator.configure)
+to use the *MyApp.properties* file to configure Log4cxx.
+A more realistic approach would (for example)
+use the current module name to select the configuration file
+(see the \ref com/foo/config3.cpp file for how to do this).
+
+Here is a sample *MyApp.properties* configuration file that results in exactly 
same output
+as the previous [BasicConfigurator::configure](@ref 
log4cxx.BasicConfigurator.configure) based example.
+
+~~~
+    # Set root logger level to DEBUG and its only appender to A1.
+    log4j.rootLogger=DEBUG, A1
+
+    # A1 is set to be a ConsoleAppender.
+    log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+    # A1 uses PatternLayout.
+    log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+    log4j.appender.A1.layout.ConversionPattern=%r [%t] %-5p %c %x - %m%n
+~~~
+
+It can be noticed that the PropertyConfigurator file format is the same
+as log4j.
+
+Suppose we are no longer interested in seeing the output of any
+component belonging to the *com::foo* package. The following
+configuration file shows one possible way of achieving this.
+
+~~~
+    log4j.rootLogger=DEBUG, A1
+    log4j.appender.A1=org.apache.log4j.ConsoleAppender
+    log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+
+    # Print the date in ISO 8601 format
+    log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
+
+    # Print only messages of level WARN or above in the package com.foo.
+    log4j.logger.com.foo=WARN
+~~~
+
+The output of *MyApp* configured with this file is shown below.
+
+~~~
+    2022-12-13 11:01:45,091 [12345] INFO  MyApp - Entering application.
+    2022-12-13 11:01:45,091 [12345] INFO  MyApp - Exiting application.
+~~~
+
+As the logger *com.foo.Bar* does not have an assigned level, it inherits
+its level from *com.foo*, which was set to WARN in the configuration
+file. The log statement from the *Bar::doIt* method has the level *DEBUG*,
+lower than the logger level WARN. Consequently, *doIt()* method's log
+request is suppressed.
+
+Here is another configuration file that uses multiple appenders.
+\include MyApp.properties
+
+Calling the enhanced MyApp with the this configuration file will output
+the following on the console.
+
+~~~
+     INFO [12345] (MyApp.cpp:8) - Entering application.
+    DEBUG [12345] (bar.cpp:8) - Did it again!
+     INFO [12345] (MyApp.cpp:11) - Exiting application.
+~~~
+
+In addition, as the root logger has been allocated a second appender,
+output will also be directed to the *example.log* file. This file will
+be rolled over when it reaches 100KB. When roll-over occurs, the old
+version of *example.log* is automatically moved to *example.log.1*.
+
+Note that to obtain these different logging behaviors we did not need to
+recompile code. We could just as easily have logged to a UNIX Syslog
+daemon, redirected all *com.foo* output to an NT Event logger, or
+forwarded logging events to a remote Log4cxx server, which would log
+according to local server policy, for example by forwarding the log
+event to a second Log4cxx server.
+
+\example com/foo/config3.cpp
+This file is an example of how to use the current module name to select the 
Log4cxx configuration file.
diff --git a/src/site/markdown/extending.md b/src/site/markdown/extending.md
index 13170e1e..1e826363 100644
--- a/src/site/markdown/extending.md
+++ b/src/site/markdown/extending.md
@@ -25,7 +25,7 @@ Sometimes, you may want to extend Log4cxx, for example by 
creating
 a new appender to write out data in a new format.  The following
 guide shows how you can extend Log4cxx in order to add a new appender.
 
-The full sample application can be found at \ref custom-appender.cpp and \ref 
example-custom-appender.xml .
+The full sample application can be found at \ref custom-appender.cpp and \ref 
custom-appender.xml .
 
 The first thing for our example is to create a class that extends
 log4cxx.AppenderSkeleton so that we don't need to implement all of
diff --git a/src/site/markdown/faq.md b/src/site/markdown/faq.md
index 209c471b..b23ce38a 100644
--- a/src/site/markdown/faq.md
+++ b/src/site/markdown/faq.md
@@ -1,4 +1,4 @@
-FAQ {#faq}
+Frequently Asked Technical Questions {#faq}
 ===
 <!--
  Note: License header cannot be first, as doxygen does not generate
@@ -20,8 +20,6 @@ FAQ {#faq}
  See the License for the specific language governing permissions and
  limitations under the License.
 -->
-
-# Frequently Asked Technical Questions
 [TOC]
 
 ## How do I add a custom level to Apache Log4cxx?{#custom_levels}
@@ -49,7 +47,7 @@ DLL" with release builds of Log4cxx and "Multithread DLL 
Debug" with debug build
 Yes. Apache Log4cxx exposes API methods in multiple string flavors supporting 
differently encoded
 textual content, like `char*`, `std::string`, `wchar_t*`, `std::wstring`, 
`CFStringRef` et al. All
 provided texts will be converted to the `LogString` type before further 
processing, which is one of
-several supported Unicode representations selected by the `--with-logchar` 
option. If methods are
+several supported Unicode representations selected by the `LOG4CXX_CHAR` cmake 
option. If methods are
 used that take `LogString` as arguments, the macro `LOG4CXX_STR()` can be used 
to convert literals
 to the current `LogString` type. FileAppenders support an encoding property as 
well, which should be
 explicitly specified to `UTF-8` or `UTF-16` for e.g. XML files. The important 
point is to get the
diff --git a/src/site/markdown/filters/filters.md 
b/src/site/markdown/filters/filters.md
index 5c2110cf..4f4bbbb2 100644
--- a/src/site/markdown/filters/filters.md
+++ b/src/site/markdown/filters/filters.md
@@ -22,7 +22,44 @@ Filtering Log Messages {#filters}
 -->
 [TOC]
 
-# Filtering Messages {#filtering}
+## Labeling Log Output {#labeling-log-output}
+
+To uniquely stamp each request to relate it to a particular source,
+you can push contextual information
+into the *Nested Diagnostic Context* (NDC) using the *log4cxx::NDC* class
+or the *Mapped Diagnostic Context* provided by *log4cxx::MDC* class.
+For an example using log4cxx::NDC refer to \ref trivial.cpp.
+
+The NDC is managed per thread as a *stack* of contextual information.
+When the layout specifies that the NDC is to be included,
+each log entry will include the entire stack for the current thread.
+A log4cxx::PatternLayout allows named entries of the MDC
+to be included in the log message.
+The user is responsible for placing the correct information in the NDC/MDC
+by creating a *log4cxx::NDC* or *log4cxx::MDC* stack variable at
+a few well-defined points in the code. In contrast, the per-client
+logger approach commands extensive changes in the code.
+
+To illustrate this point, let us take the example of a servlet
+delivering content to numerous clients. The servlet can build the NDC at
+the very beginning of the request before executing other code. The
+contextual information can be the client's host name and other
+information inherent to the request, typically information contained in
+cookies. Hence, even if the servlet is serving multiple clients
+simultaneously, the logs initiated by the same code, i.e. belonging to
+the same logger, can still be distinguished because each client request
+will have a different NDC stack. Contrast this with the complexity of
+passing a freshly instantiated logger to all code exercised during the
+client's request.
+
+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.
+
+## Excluding Log Output {#excluding-log-output}
 
 When dealing with large amounts of logging information, it can be useful
 to filter on messages that we are interested in.  This filtering only
@@ -55,3 +92,6 @@ The following pages have information on specific filters:
 
 * @subpage map-filter
 * @subpage location-info-filter
+
+\example trivial.cpp
+This example shows how to add a context string to each logging message using 
the NDC.
diff --git a/src/site/markdown/1-usage.md 
b/src/site/markdown/internal-debugging.md
similarity index 56%
copy from src/site/markdown/1-usage.md
copy to src/site/markdown/internal-debugging.md
index 4cb5694e..bc592514 100644
--- a/src/site/markdown/1-usage.md
+++ b/src/site/markdown/internal-debugging.md
@@ -1,9 +1,5 @@
-Usage {#usage-overview}
+Internal Debugging {#internal-debugging}
 ===
-<!--
- Note: License header cannot be first, as doxygen does not generate
- cleanly if it before the '==='
--->
 <!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
@@ -21,18 +17,14 @@ Usage {#usage-overview}
  limitations under the License.
 -->
 
-See the following pages for usage information:
+Because Log4cxx is a logging library, we can't use it to output errors from
+the library itself.  There are several ways to activate internal logging:
+
+1. Configure the library directly by calling the
+[LogLog::setInternalDebugging](@ref 
log4cxx.helpers.LogLog.setInternalDebugging)
+method
+2. If using a properties file, set the value `log4j.debug=true` in your 
configuration file
+3. If using an XML file, set the attribute `internalDebug=true` in the root 
node
+4. From the environment: `LOG4CXX_DEBUG=true`
 
-* @subpage usage
-* @subpage nested-diagnostic-contexts
-* @subpage filters
-* @subpage threading
-* @subpage extending-log4cxx
-* @subpage stacktrace-support
-* @subpage faq
-* @subpage configuration-samples
-* @subpage qt-support
-* @subpage performance
-* @subpage multiprocess-logging
-* @subpage environment-variables
-* @subpage macros-influencing-log4cxx
+All error and warning messages are sent to stderr.
diff --git a/src/site/markdown/macros-influencing-log4cxx.md 
b/src/site/markdown/macros-influencing-log4cxx.md
index 4aaa189a..40975f26 100644
--- a/src/site/markdown/macros-influencing-log4cxx.md
+++ b/src/site/markdown/macros-influencing-log4cxx.md
@@ -1,4 +1,4 @@
-Macros Influencing Log4cxx {#macros-influencing-log4cxx}
+Preprocessor Macros Influencing Log4cxx {#macros-influencing-log4cxx}
 ===
 <!--
  Note: License header cannot be first, as doxygen does not generate
@@ -21,8 +21,6 @@ Macros Influencing Log4cxx {#macros-influencing-log4cxx}
  limitations under the License.
 -->
 
-# Macros that influence Log4cxx
-
 The following macros can be defined in client code to influence how log 
messages
 are set or not.
 
diff --git a/src/site/markdown/multiprocess.md 
b/src/site/markdown/multiprocess.md
index 5c7e7100..42032018 100644
--- a/src/site/markdown/multiprocess.md
+++ b/src/site/markdown/multiprocess.md
@@ -1,4 +1,4 @@
-Multiprocess Logging {#multiprocess-logging}
+Logging With Multiple Processes {#multiprocess-logging}
 ===
 <!--
  Note: License header cannot be first, as doxygen does not generate
@@ -21,12 +21,10 @@ Multiprocess Logging {#multiprocess-logging}
  limitations under the License.
 -->
 
-# Logging With Multiple Processes
-
 If you have multiple applications that all log to the same file, it is often
 desirable that the file that these applications write to will roll over when
-required.  In order for that to happen, Log4cxx supplies a
-`MultiprocessRollingFileAppender` that will check the size of the file when
+required.  In order for that to happen, Log4cxx provides the
+log4cxx::rolling::MultiprocessRollingFileAppender that will check the size of 
the file when
 writing to the file and roll it over appropriately.
 
 This is an optional feature, and thus must be explicitly enabled when building
diff --git a/src/site/markdown/nested-diagnostic-contexts.md 
b/src/site/markdown/nested-diagnostic-contexts.md
deleted file mode 100644
index 994d53a8..00000000
--- a/src/site/markdown/nested-diagnostic-contexts.md
+++ /dev/null
@@ -1,69 +0,0 @@
-Nested Diagnostic Contexts {#nested-diagnostic-contexts}
-===
-<!--
- Note: License header cannot be first, as doxygen does not generate
- cleanly if it before the '==='
--->
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-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.
-
-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 *Pattern Languages
-of Program Design 3*, edited by R. Martin, D. Riehle, and F. Buschmann
-(Addison-Wesley, 1997).
-
-To uniquely stamp each request, the user pushes contextual information
-into the *Nested Diagnostic Context* (NDC) using the *log4cxx::NDC* class.
-For an example refer to \ref trivial.cpp.
-Note that all methods of the *log4cxx::NDC* class are static.
-
-The NDC is managed per thread as a *stack* of contextual information.
-Each log entry will include the entire stack
-for the current thread (for better control use *log4cxx::MDC*).
-The user is responsible for placing the correct information in the NDC
-by using the *push* and *pop* methods at
-a few well-defined points in the code. In contrast, the per-client
-logger approach commands extensive changes in the code.
-
-To illustrate this point, let us take the example of a servlet
-delivering content to numerous clients. The servlet can build the NDC at
-the very beginning of the request before executing other code. The
-contextual information can be the client's host name and other
-information inherent to the request, typically information contained in
-cookies. Hence, even if the servlet is serving multiple clients
-simultaneously, the logs initiated by the same code, i.e. belonging to
-the same logger, can still be distinguished because each client request
-will have a different NDC stack. Contrast this with the complexity of
-passing a freshly instantiated logger to all code exercised during the
-client's request.
-
-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.
diff --git a/src/site/markdown/performance.md b/src/site/markdown/performance.md
index 1b1494f6..8aa05c1f 100644
--- a/src/site/markdown/performance.md
+++ b/src/site/markdown/performance.md
@@ -20,9 +20,6 @@ Log4cxx Performance {#performance}
  See the License for the specific language governing permissions and
  limitations under the License.
 -->
-[TOC]
-
-# Log4cxx Performance
 
 One important question with a logging library is: is it fast enough?  While
 Log4cxx may not be the fastest logging implementation, it is more than fast
diff --git a/src/site/markdown/stacktrace.md b/src/site/markdown/stacktrace.md
index bb9e52cb..ae8f90b9 100644
--- a/src/site/markdown/stacktrace.md
+++ b/src/site/markdown/stacktrace.md
@@ -20,7 +20,6 @@ Stacktrace Support {#stacktrace-support}
  See the License for the specific language governing permissions and
  limitations under the License.
 -->
-# Stacktrace Support
 When debugging a code base and an assertion is hit, it is often useful to
 have a stacktrace as part of an assertion in order for you to tell where
 you are in the code to know why it is buggy.  Generating a stacktrace can
diff --git a/src/site/markdown/threading.md b/src/site/markdown/threading.md
index ff379246..c98b880d 100644
--- a/src/site/markdown/threading.md
+++ b/src/site/markdown/threading.md
@@ -22,8 +22,6 @@ Threading {#threading}
 -->
 [TOC]
 
-# Threading Notes with Log4cxx {#threading-notes}
-
 Log4cxx is designed to be thread-safe under under normal usage.  This
 means that logging itself is always thread-safe, however there are
 certain circumstances that can cause threading issues with Log4cxx.

Reply via email to