// // File : ErrorLogger.h // // Purpose: Declaration of the class ErrorLogger // // $Id: ErrorLogger.hh 8758 2010-09-27 12:16:24Z mathes $ // /** @file ErrorLogger.hh * Declaration of the class ErrorLogger. * @author Lukas Nellen, UNAM Mexico, S. Argir`o, INFN Torino, * H.-J. Mathes, FzK */ #ifndef _FdUtil_ErrorLogger_hh_ #define _FdUtil_ErrorLogger_hh_ static const char CvsId_FdUtil_ErrorLogger[] = "$Id: ErrorLogger.hh 8758 2010-09-27 12:16:24Z mathes $"; #include #include #include #include #include #ifndef NO_VERSION # include #endif // NO_VERSION #include namespace FdUtil { // --- forward declaration(s) class ErrorLoggerStream; /** Interface to the FD (Error) logger. * * \brief Class to handle routing and writing of error messages. * * In order to initialize the ErrorLogger properly (especially when the * code or the code of the libraries used is using FD_C* macros, * @see ErrorLogging.hh ) one has to do something like: \verbatim #include using FdUtil::ErrorLogger; int main(int argc, char** argv) { ErrorLogger &logger = ErrorLogger::GetInstance(); logger.SetVerbosity(ErrorLogger::eTerse); logger.SetOption(ErrorLogger::eShowSeverity); logger.SetOption(ErrorLogger::eShowGPSTime); // eventually set a minimum logging level logger.SetLoggingLevel(ErrorLogger::eInfo); // ... users code exit( EXIT_SUCCESS ); } \endverbatim * * The default logging stream is 'std::clog'. */ class ErrorLogger : public FdUtil::Singleton { friend class FdUtil::Singleton; public: /** Message logging options. */ typedef enum ELoggingOption { eShowSeverity = 0x0001, ///< display severity level (INF, CRI, ...) eShowGPSTime = 0x0002, ///< display time in GPS format (overrides Unix) eShowUnixTime = 0x0004, ///< display time in Unix format eShowFilename = 0x0008, ///< display __FILE__ macro eShowLineNumber = 0x0010, ///< display __LINE__ macro eShowClassName = 0x0020, ///< display class name set by SetClassName() eShowFuncName = 0x0040 ///< display __func__ macro } ELoggingOption; /// Message severity levels typedef enum ESeverityLevel { eDebug = -1, ///< Debugging message eInfo = 0, ///< General (informational) message eWarning = 1, ///< Warning message eError = 2, ///< Error message eCritical = 3, ///< Critical error eSevere = 4, ///< Severe error eFatal = 5 ///< Fatal error message } ESeverityLevel; /// Message verbosity typedef enum EVerbosityLevel { eDefaultVerbosity = -1, ///< Use the default verbosity eTerse, ///< Terse error messages eVerbose ///< Verbose error messages } EVerbosityLevel; public: /** Get ACSII representation for passed int value. */ static std::string GetASCIIFromInt(unsigned int i, int width) { std::ostringstream str; str << std::setw(width) << i; return str.str(); } /** Get the current logging level. */ ErrorLogger::ESeverityLevel GetLoggingLevel() { return fLoggingLevel; } /** Get a reference to the ostream used by this class. */ std::ostream& GetStream(ESeverityLevel level=eInfo); /** Get the current verbosity level. */ ErrorLogger::EVerbosityLevel GetVerbosity() { return fVerbosity; } /** Get 'label' of the passed severity. */ static std::string GetVerboseSeverity(ErrorLogger::ESeverityLevel severity); /** Get short 'label' of the passed severity. */ static std::string GetVerboseSeverityShort(ErrorLogger::ESeverityLevel severity); /** \brief Return the status of the specified logging option. */ bool IsOptionSet(ELoggingOption option) { return fLoggingOption & (int)option; } /** General interface for logging a message. * * Write and format an error message. For verbose message logging, * the file name and line number are added to the beginning of the * file. The format is such that (X)Emacs can jump directly to the * corresponding line in the source file. */ void Log(ESeverityLevel severity, std::string functionName, std::string fileName, int lineNumber, std::string message, EVerbosityLevel verbosity = eDefaultVerbosity ) const; /** Dump message from \c ostringstream instead of of a \c string. */ void Log(ESeverityLevel severity, std::string functionName, std::string fileName, int lineNumber, std::ostringstream &message, EVerbosityLevel verbosity = eDefaultVerbosity ) const { Log(severity, functionName, fileName, lineNumber, message.str(), verbosity); }; /** \brief Set the error logging stream to point to the specified file. */ void SetFile(const char* filename); /** \brief Set the error logging stream to point to the specified file. */ void SetFile(const std::string filename) { SetFile( filename.c_str() ); } #if 0 // not working /** \brief Set the error logging stream to use the specified FILE handle. */ void SetFile(FILE *file); #endif /** \brief Set formatting options for the generated output message. */ void SetOption(ELoggingOption option, bool enable=true); /** \brief Set the logging level. * * Logging messages with a severity >= this level will be forwarded * to the logging stream, the rest goes to the null stream. * * @param level desired severity level for output * @param quiet setting of level is logged (default) or not */ void SetLoggingLevel(ESeverityLevel level,bool quiet=false); /** \brief Set the error logging stream. * * \note * This method has to be replaced by a more general mechanism * for the routing of messages. */ void SetStream(std::ostream *stream) { fOStream = stream; }; /** \brief Set the verbosity level. * In this sense increased verbosity means that a message might * contain more information. */ void SetVerbosity(EVerbosityLevel verbosity); protected: /** Default constructor of the class ErrorLogger. */ ErrorLogger(); /** Default destructor of the class ErrorLogger. */ ~ErrorLogger() { } private: ErrorLogger(const ErrorLogger& rhs); ErrorLogger& operator=(const ErrorLogger& rhs); std::ostream *fOStream; ///< Current stream for logging messages std::ofstream fOfStream; ///< Logging stream into a file int fLoggingOption; ///< Logging option ESeverityLevel fLoggingLevel; ///< Logging level EVerbosityLevel fVerbosity; ///< Verbosity level static std::ostream *fgNullStream; }; } // namespace FdUtil // DPA (Offline) define similar macros, this could create a conflict #ifndef DPA /** \brief Standard message logging macro This macro is used by the convenience macros defined below to write a log message. It automatically sets the function name, the file name and the line number. */ #define FD_LOG_MESSAGE_(severity, message) \ FdUtil::ErrorLogger::GetInstance().Log(severity, __func__, __FILE__, __LINE__, \ message) /// Brief message logging macro - always do \e terse logging #define FD_LOG_TERSE_MESSAGE_(severity, message) \ FdUtil::ErrorLogger::GetInstance().Log(severity, __func__, __FILE__, __LINE__, \ message, FdUtil::ErrorLogger::eTerse) /** \brief Macro for logging debugging messages. This macro is only active if the \c DEBUG macro is defined. Otherwise, debug messages are suppressed at compile time. \remark This macro is not named \c DEBUG since \c DEBUG is usually used to activate conditionally compiled debugging code. */ #ifdef DEBUG # define FD_DEBUGLOG(message) FD_LOG_MESSAGE_(FdUtil::ErrorLogger::eDebug, message) #else # define FD_DEBUGLOG(message) #endif /// Macro for logging informational messages #define FD_INFO(message) FD_LOG_MESSAGE_(FdUtil::ErrorLogger::eInfo, message) /// Macro for logging warning messages #define FD_WARNING(message) FD_LOG_MESSAGE_(FdUtil::ErrorLogger::eWarning, message) /// Macro for logging error messages #define FD_ERROR(message) FD_LOG_MESSAGE_(FdUtil::ErrorLogger::eError, message) /// Macro for logging fatal messages #define FD_FATAL(message) FD_LOG_MESSAGE_(FdUtil::ErrorLogger::eFatal, message) /// Macro for logging severe messages #define FD_SEVERE(message) FD_LOG_MESSAGE_(FdUtil::ErrorLogger::eSevere, message) /// Macro for logging critical messages #define FD_CRITICAL(message) FD_LOG_MESSAGE_(FdUtil::ErrorLogger::eCritical,message) /// Macro for logging informational messages #define FD_INFO_TERSE(message) FD_LOG_TERSE_MESSAGE_(FdUtil::ErrorLogger::eInfo, \ message) /// Macro for logging warning messages #define FD_WARNING_TERSE(message) FD_LOG_TERSE_MESSAGE_(FdUtil::ErrorLogger::eWarning, \ message) /// Macro for logging error messages #define FD_ERROR_TERSE(message) FD_LOG_TERSE_MESSAGE_(FdUtil::ErrorLogger::eError, \ message) /// Macro for logging fatal messages #define FD_FATAL_TERSE(message) FD_LOG_TERSE_MESSAGE_(FdUtil::ErrorLogger::eFatal, \ message) #endif // DPA #endif // _FdUtil_ErrorLogger_hh_