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