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