00001 /* 00002 The lestes compiler suite 00003 Copyright (C) 2002, 2003, 2004, 2005 Miroslav Tichy 00004 Copyright (C) 2002, 2003, 2004, 2005 Petr Zika 00005 Copyright (C) 2002, 2003, 2004, 2005 Vojtech Hala 00006 Copyright (C) 2002, 2003, 2004, 2005 Jiri Kosina 00007 Copyright (C) 2002, 2003, 2004, 2005 Pavel Sanda 00008 Copyright (C) 2002, 2003, 2004, 2005 Jan Zouhar 00009 Copyright (C) 2002, 2003, 2004, 2005 Rudolf Thomas 00010 00011 This program is free software; you can redistribute it and/or modify 00012 it under the terms of the GNU General Public License as published by 00013 the Free Software Foundation; version 2 of the License. 00014 00015 This program is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU General Public License for more details. 00019 00020 See the full text of the GNU General Public License version 2, and 00021 the limitations in the file doc/LICENSE. 00022 00023 By accepting the license the licensee waives any and all claims 00024 against the copyright holder(s) related in whole or in part to the 00025 work, its use, and/or the inability to use it. 00026 00027 */ 00028 #ifndef lestes__msg___logger_hh___included 00029 #define lestes__msg___logger_hh___included 00030 00031 /*! \file 00032 * Logger and the llog macro. 00033 * \author Rudo 00034 */ 00035 00036 /*! 00037 * The llog macro calls fullname_formatter on given logger, which prints full 00038 * name of the logger followed by ": ". You can use the << operator in the result. 00039 */ 00040 #define llog( logger ) ((*(logger)) << ::lestes::msg::fullname_formatter::instance()) 00041 00042 /*! 00043 * The llog_plain macro calls plain_formatter on given logger. The plain_formatter does 00044 * nothing except returning the logger's ostream. 00045 */ 00046 #define llog_plain( logger ) ((*(logger)) << ::lestes::msg::plain_formatter::instance()) 00047 00048 /*! 00049 * The llog_xml_open macro outputs opening xml tag with given name to given 00050 * logger. The tag contains attribute named 'by' filled with full path of the 00051 * logger. xml_formatter is used to achieve this. 00052 * 00053 * Note: To avoid the 'by' attribute, simply use llog_plain. 00054 */ 00055 #define llog_xml_open( logger, tag ) \ 00056 (::lestes::msg::xml_formatter::instance()->tag_name_set(tag), \ 00057 *(logger) << ::lestes::msg::xml_formatter::instance()) 00058 /*! 00059 * The llog_xml_close prints closing tag with specified name to given logger. 00060 * It is just a simple wrapper around llog_plain. 00061 */ 00062 #define llog_xml_close( logger, tag ) \ 00063 ((*(logger)) << ::lestes::msg::plain_formatter::instance() << "</" << (tag) << '>') 00064 00065 /*! 00066 * \brief declares logger with specified name, used in namespace scope 00067 * 00068 * The declare_logger macro declares [extern] variable with given name, its type is 00069 * ptr<logger>; the variable is ready to be passed to llog family of macros. 00070 * The actual definition of the variable is handled by initialize_top_logger 00071 * and initialize_logger macros. 00072 * 00073 * The macro can only be used in namespace scope. It can be used in a header file. 00074 * 00075 * Note: The macro also declares a function named variable_name##_init (i.e. 00076 * passed name suffixed with _init) which is used to initialize the pointer. 00077 */ 00078 #define declare_logger( variable_name ) \ 00079 extern ::lestes::std::ptr< ::lestes::msg::logger > variable_name; \ 00080 const ::lestes::std::ptr< ::lestes::msg::logger > & variable_name##_init(); 00081 00082 /*! 00083 * \brief declares the logger variable with correct initializer 00084 * 00085 * The initialize_logger macro declares the logger variable and initializes it. 00086 * Name of the logger instance and name of variable with a pointer to parent 00087 * logger are passed as arguments. The parent variable must be declared and 00088 * initialized using declare_logger and initialize_logger (or 00089 * initialize_top_logger) macros. 00090 * 00091 * The macro can only be used in namespace scope. It MUST NOT be used in a header file. 00092 * 00093 * Note: The macro also defines a function used to initialize the pointer. 00094 * Such function of the parent logger is called from it. By analogy, this 00095 * function is used when the logger is used as a parent in different 00096 * initialize_logger macro invocation. 00097 */ 00098 #define initialize_logger( variable_name, logger_name, parent_variable ) \ 00099 ptr< ::lestes::msg::logger > variable_name = variable_name##_init(); \ 00100 \ 00101 const ptr< ::lestes::msg::logger > & variable_name##_init() \ 00102 { \ 00103 if (!variable_name) \ 00104 variable_name = ::lestes::msg::logger::create( \ 00105 logger_name, parent_variable##_init() ); \ 00106 return variable_name; \ 00107 } 00108 00109 /*! 00110 * \brief similar to initialize_logger, just the logger will be a child of the root one 00111 */ 00112 #define initialize_top_logger( variable_name, logger_name ) \ 00113 ptr< ::lestes::msg::logger > variable_name = variable_name##_init(); \ 00114 \ 00115 const ptr< ::lestes::msg::logger > & variable_name##_init() \ 00116 { \ 00117 if (!variable_name) \ 00118 variable_name = ::lestes::msg::logger::create( \ 00119 logger_name, ::lestes::msg::logger::root_instance() ); \ 00120 return variable_name; \ 00121 } 00122 00123 #include <lestes/common.hh> 00124 #include <lestes/std/map.hh> 00125 #include <lestes/std/objectize_macros.hh> 00126 #include <lestes/std/ostream_wrapper.hh> 00127 #include <lestes/msg/logger_formatters.hh> 00128 00129 #include <iosfwd> 00130 00131 package(lestes); 00132 package(msg); 00133 00134 class logger_formatter; 00135 00136 /*! 00137 * ... 00138 * One should only instantiate this class by hand when they know what they are doing. 00139 */ 00140 class logger : public ::lestes::std::object { 00141 friend class logger_configurator; 00142 public: 00143 //! Map that maps lstrings to loggers, used to store children of a logger. 00144 typedef map< lstring, srp<logger> > children_map_type; 00145 00146 //! Factory method, creates logger with given name. Also adds it to 'children' of given parent. 00147 static ptr<logger> create( const lstring & a_name, const ptr<logger> & a_parent ); 00148 //! Returns pointer to the root "grandparent" logger. 00149 static ptr<logger> root_instance(); 00150 //! Configures the logger tree by applying the settings found in given xml file. 00151 static bool init( const lstring & filename ); 00152 //! Closes all files open during init(). 00153 static void finish(); 00154 //! Traverses the logger tree starting at root_instance(), outputs xml configuration file with corresponding elements. 00155 static ::std::ostream & dump_skeleton( ::std::ostream & ); 00156 ptr<logger> parent_get() const; 00157 lstring name_get() const; 00158 ptr<children_map_type> children_get() const; 00159 ptr < logger_formatter > formatter_get() const; 00160 void formatter_set(ptr < logger_formatter > x); 00161 #ifdef ALL_LOGGER_GETTERS_NEEDED 00162 bool logging_get() const; 00163 bool logging_changed_get() const; 00164 #endif 00165 ::std::ostream & operator << ( const ptr<logger_formatter> & ); 00166 private: 00167 //! Whether this logger is supposed to actually do something. 00168 bool logging; 00169 //! True when logging field has already been changed. 00170 bool logging_changed; 00171 //! Pointer to a stream used for the actual logging. 00172 srp<ostream_wrapper> ostr; 00173 00174 //! Name of this logger. This does not include names of parents. 00175 const lstring name; 00176 //! Pointer to parent logger, the root logger points to self; checked. 00177 const srp<logger> parent; 00178 const srp<children_map_type> children; 00179 00180 //! the default formatter 00181 srp < logger_formatter > formatter; 00182 00183 //! Hold pointer to the root logger instance. 00184 static ptr<logger> the_root_instance; 00185 00186 typedef map< lstring, srp<ostream_wrapper> > files_map_type; 00187 static ptr<files_map_type> files_map; 00188 00189 //! Dumps all children (including "transitive" ones:) as xml to given ostream; used internally by dump_skeleton method. 00190 static void subtree_dump( const ptr<logger> &, ::std::ostream & ); 00191 00192 static ptr<ostream_wrapper> null_ostream; 00193 static ptr<ostream_wrapper> cerr_wrapper; 00194 //! This ctor is only used to construct the root logger. 00195 logger(); 00196 protected: 00197 //! Constructor run from the 'create' factory method. 00198 logger( const lstring & a_name, const ptr<logger> a_parent ); 00199 void gc_mark(); 00200 }; 00201 00202 end_package(msg); 00203 end_package(lestes); 00204 00205 #endif // lestes__msg___logger_hh___included
1.5.1-20070107