00f192cf2293dbe3796f865616596a52a6a3114c
[senf.git] / senf / Utils / Logger / Log.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 Log public header */
25
26 #ifndef HH_SENF_Utils_Logger_Log_
27 #define HH_SENF_Utils_Logger_Log_ 1
28
29 // Custom includes
30 #include <boost/preprocessor/seq/size.hpp>
31 #include <boost/preprocessor/dec.hpp>
32 #include <boost/preprocessor/seq/elem.hpp>
33 #include <boost/preprocessor/seq/pop_back.hpp>
34 #include "Parameters.hh"
35
36 //#include "Log.mpp"
37 #include "Log.ih"
38 //-/////////////////////////////////////////////////////////////////////////////////////////////////
39
40 /** \defgroup logging Logging commands
41
42     The logging library provides several commands to create %log messages. All these macro commands
43     take a variable number of arguments. Since this is not supported in a usable way by the C++
44     preprocessor, the arguments are encoded into a <a
45     href="http://www.boost.org/doc/libs/release/libs/preprocessor/doc/index.html">Boost.Preprocessor</a>
46     like sequence:
47
48     \code
49     SENF_LOG( (senf::log::Debug)(senf::log::NOTICE)(FroblizerArea)("The log message") );
50     \endcode
51
52     The argument is comprised of a sequence of parameters and the %log message itself.
53     The parameters are
54     - the <em>%log stream</em>,
55     - the <em>%log area</em>,
56     - the <em>%log level</em>.
57
58     These parameters are optional and may be specified <i>in arbitrary order</i> (with the %log
59     message always being the last sequence element) and even multiple times in the parameter
60     sequence. If some argument type occurs multiple times, the last occurrence wins. If any one of
61     the parameters is not specified, it's current default value will be used.
62
63     This current default value is set using \ref SENF_LOG_DEFAULT_STREAM, \ref SENF_LOG_DEFAULT_AREA
64     and \ref SENF_LOG_DEFAULT_LEVEL respectively. These macros set the default stream, area and/or
65     level <em>of the current scope</em>. They may be used with a class declaration to set defaults
66     for all class members or within a function or member body to set the default for that member
67     only. They may be used only \e once within each scope.
68
69     The logging library defines the global defaults for stream, area and level to be \c
70     senf::log::Debug, senf::log::DefaultArea, and senf::log::NONE respectively.
71
72     The %log level senf::log::NONE is special. If the %log level is set to this value, the %log level
73     will be set from the stream provided default value.
74
75     All these parameters must be <em>compile time constants</em> (they are all types, so it's
76     difficult for them to be something else).
77
78     \section logging_aliases Aliases
79
80     To further simplify logging commands, aliases may be defined within any scope. An alias is an
81     arbitrary collection of %log parameters:
82     \code
83     SENF_LOG_DEFINE_ALIAS( VerboseDebug, (senf::log::Debug)(senf::log::VERBOSE) );
84     \endcode
85     Within %log statements, aliases may be used like normal parameters. They will be substituted for
86     the parameter sequence they represent:
87     \code
88     SENF_LOG( (VerboseDebug)("Debug message") )
89     // is equivalent to
90     SENF_LOG( (senf::log::Debug)(senf::log::VERBOSE)("Debug message") )
91     \endcode
92     Aliases may be used together with other parameters, even with further aliases in any order.
93  */
94
95 ///\addtogroup logging
96 //\{
97
98 ///\name Generating log messages
99 //\{
100
101 /** \brief Write log message
102
103     This macro will write it's last argument to the log stream. The last argument must be an
104     expression which will be placed after a streaming \c operator<< (like
105     <i>some-log-stream</i> \c << <i>last-macro-arg</i>).
106     \code
107     SENF_LOG((parameters...)("log message " << args << ...));
108     \endcode
109
110     \hideinitializer
111  */
112 #define SENF_LOG(args)                                                                            \
113     SENF_LOG_BLOCK_( SENF_LOG_MERGE_PARAMETERS(BOOST_PP_SEQ_POP_BACK(args)),                      \
114                      { log << BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args); })
115
116 /** \brief Write log message (template context)
117
118     This macro is used like \ref SENF_LOG() if called from a template context
119
120     \hideinitializer
121  */
122 #define SENF_LOG_TPL(args)                                                                        \
123     SENF_LOG_BLOCK_TPL_( SENF_LOG_MERGE_PARAMETERS_TPL(BOOST_PP_SEQ_POP_BACK(args)),              \
124                          { log << BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args); })
125
126 /** \brief Enable block based on logging parameters
127
128     This macro is like SENF_LOG, however instead of writing a simple message, this macro allows
129     to specify a complete block of code to be executed if the log message is enabled.
130     \code
131     SENF_LOG_BLOCK((parameters...)({
132        // arbitrary code using 'log' for logging
133        log << "log message";
134     }));
135     \endcode
136
137     \hideinitializer
138  */
139 #define SENF_LOG_BLOCK(args)                                                                      \
140     SENF_LOG_BLOCK_( SENF_LOG_MERGE_PARAMETERS(BOOST_PP_SEQ_POP_BACK(args)),                      \
141                      BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args))
142
143 /** \brief Write log message (template context)
144
145     This macro is used like \ref SENF_LOG_BLOCK() if called from a template context
146
147     \hideinitializer
148  */
149 #define SENF_LOG_BLOCK_TPL(args)                                                                  \
150     SENF_LOG_BLOCK_TPL_( SENF_LOG_MERGE_PARAMETERS_TPL(BOOST_PP_SEQ_POP_BACK(args)),              \
151                          BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(args)),args))
152
153 //\}
154 //\}
155
156 //-/////////////////////////////////////////////////////////////////////////////////////////////////
157 //#include "Log.cci"
158 //#include "Log.ct"
159 //#include "Log.cti"
160 #endif
161
162 \f
163 // Local Variables:
164 // mode: c++
165 // fill-column: 100
166 // comment-column: 40
167 // c-file-style: "senf"
168 // indent-tabs-mode: nil
169 // ispell-local-dictionary: "american"
170 // compile-command: "scons -u test"
171 // End: