6c1ae63b65525818a17931910b423de26b9e2af2
[senf.git] / 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_Config_
27 #define HH_Config_ 1
28
29 // Custom includes
30 #include "Levels.hh"
31
32 //#include "Config.mpp"
33 #include "Config.ih"
34 ///////////////////////////////hh.p////////////////////////////////////////
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 \ref Targets 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                              (( (foo)(Transactions),(_),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 then re-enables debug logging only within the
65     \c foo::SomeClass area, where it is set to \c VERBOSE. Furthermore, the limit on the \c
66     foo::Transactions stream is set to \c NOTICE.
67
68     \see \ref SENF_LOG_CONF
69
70     \section config_runtime Runtime configuration
71
72     The runtime configuration is performed by routing messages to one or more logging targets:
73     \code
74     senf::log::ConsoleLog & consoleLog (senf::log::ConsoleLog::instance());
75     senf::log::FileLog fileLog ("my.log");
76
77     consoleLog.route<senf::log::Debug>();
78     consoleLog.route<foo::Transactions, foo::SomeClass>(senf::log::Target::REJECT);
79     consoleLog.route<foo::Transactions, senf::log::IMPORTANT>();
80
81     fileLog.route<foo::Transactions>();
82     \endcode 
83     Here we see an already relatively complex setup: All debug messages (that is, those, which are
84     not disabled at compile time) are routed to the console. We also route important transactions to
85     the console \e except transactions from the \c foo::SomeClass area. The \c fileLog simply
86     receives all transaction log messages.
87
88     The routing statements are processed by the targets in order, the first matching rule will
89     decide a log messages fate for that target.
90     
91     There are two cases, where this setup may lead to inadvertently lost log messages:
92     \li When using a library which does internally use the Logger but not initializing the logger in
93         your application.
94     \li When log messages are created during initialization of static objects.
95     Since no route is set up in these cases, the messages will be dropped.
96     
97     To counter this problem, the logger is initially in <em>fallback routing</em> state. If any log
98     message arrives in this state, the message will be unconditionally logged to the console. The
99     first routing statement on any target will take the logger out of this state and normal routing
100     will take place.
101
102     \see \ref senf::log::Target
103
104     \section config_timesource Log message timing
105
106     One auxiliary aspect of logging is message timing. Each message is stamped with a time-stamp
107     giving the exact time the message was created. How the current date/time value is created may be
108     changed by setting a \e TimeSource. A TimeSource is an instance derived from
109     senf::log::TimeSource which will return the current universal time (UTC) when called.
110
111     By default, the logging library will call gettimeofday() for each log message. To change the
112     time source, just pass the new class or instance to senf::log::timeSource:
113     \code
114     // Use senf::Scheduler::instance().eventTime() to time log messages
115     senf::log::timeSource<senf::SchedulerLogTimeSource>();
116     \endcode
117  */
118
119 namespace senf {
120 namespace log {
121
122     ///\ingroup config
123     ///\{
124
125 #   ifdef DOXYGEN
126
127     /** \brief Compile time configuration
128
129         This define symbol sets the compile time logger configuration. This symbol should normally
130         be set on the compiler command line.
131
132         The formal syntax of this option is:
133
134         \par ""
135             <table class="ebnf">
136             <tr><td>conf</td>         <td>::= \e element \e element* \n</td></tr>
137             <tr><td>element</td>      <td>::= <tt>((</tt> \e stream <tt>,</tt> \e optional_area <tt>,</tt> \e level <tt>))</tt> \n</td></tr>
138             <tr><td>stream</td>       <td>::= \e scope_seq \n</td></tr>
139             <tr><td>optional_area</td><td>::= <tt>(_)</tt> | \e scope_seq \n</td></tr>
140             <tr><td>level</td>        <td>::= \c VERBOSE | \c NOTICE | \c MESSAGE | \c IMPORTANT | \c CRITICAL | \c DISABLED \n</td></tr>
141             <tr><td>scope_seq</td>    <td>::= \e scope \e scope \e scope* \n</td></tr>
142             <tr><td>scope</td>        <td>::= <tt>(</tt> \e name <tt>)</tt> \n</td></tr>
143             <tr><td>name</td>         <td>::= arbitrary C++ identifier</td></tr>
144             </table>
145
146         \ref SENF_LOG_CONF is a Boost.Preprocessor style sequence of 3-tuples. Each tuple applies to
147         a specific stream which is defined by the first tuple element \e stream. 
148
149         The next tuple element, \e optional_area optionally restricts the entry to match only the
150         given area. 
151
152         The last tuple element \e level defines the compile time log level. Messages with a level
153         below this are discarded at compile time.
154
155         Both \e stream and \e optional_area are given as a \e scope_seq. A scope sequence is a fully
156         qualified C++ identifier placed into a sequence: <tt>foo::bar::baz</tt> is represented by
157         <tt>(foo)(bar)(baz)</tt>.
158      */
159 #   define SENF_LOG_CONF
160
161 #   endif
162
163     /** \brief Check, if logging is enabled for stream/area/level tuple
164         
165         This is a template meta-function which will check, whether logging to the given combination
166         of parameters \a Stream, \a Area and \a Level is compile-time enabled. The logging might
167         still be disabled at runtime.
168         \code
169         if (senf::log::Enabled<senf::log::Debug, 
170                                senf::log::DefaultArea, 
171                                senf::log::VERBOSE>::value) {
172             // ...
173         }
174         \endcode
175
176         Since the \e value member is a compile time constant, the compiler will completely optimize
177         away this block of code when logging is disabled.
178      */
179     template <class Stream, class Area, class Level>
180     struct Enabled
181     {
182         static const bool value = (
183             (Level::value == NONE::value ? Stream::defaultLevel::value : Level::value)
184                 >= detail::Config<Stream,Area>::compileLimit::value );
185     };
186
187     ///\}
188
189 }}
190
191 ///////////////////////////////hh.e////////////////////////////////////////
192 //#include "Config.cci"
193 //#include "Config.ct"
194 //#include "Config.cti"
195 #endif
196
197 \f
198 // Local Variables:
199 // mode: c++
200 // fill-column: 100
201 // comment-column: 40
202 // c-file-style: "senf"
203 // indent-tabs-mode: nil
204 // ispell-local-dictionary: "american"
205 // compile-command: "scons -u test"
206 // End: