Packets: Fix VariantParser invalid parser access bug
[senf.git] / Utils / Logger / Config.hh
index 4ffb5ac..9f0f735 100644 (file)
@@ -1,8 +1,8 @@
 // $Id$
 //
-// Copyright (C) 2007 
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// Copyright (C) 2007
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
 //     Stefan Bund <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
@@ -23,8 +23,8 @@
 /** \file
     \brief Config public header */
 
-#ifndef HH_Config_
-#define HH_Config_ 1
+#ifndef HH_SENF_Utils_Logger_Config_
+#define HH_SENF_Utils_Logger_Config_ 1
 
 // Custom includes
 #include "Levels.hh"
@@ -46,7 +46,7 @@
     <em>Runtime</em> configuration on the other hand deals with routing all those messages, which
     are enabled at compile time to the logging targets. If a message is not routed, it will be
     discarded. This allows to additionally disable messages at run-time. Message routing is managed
-    via the \ref Target interface.
+    via the ::Target interface.
 
     \section config_compile Compile time configuration
 
     <pre>
     g++ ... -DSENF_LOG_CONF="(( (senf)(log)(Debug),(_),DISABLED ))
                              (( (senf)(log)(Debug),(foo)(SomeClass),VERBOSE ))
-                             (( (foo)(Transactions),(_),NOTICE ))" ...
+                             (( (_),(_),NOTICE ))" ...
     </pre>
     The value is relatively complex; It's a Boost.Preprocessor style sequence of tuples, of which
     the first and second elements are again sequences. What this boils down to, is that it allows to
-    configure compile time logging limits based on stream and optional area. 
+    configure compile time logging limits based on stream and optional area.
 
     The above example disables all debug logging by setting the default log limit for all areas on
-    the \c senf::log::Debug stream to \c DISABLED. It then re-enables debug logging only within the
-    \c foo::SomeClass area, where it is set to \c VERBOSE. Furthermore, the limit on the \c
-    foo::Transactions stream is set to \c NOTICE.
+    the \c senf::log::Debug stream to \c DISABLED. It enables debug logging only within the \c
+    foo::SomeClass area, where it is set to \c VERBOSE. Lastly, the global compile time limit is set
+    to \c NOTICE.
+
+    There are two standard uses for this configuration: Either to disable most logging in final
+    builds by changing the compile time limit to something like senf::log::IMPORTANT or to enable
+    senf::log::VERBOSE messages for some area:
+    <pre>
+    # Disable debug logging below 'IMPORTANT' level
+    g++ ... -DSENF_LOG_CONF="(( (senf)(log)(Debug), (_), IMPORTANT ))"
+
+    # Or enable verbose messages for the 'some::Area' area
+    g++ ... -DSENF_LOG_CONF="(( (senf)(log)(Verbose), (some)(Area), VERBOSE ))"
+    </pre>
+
+    All the entries specified via \c SENF_LOG_CONF are applied in a fixed order:
+    
+    \li First the entries which have both a stream and an area specified are checked
+    \li next all entries with area but no stream given are checked
+    \li followed by all entries with a given stream but no area
+    \li and lastly if no match was found until now, a generic entry without stream and area is
+        checked
+    \li if no matching entry is found, the default compile time limit of the stream is used
+
+    So an area specification has precedence over a stream specification.
+
+    \warning Enabling a message at compile time does \e not ensure, the message is shown. You
+        additionally need to \e route the message (see next chapter). This is especially true for \c
+        VERBOSE messages, which are default disabled at runtime.
 
     \see \ref SENF_LOG_CONF
 
 
     The runtime configuration is performed by routing messages to one or more logging targets:
     \code
-    senf::log::ConsoleLog consoleLog;
-    senf::log::FileLog fileLog ("my.log");
+    senf::log::ConsoleTarget & consoleLog (senf::log::ConsoleTarget::instance());
+    senf::log::FileTarget fileLog ("my.log");
 
     consoleLog.route<senf::log::Debug>();
     consoleLog.route<foo::Transactions, foo::SomeClass>(senf::log::Target::REJECT);
     consoleLog.route<foo::Transactions, senf::log::IMPORTANT>();
 
     fileLog.route<foo::Transactions>();
-    \endcode Here we see an already relatively complex setup: All debug messages (that is, those,
-    which are not disabled at compile time) are routed to the console. We also route important
-    transactions to the console \e except transactions from the \c foo::SomeClass area. The \c
-    fileLog simply receives all transaction log messages.
+    \endcode 
+    Here we see an already relatively complex setup: All debug messages (that is, those, which are
+    not disabled at compile time) are routed to the console. We also route important transactions to
+    the console \e except transactions from the \c foo::SomeClass area. The \c fileLog simply
+    receives all transaction log messages.
 
     The routing statements are processed by the targets in order, the first matching rule will
     decide a log messages fate for that target.
+
+    \warning You can \e only route those messages at runtime which have been compile-time
+        enabled. By default, \c VERBOSE messages are \e disabled at compile time. They must be
+        enabled \e explicitly by setting \c SENF_LOG_CONF so they can be routed.
+
+    \section config_fallback Fallback routing
     
     There are two cases, where this setup may lead to inadvertently lost log messages:
     \li When using a library which does internally use the Logger but not initializing the logger in
     Since no route is set up in these cases, the messages will be dropped.
     
     To counter this problem, the logger is initially in <em>fallback routing</em> state. If any log
-    message arrives in this state, the message will be unconditionally logged to the console. The
-    first routing statement on any target will take the logger out of this state and normal routing
-    will take place.
+    message arrives in this state, the message will be logged to the console if it is above the
+    default runtime limit of it's stream. The first routing statement on any target will take the
+    logger out of this state and normal routing will take place.
 
     \see \ref senf::log::Target
 
     By default, the logging library will call gettimeofday() for each log message. To change the
     time source, just pass the new class or instance to senf::log::timeSource:
     \code
-    // Use senf::Scheduler::instance().eventTime() to time log messages
-    senf::log::timeSource<senf::SchedulerLogTimeSource>();
+    // Use senf::scheduler::eventTime() to time log messages
+    senf::log::timeSource<senf::scheduler::LogTimeSource>();
     \endcode
  */
 
@@ -132,28 +165,30 @@ namespace log {
 
         \par ""
             <table class="ebnf">
-            <tr><td>conf</td>         <td>::= \e element \e element* \n</td></tr>
-            <tr><td>element</td>      <td>::= <tt>((</tt> \e stream <tt>,</tt> \e optional_area <tt>,</tt> \e level <tt>))</tt> \n</td></tr>
-            <tr><td>stream</td>       <td>::= \e scope_seq \n</td></tr>
-            <tr><td>optional_area</td><td>::= <tt>(_)</tt> | \e scope_seq \n</td></tr>
-            <tr><td>level</td>        <td>::= \c VERBOSE | \c NOTICE | \c MESSAGE | \c IMPORTANT | \c CRITICAL | \c DISABLED \n</td></tr>
-            <tr><td>scope_seq</td>    <td>::= \e scope \e scope \e scope* \n</td></tr>
-            <tr><td>scope</td>        <td>::= <tt>(</tt> \e name <tt>)</tt> \n</td></tr>
-            <tr><td>name</td>         <td>::= arbitrary C++ identifier</td></tr>
+            <tr><td>conf</td>            <td>::= \e element \e element* \n</td></tr>
+            <tr><td>element</td>         <td>::= <tt>((</tt> \e optional_stream <tt>,</tt> \e optional_area <tt>,</tt> \e level <tt>))</tt> \n</td></tr>
+            <tr><td>optional_stream</td> <td>::= <tt>(_)</tt> | \e scope_seq \n</td></tr>
+            <tr><td>optional_area</td>   <td>::= <tt>(_)</tt> | \e scope_seq \n</td></tr>
+            <tr><td>level</td>           <td>::= \c VERBOSE | \c NOTICE | \c MESSAGE | \c IMPORTANT | \c CRITICAL | \c DISABLED \n</td></tr>
+            <tr><td>scope_seq</td>       <td>::= \e scope \e scope* \n</td></tr>
+            <tr><td>scope</td>           <td>::= <tt>(</tt> \e name <tt>)</tt> \n</td></tr>
+            <tr><td>name</td>            <td>::= arbitrary C++ identifier</td></tr>
             </table>
 
-        \ref SENF_LOG_CONF is a Boost.Preprocessor style sequence of 3-tuples. Each tuple applies to
-        a specific stream which is defined by the first tuple element \e stream. 
+        \ref SENF_LOG_CONF is a Boost.Preprocessor style sequence of 3-tuples. 
+
+        The first tuple element \e optional_stream specifies the stream to match. If this is
+        <tt>(_)</tt>, the entry will match any stream.
 
         The next tuple element, \e optional_area optionally restricts the entry to match only the
-        given area. 
+        given area. If set to <tt>(_)</tt>, the area is left unrestricted.
 
         The last tuple element \e level defines the compile time log level. Messages with a level
         below this are discarded at compile time.
 
-        Both \e stream and \e optional_area are given as a \e scope_seq. A scope sequence is a fully
-        qualified C++ identifier placed into a sequence: <tt>foo::bar::baz</tt> is represented by
-        <tt>(foo)(bar)(baz)</tt>.
+        Both \e optional_stream and \e optional_area are given as a \e scope_seq. A scope sequence
+        is a fully qualified C++ identifier placed into a sequence: <tt>foo::bar::baz</tt> is
+        represented by <tt>(foo)(bar)(baz)</tt>.
      */
 #   define SENF_LOG_CONF