X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Utils%2FLogger%2FMainpage.dox;h=7a5509d6599d071c910cbc40c474ce24888f1269;hb=532240d72e09e19e57fac9bb55c2560b9c9e5b97;hp=9bd611877aabbf630d027cf97a9eecdabbb5d031;hpb=b52002fa2001e6472d6aa3dde263b85f654c6e8e;p=senf.git diff --git a/Utils/Logger/Mainpage.dox b/Utils/Logger/Mainpage.dox index 9bd6118..7a5509d 100644 --- a/Utils/Logger/Mainpage.dox +++ b/Utils/Logger/Mainpage.dox @@ -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 @@ -29,96 +29,122 @@ targets at the same time. To allow concise usage of the library, a utility to define logging defaults for any scope is provided. - An important basic concept of the library is, that most of the macros take a variable number of - arguments. Since this is not supported in the needed manner by the C++ preprocessor, the - arguments are encoded into a Boost.Preprocessor like - sequence: + \see + \ref logging \n + \ref config \n + \ref targets \n + \ref loglevels + + \section logging_concepts Concepts + + Log messages are arbitrarily created throughout the code using simple log statements (which are + macros). Besides the log message itself, every log message is labeled with additional + information: The \e stream, the \e area and a log \e level. If the message is not compile-time + disabled, the message is then directed to one or several log \e targets. + + A \e stream combines log messages with a single purpose: Debug messages, access logging and so + on. Any number of streams may be defined. There is one predefined default stream called \c + senf::log::Debug. (see: \ref SENF_LOG_DEFINE_STREAM) + + The \e area gives information about the source location of the message. Areas may be defined and + assigned arbitrarily but should be used to label messages from a single class or subsystem. It + is possible to reuse a class as it's own area tag, which is often desireable. There is a + default area \c senf::log::DefaultArea which is used, when no other area is assigned. (see: \ref + SENF_LOG_DEFINE_AREA, \ref SENF_LOG_CLASS_AREA) + + The log \e level gives information on the importance of the message. The list of log-levels is + fixed. (see: \ref loglevels) + + Depending on their the \e stream, \e area and \e level information, log messages can be enabled + or disabled at \e compile time. Messages disabled at compile time should not generate any + code. (see: \ref SENF_LOG_CONF) + + \attention The default log stream senf::log::Debug has senf::log::VERBOSE messages + disabled at compile time. senf::log::VERBOSE message will therefore only appear, + if you explictly enable the messages for the area in question using (here for the area + some::Area) +
 
+        g++ ... -DSENF_LOG_CONF="(( (senf)(log)(Debug), (some)(Area), VERBOSE ))" 
+        
+ in addition to routing the messages at runtime. For more, see \ref config. + + To be of any use, the log messages have to be written somewhere. This is the responsibility of + any number of \e targets. A \e target receives messages and using it's routing information + decides, wether the message is output or not. A message may be routed to multiple targets + simultaneously or may not be output by any target at all. (see: \ref targets) + + \section logging_tutorial Tutorial introduction + + Using the logging library mostly concerns using \ref SENF_LOG statements in your code. There are + some other helpers used to simplify specifying parameters. \code - SENF_LOG( (senf::log::Debug)(senf::log::NOTICE)(FroblizerArea)("The log message") ); - \endcode - - The last sequence element always is the log message. Before that we have a number of log - parameters in arbitrary order. Since giving all the parameters in every log message is to - verbose, there are two helpful constructs to reduce the verbosity. Using \ref - SENF_LOG_DEFAULT_STREAM, \ref SENF_LOG_DEFAULT_AREA and \ref SENF_LOG_DEFAULT_LEVEL it is - possible to define the default logging parameters to be used within a given scope. Using \ref - SENF_LOG_DEF_ALIAS you can define an alias (which is a scoped symbol) as an arbitrary - combination of parameters. + namespace foo { - \code - SENF_LOG_DEF_STREAM( userLog, senf::log::MESSAGE, senf::log::MESSAGE ); + // Define a new log stream with default level, runtime limit and compile time limit + // set to senf::log::MESSAGE + SENF_LOG_DEFINE_STREAM( UserLog, senf::log::MESSAGE, senf::log::MESSAGE, senf::log::MESSAGE ); - class Froblizer - { - // Define a new log area - SENF_LOG_DEF_AREA(FroblizerArea); + class Froblizer + { + // Define a log area which will automatically be used by all members of this class. + // This is a combination of SENF_LOG_DEFINE_AREA and SENF_LOG_DEFAULT_AREA. + SENF_LOG_CLASS_AREA(); - // Set default log parameters for this scope - SENF_LOG_DEFAULTS((senf::log::Debug)(senf::log::NOTICE)(FroblizerArea)); + // Set default log parameters for this scope. + SENF_LOG_DEFAULT_STREAM(foo::UserLog); + SENF_LOG_DEFAULT_LEVEL(senf::log::NOTICE); - // Define an alias for emergency messages to the sysadmin. - // The log area is inherited from the default at the place, where this - // alias is used *not* where it is defined - SENF_LOG_DEF_ALIAS(LogEmerg, (userLog)(senf::log::CRITICAL)); + // Define an alias for emergency debug messages + // The log area is inherited from the default at the place, where this + // alias is used *not* where it is defined + SENF_LOG_DEFINE_ALIAS(LogEmerg, (senf::log::Debug)(senf::log::CRITICAL)); - void test(); + void test(); - public: - void froblize(); - }; + public: + void froblize(); + }; + } - void Froblizer::froblize() + void foo::Froblizer::froblize() { - SENF_LOG(("This is the Debug stream at level NOTICE in the FroblizeArea")); - SENF_LOG((senf::log::WARNING) ("Same stream and area but at warning level")); - SENF_LOG((LogEmerg) ("This goes to the userLog at level CRITICAL in the FroblizerArea")); + SENF_LOG(("This is the UserLog at level NOTICE in the FroblizeArea")); + SENF_LOG((senf::log::IMPORTANT) ("Same stream and area but at important level")); + SENF_LOG((LogEmerg) ("This goes to the DebugLog at level CRITICAL in the FroblizerArea")); } - void Froblizer::test() + void foo::Froblizer::test() { // Change the default log level for this method. stream and area are taken // from the next scope up - SENF_LOG_DEFAULTS((senf::log::VERBOSE)); + SENF_LOG_DEFAULT_LEVEL(senf::log::VERBOSE); + + SENF_LOG(("Log to UserLog stream in Froblizer area however at VERBOSE level")); + } - SENF_LOG(("Log to Debug stream in Froblizer area however at VERBOSE level")); + int main(int, char **) + { + // Set up the routing targets + senf::log::ConsoleTarget & console (senf::log::ConsoleTarget::instance()); + senf::log::FileTarget logfile ("my.log"); + + // Debug messages go to the console + console.route(); + // Important user message are written to the log file + logfile.route(); } \endcode - Currently, the library is not implemented in any way. The interface has been defined up to a - point and we have dummy implementations of the 'in-code' part of the interface. This is the - part, which is called throughout the code. The configuration API is defined but we don't even - have a template implementation. However, this allows starting to use the SENF Logger in newly - developed code. Even though this code will unconditionally log everything to \c std::cerr for - now and errors in the parameter specification will not be caught (since they are just ignored) - the logging should work automatically as advertised as soon as the logger is completely - implemented. - - I did not find any implementation which was not either completely convoluted, unusable or - slow. So I turned to a macro based implementation which can provide all the design goals stated - above. - - \section logger_compile_conf Compile time configuration - - The logger infrastructure allows to enable or disable log levels or areas at compile - time. Levels or areas disabled at compile time do not generate any code. The compile time - configuration is done in two parts: When defining log streams, default log levels and log level - limits are defined. Additionally the \c SENF_LOG_CONF symbol can be defined to customize this - default configuration. - - The \c SENF_LOG_CONF symbol is a Boost.Preprocessor style sequence of sequences: -
-    g++ ... -DSENF_LOG_CONF="((senf::log::Debug)(_)(DISABLED)) \
-                             ((senf::log::Debug)(foo::FooArea)(VERBOSE))" ...
-    
- Each element defines the compile time limit for a stream and optional area. - \implementation I would have much preferred a more C++ like implementation. However given the - design goals - \li Flexible configuration at compile and runtime - \li Concise usage and simple interface - \li Zero overhead for compile-time disabled log messages + design goals + \li Flexible configuration at compile and runtime + \li Concise usage and simple interface + \li Zero overhead for compile-time disabled log messages + + I did not find any non-mcaro implementation which was not either completely convoluted, + unusable or slow. So I turned to a macro based implementation which can provide all the + design goals stated above. */