1 /* 2 * Copyright (C) 2003, Tommi Maekitalo 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * As a special exception, you may use this file as part of a free 10 * software library without restriction. Specifically, if other files 11 * instantiate templates or use macros or inline functions from this 12 * file, or you compile this file and link it with other files to 13 * produce an executable, this file does not by itself cause the 14 * resulting executable to be covered by the GNU General Public 15 * License. This exception does not however invalidate any other 16 * reasons why the executable file might be covered by the GNU Library 17 * General Public License. 18 * 19 * This library is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 * Lesser General Public License for more details. 23 * 24 * You should have received a copy of the GNU Lesser General Public 25 * License along with this library; if not, write to the Free Software 26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 27 */ 28 29 #ifndef CXXTOOLS_LOG_CXXTOOLS_H 30 #define CXXTOOLS_LOG_CXXTOOLS_H 31 32 #include <string> 33 #include <iostream> 34 35 #define _cxxtools_log_enabled(level) \ 36 (getLogger() != 0 && getLogger()->isEnabled(::cxxtools::Logger::LOG_LEVEL_ ## level)) 37 38 #define _cxxtools_log(level, expr) \ 39 do { \ 40 ::cxxtools::Logger* _cxxtools_logger = getLogger(); \ 41 if (_cxxtools_logger != 0 && _cxxtools_logger->isEnabled(::cxxtools::Logger::LOG_LEVEL_ ## level)) \ 42 { \ 43 ::cxxtools::LogMessage _cxxtools_logMessage(_cxxtools_logger, #level); \ 44 _cxxtools_logMessage.out() << expr; \ 45 _cxxtools_logMessage.finish(); \ 46 } \ 47 } while (false) 48 49 #define _cxxtools_log_if(level, cond, expr) \ 50 do { \ 51 ::cxxtools::Logger* _cxxtools_logger = getLogger(); \ 52 if (_cxxtools_logger != 0 && _cxxtools_logger->isEnabled(::cxxtools::Logger::LOG_LEVEL_ ## level) && (cond)) \ 53 { \ 54 ::cxxtools::LogMessage _cxxtools_logMessage(_cxxtools_logger, #level); \ 55 _cxxtools_logMessage.out() << expr; \ 56 _cxxtools_logMessage.finish(); \ 57 } \ 58 } while (false) 59 60 #define log_fatal_enabled() _cxxtools_log_enabled(FATAL) 61 #define log_error_enabled() _cxxtools_log_enabled(ERROR) 62 #define log_warn_enabled() _cxxtools_log_enabled(WARN) 63 #define log_info_enabled() _cxxtools_log_enabled(INFO) 64 #define log_debug_enabled() _cxxtools_log_enabled(DEBUG) 65 #define log_trace_enabled() _cxxtools_log_enabled(TRACE) 66 67 #define log_fatal(expr) _cxxtools_log(FATAL, expr) 68 #define log_error(expr) _cxxtools_log(ERROR, expr) 69 #define log_warn(expr) _cxxtools_log(WARN, expr) 70 #define log_info(expr) _cxxtools_log(INFO, expr) 71 #define log_debug(expr) _cxxtools_log(DEBUG, expr) 72 73 #define log_fatal_if(cond, expr) _cxxtools_log_if(FATAL, cond, expr) 74 #define log_error_if(cond, expr) _cxxtools_log_if(ERROR, cond, expr) 75 #define log_warn_if(cond, expr) _cxxtools_log_if(WARN, cond, expr) 76 #define log_info_if(cond, expr) _cxxtools_log_if(INFO, cond, expr) 77 #define log_debug_if(cond, expr) _cxxtools_log_if(DEBUG, cond, expr) 78 79 #define log_trace(expr) \ 80 ::cxxtools::LogTracer _cxxtools_tracer; \ 81 do { \ 82 ::cxxtools::Logger* _cxxtools_logger = getLogger(); \ 83 if (_cxxtools_logger != 0 && _cxxtools_logger->isEnabled(::cxxtools::Logger::LOG_LEVEL_TRACE)) \ 84 { \ 85 _cxxtools_tracer.setLogger(_cxxtools_logger); \ 86 _cxxtools_tracer.out() << expr; \ 87 _cxxtools_tracer.enter(); \ 88 } \ 89 } while (false) 90 91 #define log_define(category) \ 92 static ::cxxtools::Logger* getLogger() \ 93 { \ 94 static cxxtools::Logger* logger = 0; \ 95 if (!::cxxtools::LoggerManager::isEnabled()) \ 96 return 0; \ 97 if (logger == 0) \ 98 logger = ::cxxtools::LoggerManager::getInstance().getLogger(category); \ 99 return logger; \ 100 } 101 102 #define log_init_cxxtools ::cxxtools::LoggerManager::logInit 103 #define log_init log_init_cxxtools 104 105 namespace cxxtools 106 { 107 class SerializationInfo; 108 109 ////////////////////////////////////////////////////////////////////// 110 // 111 class Logger 112 { 113 public: 114 typedef enum { 115 LOG_LEVEL_FATAL = 0, 116 LOG_LEVEL_ERROR = 100, 117 LOG_LEVEL_WARN = 200, 118 LOG_LEVEL_INFO = 300, 119 LOG_LEVEL_DEBUG = 400, 120 LOG_LEVEL_TRACE = 500 121 } log_level_type; 122 123 private: 124 std::string category; 125 log_level_type level; 126 127 Logger(const Logger&); 128 Logger& operator=(const Logger&); 129 130 public: Logger(const std::string & c,log_level_type l)131 Logger(const std::string& c, log_level_type l) 132 : category(c), level(l) 133 { } 134 isEnabled(log_level_type l)135 bool isEnabled(log_level_type l) const 136 { return level >= l; } getCategory()137 const std::string& getCategory() const 138 { return category; } getLogLevel()139 log_level_type getLogLevel() const 140 { return level; } 141 }; 142 143 ////////////////////////////////////////////////////////////////////// 144 // 145 class LoggerManagerConfiguration 146 { 147 public: 148 class Impl; 149 150 private: 151 friend class Impl; 152 Impl* _impl; 153 154 public: 155 LoggerManagerConfiguration(); 156 LoggerManagerConfiguration(const LoggerManagerConfiguration&); 157 LoggerManagerConfiguration& operator=(const LoggerManagerConfiguration&); 158 159 ~LoggerManagerConfiguration(); 160 impl()161 Impl* impl() { return _impl; } impl()162 const Impl* impl() const { return _impl; } 163 164 Logger::log_level_type rootLevel() const; 165 Logger::log_level_type logLevel(const std::string& category) const; 166 }; 167 168 void operator>>= (const SerializationInfo& si, LoggerManagerConfiguration& loggerManagerConfiguration); 169 170 ////////////////////////////////////////////////////////////////////// 171 // 172 class LoggerManager 173 { 174 public: 175 class Impl; 176 177 friend class Impl; 178 179 Impl* _impl; 180 LoggerManager(); 181 static bool _enabled; 182 183 LoggerManager(const LoggerManager&); 184 LoggerManager& operator=(const LoggerManager&); 185 186 public: 187 ~LoggerManager(); 188 impl()189 Impl* impl() { return _impl; } impl()190 const Impl* impl() const { return _impl; } 191 192 static LoggerManager& getInstance(); 193 static void logInit(); 194 static void logInit(const std::string& fname); 195 static void logInit(const cxxtools::SerializationInfo& si); 196 197 void configure(const LoggerManagerConfiguration& config); 198 Logger* getLogger(const std::string& category); isEnabled()199 static bool isEnabled() 200 { return _enabled; } 201 202 Logger::log_level_type rootLevel() const; 203 Logger::log_level_type logLevel(const std::string& category) const; 204 }; 205 206 ////////////////////////////////////////////////////////////////////// 207 // 208 class LogMessage 209 { 210 public: 211 class Impl; 212 213 private: 214 Impl* _impl; 215 216 LogMessage(const LogMessage&); 217 LogMessage& operator=(const LogMessage&); 218 219 public: 220 LogMessage(Logger* logger, const char* level); 221 LogMessage(Logger* logger, Logger::log_level_type level); 222 ~LogMessage(); 223 impl()224 Impl* impl() { return _impl; } impl()225 const Impl* impl() const { return _impl; } 226 227 std::ostream& out(); 228 std::string str() const; 229 230 void finish(); 231 }; 232 233 ////////////////////////////////////////////////////////////////////// 234 // 235 class LogTracer 236 { 237 public: 238 class Impl; 239 240 private: 241 Impl* _impl; 242 243 LogTracer(const LogTracer&); 244 LogTracer& operator=(const LogTracer&); 245 246 public: 247 LogTracer(); 248 ~LogTracer(); 249 impl()250 Impl* impl() { return _impl; } impl()251 const Impl* impl() const { return _impl; } 252 253 void setLogger(Logger* l); 254 std::ostream& out(); 255 void enter(); 256 void exit(); 257 }; 258 259 } 260 261 #endif // LOG_CXXTOOLS_H 262