00001 #ifndef MSGLOGSTREAM_HH 00002 #define MSGLOGSTREAM_HH 00003 00004 //-------------------------------------------------------------------------- 00005 // File and Version Information: 00006 // $Id: MsgLogStream.h 8866 2014-09-06 01:04:00Z dubrovin@SLAC.STANFORD.EDU $ 00007 // 00008 // Description: 00009 // Class MsgLogStream. 00010 // 00011 // Environment: 00012 // This software was developed for the BaBar collaboration. If you 00013 // use all or part of it, please give an appropriate acknowledgement. 00014 // 00015 // Author List: 00016 // Andy Salnikov 00017 // 00018 // Copyright Information: 00019 // Copyright (C) 2005 SLAC 00020 // 00021 //------------------------------------------------------------------------ 00022 00023 //------------- 00024 // C Headers -- 00025 //------------- 00026 extern "C" { 00027 } 00028 00029 //--------------- 00030 // C++ Headers -- 00031 //--------------- 00032 #include <string> 00033 #include <sstream> 00034 00035 //---------------------- 00036 // Base Class Headers -- 00037 //---------------------- 00038 00039 //------------------------------- 00040 // Collaborating Class Headers -- 00041 //------------------------------- 00042 #include "MsgLogger/MsgLogLevel.h" 00043 #include "MsgLogger/MsgLogger.h" 00044 00045 //------------------------------------ 00046 // Collaborating Class Declarations -- 00047 //------------------------------------ 00048 00049 // --------------------- 00050 // -- Class Interface -- 00051 // --------------------- 00052 00053 /** 00054 * Macros(grrr!) for user's convenience 00055 */ 00056 #ifdef MsgLog 00057 #undef MsgLog 00058 #endif 00059 /** 00060 * @def MsgLog(logger,sev,msg) 00061 * 00062 * @brief Macro which sends single message to a named logger in logging service. 00063 * 00064 * @param logger Name of the logger 00065 * @param sev Severity level (one of debug, trace, info, warning, error) 00066 * @param msg Message, anything that can appear on the right side of << operator. 00067 * 00068 * This macro provides convenience method for working with the messaging facility. 00069 * If the logging level configured by application for the given logger name (first argument) 00070 * allows messages of the given severity (second argument) then everything included in 00071 * the last argument is formatted via << insertion operator and sent to logging service. 00072 * Brief example: 00073 * @code 00074 * MsgLog("logger", debug, "key = " << key << " value = " << value << " count = " << count); 00075 * @endcode 00076 */ 00077 #define MsgLog(logger,sev,msg) \ 00078 if ( MsgLogger::MsgLogger(logger).logging(MsgLogger::MsgLogLevel(MsgLogger::MsgLogLevel::sev)) ) { \ 00079 MsgLogger::MsgLogStream _msg_log_stream_123(logger, MsgLogger::MsgLogLevel(MsgLogger::MsgLogLevel::sev), __FILE__, __LINE__) ;\ 00080 _msg_log_stream_123.ostream_hack() << msg ; \ 00081 } 00082 00083 #ifdef MsgLogRoot 00084 #undef MsgLogRoot 00085 #endif 00086 /** 00087 * @def MsgLogRoot(sev,msg) 00088 * 00089 * @brief Macro which sends single message to a root logger in logging service. 00090 * 00091 * @param sev Severity level (one of debug, trace, info, warning, error) 00092 * @param msg Message, anything that can appear on the right side of << operator. 00093 * 00094 * See @c MsgLog for details. Brief example: 00095 * @code 00096 * MsgLogRoot(debug, "key = " << key << " value = " << value << " count = " << count); 00097 * @endcode 00098 */ 00099 #define MsgLogRoot(sev,msg) \ 00100 if ( MsgLogger::MsgLogger().logging(MsgLogger::MsgLogLevel(MsgLogger::MsgLogLevel::sev)) ) { \ 00101 MsgLogger::MsgLogStream _msg_log_stream_123(MsgLogger::MsgLogLevel(MsgLogger::MsgLogLevel::sev), __FILE__, __LINE__) ;\ 00102 _msg_log_stream_123.ostream_hack() << msg ; \ 00103 } 00104 00105 #ifdef WithMsgLog 00106 #undef WithMsgLog 00107 #endif 00108 /** 00109 * @def WithMsgLog(logger,sev,str) 00110 * 00111 * @brief Macro which provides scoped logging stream with output sent to a named logger. 00112 * 00113 * @param logger Name of the logger 00114 * @param sev severity level (one of debug, trace, info, warning, error) 00115 * @param str stream 00116 * 00117 * The use of this macro must be followed by the compound statement (enclosed in {}). The stream defined by this 00118 * macro (last argument) is available inside the compound statement and can be used multiple times. All output to 00119 * this stream is collected and is sent to the messaging service at the end of the scope of the compound statement; 00120 * complete output appears as a single message. This macro is useful when output is produced inside loop or 00121 * if/then/else statement. Brief example: 00122 * @code 00123 * WithMsgLog("logger", debug, out) { 00124 * if (condition) out << "condition is true, "; 00125 * out << "values: "; 00126 * for (int i = 0; i < max; ++ i) out << ' ' << value[i]; 00127 * } 00128 * @endcode 00129 */ 00130 #define WithMsgLog(logger,sev,str) \ 00131 for ( MsgLogger::MsgLogStream str(logger, MsgLogger::MsgLogLevel(MsgLogger::MsgLogLevel::sev), __FILE__ , __LINE__) ; str.ok() ; str.finish() ) 00132 00133 #ifdef WithMsgLogRoot 00134 #undef WithMsgLogRoot 00135 #endif 00136 /** 00137 * @def WithMsgLogRoot(sev,str) 00138 * 00139 * @brief Macro which provides scoped logging stream with output sent to a root logger. 00140 * 00141 * @param sev severity level (one of debug, trace, info, warning, error) 00142 * @param str stream 00143 * 00144 * See @c WithMsgLog for details. Brief example: 00145 * @code 00146 * WithMsgLogRoot(debug, out) { 00147 * if (condition) out << "condition is true, "; 00148 * out << "values: "; 00149 * for (int i = 0; i < max; ++ i) out << ' ' << value[i]; 00150 * } 00151 * @endcode 00152 */ 00153 #define WithMsgLogRoot(sev,str) \ 00154 for ( MsgLogger::MsgLogStream str(MsgLogger::MsgLogLevel(MsgLogger::MsgLogLevel::sev), __FILE__ , __LINE__) ; str.ok() ; str.finish() ) 00155 00156 namespace MsgLogger { 00157 00158 /** 00159 * @ingroup MsgLogger 00160 * 00161 * Special stream class (subclass of standard stream class) which collects 00162 * the message source and forwards complete message to the logger class 00163 * on destruction. 00164 * 00165 * This software was developed originally for the BaBar collaboration and 00166 * adapted/rewritten for LUSI. 00167 * 00168 * Copyright (C) 2005 SLAC 00169 * 00170 * @see MsgLogger 00171 * 00172 * @version $Id: MsgLogStream.h 8866 2014-09-06 01:04:00Z dubrovin@SLAC.STANFORD.EDU $ 00173 * 00174 * @author Andy Salnikov 00175 */ 00176 00177 class MsgLogStream : public std::stringstream { 00178 00179 public: 00180 00181 /** 00182 * Constructors. 'file' argument is usually a filenamestring constructed from 00183 * __FILE__ macros. It is char* type instead of std::string for optimization 00184 * reasons (crappy C++ has no compile-time constructors for classes.) The pointer is stored 00185 * in an object, content is not copied, so make sure that you don't overwrite the string you pass. 00186 */ 00187 explicit MsgLogStream ( MsgLogLevel sev, const char* file = 0, int line = -1 ) ; 00188 MsgLogStream ( const std::string& loggerName, MsgLogLevel sev, const char* file = 0, int line = -1 ) ; 00189 00190 // Destructor 00191 virtual ~MsgLogStream() ; 00192 00193 // g++ somehow fails to recognize temporary MsgLogStream() as a good stream, 00194 // had to add this "cast" operation 00195 std::ostream& ostream_hack() { return *this ; } 00196 00197 // send my content to logger 00198 void emit_content() ; 00199 00200 // get the state of the stream 00201 bool ok() const { return _ok ; } 00202 00203 // set the state of the stream to "not OK" 00204 void finish() { _ok = false ; } 00205 00206 protected: 00207 00208 private: 00209 00210 // Data members 00211 std::string _logger ; 00212 MsgLogLevel _sev ; 00213 const char* _file ; 00214 int _lineNum ; 00215 bool _ok ; 00216 00217 // Note: if your class needs a copy constructor or an assignment operator, 00218 // make one of the following public and implement it. 00219 MsgLogStream( const MsgLogStream& ); // Copy Constructor 00220 MsgLogStream& operator= ( const MsgLogStream& ); // Assignment op 00221 00222 }; 00223 00224 } // namespace MsgLogger 00225 00226 #endif // MSGLOGSTREAM_HH