Fix documentation build under maverick (doxygen 1.7.1)
[senf.git] / senf / Utils / Logger / Config.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Config public header */
25
26 #ifndef HH_SENF_Utils_Logger_Config_
27 #define HH_SENF_Utils_Logger_Config_ 1
28
29 // Custom includes
30 #include "Levels.hh"
31
32 //#include "Config.mpp"
33 #include "Config.ih"
34 //-/////////////////////////////////////////////////////////////////////////////////////////////////
35
36 /** \defgroup config Configuration
37
38     The logger infrastructure provides for very fine-grained configuration of log messages. There
39     are two parts to this configuration: compile-time configuration and runtime configuration.
40
41     <em>Compile-time</em> configuration selects, which log statements will even be compiled. If
42     logging for a certain combination of stream, area and level is disabled at compile time, no code
43     will be generated for any such disabled log statement. This type of configuration is done using
44     \ref SENF_LOG_CONF.
45
46     <em>Runtime</em> configuration on the other hand deals with routing all those messages, which
47     are enabled at compile time to the logging targets. If a message is not routed, it will be
48     discarded. This allows to additionally disable messages at run-time. Message routing is managed
49     via the ::Target interface.
50
51     \section config_compile Compile time configuration
52
53     Compile time configuration is set on the compiler command line:
54     <pre>
55     g++ ... -DSENF_LOG_CONF="(( (senf)(log)(Debug),(_),DISABLED ))
56                              (( (senf)(log)(Debug),(foo)(SomeClass),VERBOSE ))
57                              (( (_),(_),NOTICE ))" ...
58     </pre>
59     The value is relatively complex; It's a Boost.Preprocessor style sequence of tuples, of which
60     the first and second elements are again sequences. What this boils down to, is that it allows to
61     configure compile time logging limits based on stream and optional area.
62
63     The above example disables all debug logging by setting the default log limit for all areas on
64     the \c senf::log::Debug stream to \c DISABLED. It enables debug logging only within the \c
65     foo::SomeClass area, where it is set to \c VERBOSE. Lastly, the global compile time limit is set
66     to \c NOTICE.
67
68     There are two standard uses for this configuration: Either to disable most logging in final
69     builds by changing the compile time limit to something like senf::log::IMPORTANT or to enable
70     senf::log::VERBOSE messages for some area:
71     <pre>
72     # Disable debug logging below 'IMPORTANT' level
73     g++ ... -DSENF_LOG_CONF="(( (senf)(log)(Debug), (_), IMPORTANT ))"
74
75     # Or enable verbose messages for the 'some::Area' area
76     g++ ... -DSENF_LOG_CONF="(( (senf)(log)(Verbose), (some)(Area), VERBOSE ))"
77     </pre>
78
79     All the entries specified via \c SENF_LOG_CONF are applied in a fixed order:
80
81     \li First the entries which have both a stream and an area specified are checked
82     \li next all entries with area but no stream given are checked
83     \li followed by all entries with a given stream but no area
84     \li and lastly if no match was found until now, a generic entry without stream and area is
85         checked
86     \li if no matching entry is found, the default compile time limit of the stream is used
87
88     So an area specification has precedence over a stream specification.
89
90     \warning Enabling a message at compile time does \e not ensure, the message is shown. You
91         additionally need to \e route the message (see next chapter). This is especially true for \c
92         VERBOSE messages, which are default disabled at runtime.
93
94     \see \ref SENF_LOG_CONF
95
96     \section config_runtime Runtime configuration
97
98     The runtime configuration is performed by routing messages to one or more logging targets:
99     \code
100     senf::log::ConsoleTarget & consoleLog (senf::log::ConsoleTarget::instance());
101     senf::log::FileTarget fileLog ("my.log");
102
103     consoleLog.route<senf::log::Debug>();
104     consoleLog.route<foo::Transactions, foo::SomeClass>(senf::log::Target::REJECT);
105     consoleLog.route<foo::Transactions, senf::log::IMPORTANT>();
106
107     fileLog.route<foo::Transactions>();
108     \endcode
109     Here we see an already relatively complex setup: All debug messages (that is, those, which are
110     not disabled at compile time) are routed to the console. We also route important transactions to
111     the console \e except transactions from the \c foo::SomeClass area. The \c fileLog simply
112     receives all transaction log messages.
113
114     The routing statements are processed by the targets in order, the first matching rule will
115     decide a log messages fate for that target.
116
117     \warning You can \e only route those messages at runtime which have been compile-time
118         enabled. By default, \c VERBOSE messages are \e disabled at compile time. They must be
119         enabled \e explicitly by setting \c SENF_LOG_CONF so they can be routed.
120
121     \section config_fallback Fallback routing
122
123     There are two cases, where this setup may lead to inadvertently lost log messages:
124     \li When using a library which does internally use the Logger but not initializing the logger in
125         your application.
126     \li When log messages are created during initialization of static objects.
127     Since no route is set up in these cases, the messages will be dropped.
128
129     To counter this problem, the logger is initially in <em>fallback routing</em> state. If any log
130     message arrives in this state, the message will be logged to the console if it is above the
131     default runtime limit of it's stream. The first routing statement on any target will take the
132     logger out of this state and normal routing will take place.
133
134     \see \ref senf::log::Target
135
136     \section config_timesource Log message timing
137
138     One auxiliary aspect of logging is message timing. Each message is stamped with a time-stamp
139     giving the exact time the message was created. How the current date/time value is created may be
140     changed by setting a \e TimeSource. A TimeSource is an instance derived from
141     senf::log::TimeSource which will return the current universal time (UTC) when called.
142
143     By default, the logging library will call gettimeofday() for each log message. To change the
144     time source, just pass the new class or instance to senf::log::timeSource:
145     \code
146     // Use senf::scheduler::eventTime() to time log messages
147     senf::log::timeSource<senf::scheduler::LogTimeSource>();
148     \endcode
149  */
150
151 namespace senf {
152 namespace log {
153
154     ///\ingroup config
155     //\{
156
157 #   ifdef DOXYGEN
158
159     /** \brief Compile time configuration
160
161         This define symbol sets the compile time logger configuration. This symbol should normally
162         be set on the compiler command line.
163
164         The formal syntax of this option is:
165
166         \par ""
167             <table class="ebnf">
168             <tr><td>conf</td>            <td>::= \e element \e element* \n</td></tr>
169             <tr><td>element</td>         <td>::= <tt>((</tt> \e optional_stream <tt>,</tt> \e optional_area <tt>,</tt> \e level <tt>))</tt> \n</td></tr>
170             <tr><td>optional_stream</td> <td>::= <tt>(_)</tt> | \e scope_seq \n</td></tr>
171             <tr><td>optional_area</td>   <td>::= <tt>(_)</tt> | \e scope_seq \n</td></tr>
172             <tr><td>level</td>           <td>::= \c VERBOSE | \c NOTICE | \c MESSAGE | \c IMPORTANT | \c CRITICAL | \c DISABLED \n</td></tr>
173             <tr><td>scope_seq</td>       <td>::= \e scope \e scope* \n</td></tr>
174             <tr><td>scope</td>           <td>::= <tt>(</tt> \e name <tt>)</tt> \n</td></tr>
175             <tr><td>name</td>            <td>::= arbitrary C++ identifier</td></tr>
176             </table>
177
178         \ref SENF_LOG_CONF is a Boost.Preprocessor style sequence of 3-tuples.
179
180         The first tuple element \e optional_stream specifies the stream to match. If this is
181         <tt>(_)</tt>, the entry will match any stream.
182
183         The next tuple element, \e optional_area optionally restricts the entry to match only the
184         given area. If set to <tt>(_)</tt>, the area is left unrestricted.
185
186         The last tuple element \e level defines the compile time log level. Messages with a level
187         below this are discarded at compile time.
188
189         Both \e optional_stream and \e optional_area are given as a \e scope_seq. A scope sequence
190         is a fully qualified C++ identifier placed into a sequence: <tt>foo::bar::baz</tt> is
191         represented by <tt>(foo)(bar)(baz)</tt>.
192      */
193 #   define SENF_LOG_CONF
194
195 #   endif
196
197     /** \brief Check, if logging is enabled for stream/area/level tuple
198
199         This is a template meta-function which will check, whether logging to the given combination
200         of parameters \a Stream, \a Area and \a Level is compile-time enabled. The logging might
201         still be disabled at runtime.
202         \code
203         if (senf::log::Enabled<senf::log::Debug,
204                                senf::log::DefaultArea,
205                                senf::log::VERBOSE>::value) {
206             // ...
207         }
208         \endcode
209
210         Since the \e value member is a compile time constant, the compiler will completely optimize
211         away this block of code when logging is disabled.
212      */
213     template <class Stream, class Area, class Level>
214     struct Enabled
215     {
216         static const bool value = (
217             (Level::value == NONE::value ? Stream::defaultLevel::value : Level::value)
218                 >= detail::Config<Stream,Area>::compileLimit::value );
219     };
220
221     //\}
222
223 }}
224
225 //-/////////////////////////////////////////////////////////////////////////////////////////////////
226 //#include "Config.cci"
227 //#include "Config.ct"
228 //#include "Config.cti"
229 #endif
230
231 \f
232 // Local Variables:
233 // mode: c++
234 // fill-column: 100
235 // comment-column: 40
236 // c-file-style: "senf"
237 // indent-tabs-mode: nil
238 // ispell-local-dictionary: "american"
239 // compile-command: "scons -u test"
240 // End: