MsgLogger/include/MsgLogStream.h

Go to the documentation of this file.
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

Generated on 19 Dec 2016 for PSDMSoftware by  doxygen 1.4.7