libqi
1.12
|
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_