libqi  1.12
qi/log.hpp
Go to the documentation of this file.
00001 /*
00002  *  Author(s):
00003  *  - Chris  Kilner <ckilner@aldebaran-robotics.com>
00004  *  - Cedric Gestes <gestes@aldebaran-robotics.com>
00005  *  - Herve Cuche <hcuche@aldebaran-robotics.com>
00006  *
00007  *  Copyright (C) 2010, 2011 Aldebaran Robotics
00008  */
00009 
00015 #pragma once
00016 #ifndef _LIBQI_QI_LOG_HPP_
00017 #define _LIBQI_QI_LOG_HPP_
00018 
00019 # include <map>
00020 # include <string>
00021 # include <iostream>
00022 # include <sstream>
00023 # include <cstdarg>
00024 # include <cstdio>
00025 
00026 #include <boost/function/function_fwd.hpp>
00027 
00028 #include <qi/config.hpp>
00029 #include <qi/os.hpp>
00030 
00031 #if defined(NO_QI_DEBUG) || defined(NDEBUG)
00032 # define qiLogDebug(...)        if (false) qi::log::detail::NullStream(__VA_ARGS__).self()
00033 #else
00034 # define qiLogDebug(...)        qi::log::LogStream(qi::log::debug, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__).self()
00035 #endif
00036 
00037 #ifdef NO_QI_VERBOSE
00038 # define qiLogVerbose(...)      if (false) qi::log::detail::NullStream(__VA_ARGS__).self()
00039 #else
00040 # define qiLogVerbose(...)      qi::log::LogStream(qi::log::verbose, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__).self()
00041 #endif
00042 
00043 #ifdef NO_QI_INFO
00044 # define qiLogInfo(...)         if (false) qi::log::detail::NullStream(__VA_ARGS__).self()
00045 #else
00046 # define qiLogInfo(...)         qi::log::LogStream(qi::log::info, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__).self()
00047 #endif
00048 
00049 #ifdef NO_QI_WARNING
00050 # define qiLogWarning(...)      if (false) qi::log::detail::NullStream(__VA_ARGS__).self()
00051 #else
00052 # define qiLogWarning(...)      qi::log::LogStream(qi::log::warning, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__).self()
00053 #endif
00054 
00055 #ifdef NO_QI_ERROR
00056 # define qiLogError(...)        if (false) qi::log::detail::NullStream(__VA_ARGS__).self()
00057 #else
00058 # define qiLogError(...)        qi::log::LogStream(qi::log::error, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__).self()
00059 #endif
00060 
00061 #ifdef NO_QI_FATAL
00062 # define qiLogFatal(...)        if (false) qi::log::detail::NullStream(__VA_ARGS__).self()
00063 #else
00064 # define qiLogFatal(...)        qi::log::LogStream(qi::log::fatal, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__).self()
00065 #endif
00066 
00067 
00068 // enum level {
00069 //   silent = 0,
00070 //   fatal,
00071 //   error,
00072 //   warning,
00073 //   info,
00074 //   verbose,
00075 //   debug
00076 // };
00077 
00078 
00079 namespace qi {
00080   namespace log {
00081 
00082     namespace detail {
00083 
00084       class NullStream {
00085       public:
00086         NullStream(const char *, ...)
00087         {
00088         }
00089 
00090         NullStream &self()
00091         {
00092           return *this;
00093         }
00094 
00095         template <typename T>
00096         NullStream& operator<<(const T& val)
00097         {
00098           return self();
00099         }
00100 
00101         NullStream& operator<<(std::ostream& (*f)(std::ostream&))
00102         {
00103           return self();
00104         }
00105 
00106       };
00107 
00108     };
00109 
00110     enum LogLevel {
00111         silent = 0,
00112         fatal,
00113         error,
00114         warning,
00115         info,
00116         verbose,
00117         debug
00118     };
00119 
00120     typedef boost::function7<void,
00121                              const qi::log::LogLevel,
00122                              const qi::os::timeval,
00123                              const char*,
00124                              const char*,
00125                              const char*,
00126                              const char*,
00127                              int> logFuncHandler;
00128 
00129     QI_API void init(qi::log::LogLevel verb = qi::log::info,
00130                      int ctx = 0,
00131                      bool synchronous = true);
00132 
00133     QI_API void destroy();
00134 
00135     QI_API void log(const qi::log::LogLevel verb,
00136                     const char              *category,
00137                     const char              *msg,
00138                     const char              *file = "",
00139                     const char              *fct = "",
00140                     const int               line = 0);
00141 
00142     QI_API const char* logLevelToString(const qi::log::LogLevel verb);
00143 
00144     QI_API const qi::log::LogLevel stringToLogLevel(const char* verb);
00145 
00146     QI_API void setVerbosity(const qi::log::LogLevel lv);
00147 
00148     QI_API qi::log::LogLevel verbosity();
00149 
00150 
00151     QI_API void setContext(int ctx);
00152 
00153     QI_API int context();
00154 
00155     QI_API void setSynchronousLog(bool sync);
00156 
00157     QI_API void addLogHandler(const std::string& name,
00158                               qi::log::logFuncHandler fct);
00159 
00160     QI_API void removeLogHandler(const std::string& name);
00161 
00162     QI_API void flush();
00163 
00164     class LogStream: public std::stringstream
00165     {
00166     public:
00167 
00168       LogStream(const LogStream &rhs)
00169         : _logLevel(rhs._logLevel)
00170         , _category(rhs._category)
00171         , _file(rhs._file)
00172         , _function(rhs._function)
00173         , _line(rhs._line)
00174       {
00175       }
00176 
00177       LogStream &operator=(const LogStream &rhs)
00178       {
00179         _logLevel = rhs._logLevel;
00180         _category = rhs._category;
00181         _file     = rhs._file;
00182         _function = rhs._function;
00183         _line     = rhs._line;
00184         return *this;
00185       }
00186 
00187       LogStream(const LogLevel    level,
00188                 const char        *file,
00189                 const char        *function,
00190                 const int         line,
00191                 const char        *category)
00192         : _logLevel(level)
00193         , _category(category)
00194         , _file(file)
00195         , _function(function)
00196         , _line(line)
00197       {
00198       }
00199 
00200       LogStream(const LogLevel    level,
00201                 const char        *file,
00202                 const char        *function,
00203                 const int         line,
00204                 const char        *category,
00205                 const char        *fmt, ...)
00206         : _logLevel(level)
00207         , _category(category)
00208         , _file(file)
00209         , _function(function)
00210         , _line(line)
00211       {
00212         char buffer[2048];
00213         va_list vl;
00214         va_start(vl, fmt);
00215        #ifdef _MSC_VER
00216         vsnprintf_s(buffer, 2048, 2047, fmt, vl);
00217        #else
00218         vsnprintf(buffer, 2048, fmt, vl);
00219        #endif
00220         buffer[2047] = 0;
00221         va_end(vl);
00222         *this << buffer;
00223       }
00224 
00225       ~LogStream()
00226       {
00227         qi::log::log(_logLevel, _category, this->str().c_str(), _file, _function, _line);
00228       }
00229 
00230       LogStream& self() {
00231         return *this;
00232       }
00233 
00234     private:
00235       LogLevel    _logLevel;
00236       const char *_category;
00237       const char *_file;
00238       const char *_function;
00239       int         _line;
00240     };
00241   }
00242 }
00243 
00244 #endif  // _LIBQI_QI_LOG_HPP_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines