X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Utils%2FLogger%2FConfig.hh;h=9f0f73541b202cc46897aad2b559ff02446f098c;hb=412024ed31a4ab4eaea7a4165a434f8efebee325;hp=0cc836281d85b6eb63bd5d01034bd66625fe25a7;hpb=b52002fa2001e6472d6aa3dde263b85f654c6e8e;p=senf.git diff --git a/Utils/Logger/Config.hh b/Utils/Logger/Config.hh index 0cc8362..9f0f735 100644 --- a/Utils/Logger/Config.hh +++ b/Utils/Logger/Config.hh @@ -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 // // 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" @@ -33,17 +33,193 @@ #include "Config.ih" ///////////////////////////////hh.p//////////////////////////////////////// +/** \defgroup config Configuration + + The logger infrastructure provides for very fine-grained configuration of log messages. There + are two parts to this configuration: compile-time configuration and runtime configuration. + + Compile-time configuration selects, which log statements will even be compiled. If + logging for a certain combination of stream, area and level is disabled at compile time, no code + will be generated for any such disabled log statement. This type of configuration is done using + \ref SENF_LOG_CONF. + + Runtime 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 ::Target interface. + + \section config_compile Compile time configuration + + Compile time configuration is set on the compiler command line: +
+    g++ ... -DSENF_LOG_CONF="(( (senf)(log)(Debug),(_),DISABLED ))
+                             (( (senf)(log)(Debug),(foo)(SomeClass),VERBOSE ))
+                             (( (_),(_),NOTICE ))" ...
+    
+ 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. + + 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 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: +
+    # 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 ))"
+    
+ + 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 + + \section config_runtime Runtime configuration + + The runtime configuration is performed by routing messages to one or more logging targets: + \code + senf::log::ConsoleTarget & consoleLog (senf::log::ConsoleTarget::instance()); + senf::log::FileTarget fileLog ("my.log"); + + consoleLog.route(); + consoleLog.route(senf::log::Target::REJECT); + consoleLog.route(); + + fileLog.route(); + \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 + your application. + \li When log messages are created during initialization of static objects. + Since no route is set up in these cases, the messages will be dropped. + + To counter this problem, the logger is initially in fallback routing state. If any log + 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 + + \section config_timesource Log message timing + + One auxiliary aspect of logging is message timing. Each message is stamped with a time-stamp + giving the exact time the message was created. How the current date/time value is created may be + changed by setting a \e TimeSource. A TimeSource is an instance derived from + senf::log::TimeSource which will return the current universal time (UTC) when called. + + 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::eventTime() to time log messages + senf::log::timeSource(); + \endcode + */ + namespace senf { namespace log { + ///\ingroup config + ///\{ + +# ifdef DOXYGEN + + /** \brief Compile time configuration + + This define symbol sets the compile time logger configuration. This symbol should normally + be set on the compiler command line. + + The formal syntax of this option is: + + \par "" + + + + + + + + + +
conf ::= \e element \e element* \n
element ::= (( \e optional_stream , \e optional_area , \e level )) \n
optional_stream ::= (_) | \e scope_seq \n
optional_area ::= (_) | \e scope_seq \n
level ::= \c VERBOSE | \c NOTICE | \c MESSAGE | \c IMPORTANT | \c CRITICAL | \c DISABLED \n
scope_seq ::= \e scope \e scope* \n
scope ::= ( \e name ) \n
name ::= arbitrary C++ identifier
+ + \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 + (_), the entry will match any stream. + + The next tuple element, \e optional_area optionally restricts the entry to match only the + given area. If set to (_), 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 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: foo::bar::baz is + represented by (foo)(bar)(baz). + */ +# define SENF_LOG_CONF + +# endif + + /** \brief Check, if logging is enabled for stream/area/level tuple + + This is a template meta-function which will check, whether logging to the given combination + of parameters \a Stream, \a Area and \a Level is compile-time enabled. The logging might + still be disabled at runtime. + \code + if (senf::log::Enabled::value) { + // ... + } + \endcode + + Since the \e value member is a compile time constant, the compiler will completely optimize + away this block of code when logging is disabled. + */ template struct Enabled { static const bool value = ( - (Level::value == senf::log::NONE::value ? Stream::defaultLevel::value : Level::value) + (Level::value == NONE::value ? Stream::defaultLevel::value : Level::value) >= detail::Config::compileLimit::value ); }; + ///\} + }} ///////////////////////////////hh.e////////////////////////////////////////