Parent Directory
|
Revision Log
reset tty colours on exit
1 /* 2 * Copyright (C) 2009 Dialogic Corp. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * 02110-1301, USA. 18 * Alternatively see <http://www.gnu.org/licenses/>. 19 * Or see the LICENSE file included within the source tree. 20 * 21 */ 22 23 /*! 24 * \file lib/logger.h 25 * \brief Simple logger for C++ applications. 26 * \author John Tarlton 27 * \version 0.1 28 29 */ 30 31 #ifndef _LOGGER_H 32 #define _LOGGER_H 33 34 /*----------------------------- Dependencies -------------------------------*/ 35 36 #include <sstream> 37 #include <fstream> 38 #include <string> 39 #include <vector> 40 41 #include <pthread.h> 42 43 /*--------------------------------------------------------------------------*/ 44 45 /*! 46 * \class Logger 47 * Simple logging utility 48 * Responsible for producing formatted logging messages and writing them out 49 * through various backends. 50 */ 51 class Logger 52 { 53 public: 54 55 /*! 56 * Logging levels. Equivalent to the priorities defined in syslog.h 57 * These are defined below in order of decreasing severity. 58 */ 59 enum LogLevel 60 { 61 LOGLEVEL_EMERG = 0, /*!< panic condition */ 62 LOGLEVEL_ALERT = 1, /*!< a condition that needs immediate attention */ 63 LOGLEVEL_CRIT = 2, /*!< critical conditions */ 64 LOGLEVEL_ERR = 3, /*!< error messages */ 65 LOGLEVEL_WARN = 4, /*!< potentially harmful situations */ 66 LOGLEVEL_NOTICE = 5, /*!< normal but significant condition */ 67 LOGLEVEL_INFO = 6, /*!< informational messages */ 68 LOGLEVEL_DEBUG = 7 /*!< fine-grained info for debugging */ 69 }; 70 71 /*! 72 * \class Appender 73 * Appenders are used to write logging output to specific destinations such 74 * as files or the console. 75 */ 76 class Appender 77 { 78 public: 79 80 /*! 81 * ctor 82 */ 83 Appender() {} 84 85 /*! 86 * dtor 87 */ 88 virtual ~Appender() {} 89 90 /*! 91 * Output the message 92 */ 93 virtual void write( Logger::LogLevel level, const std::string& s ) = 0; 94 }; 95 96 /*! 97 * Get a reference to the single instance of the Logger object. 98 */ 99 static Logger& instance() 100 { 101 static Logger singleton; 102 return singleton; 103 } 104 105 /*! 106 * Attach and take ownership of an Appender object. 107 * This is not thread-safe, designed to be called from a single threaded 108 * environment at startup. 109 */ 110 void attachAppender( Logger::Appender* appender ); 111 112 /*! 113 * Set the logging level. This causes all write() operations for log levels 114 * that are less severe than 'level' to be discarded. 115 * This is not thread-safe, designed to be called from a single threaded 116 * environment at startup. 117 * \param level - one of the LogLevel constants. 118 */ 119 void setLevel( Logger::LogLevel level ); 120 121 /*! 122 * Write a log message. 123 * \param level - one of the LogLevel constants. 124 * \param s - the logging message. 125 */ 126 void write( Logger::LogLevel level, const std::string& s ); 127 128 private: 129 130 /* Hide ctors/dtor. 131 */ 132 Logger(); 133 Logger( const Logger& ); 134 Logger& operator = ( const Logger& ); 135 136 ~Logger(); 137 138 private: 139 140 LogLevel level_; 141 std::vector<Appender*> appenders_; 142 143 pthread_mutex_t write_mutex_; /*!< ensures writes to appenders are atomic */ 144 }; 145 146 /////////////////////////////////////////////////////////////////////////////// 147 148 /*! 149 * \class ConsoleAppender 150 * Write logging information to stderr. 151 */ 152 class ConsoleAppender : public Logger::Appender 153 { 154 public: 155 156 /*! 157 * ctor 158 * \param colour - if true the output will use colours to highlight the 159 * logging level. This is only a hint and requires support 160 * from the terminal device. 161 */ 162 ConsoleAppender( bool colour = true ); 163 164 virtual ~ConsoleAppender(); 165 166 virtual void write( Logger::LogLevel level, const std::string& msg ); 167 168 private: 169 170 /*! 171 * Text attribute values for use with 'linux' and 'xterm' escape sequences. 172 */ 173 enum ConsoleAttr 174 { 175 RESET = 0, 176 BRIGHT = 1, 177 DIM = 2, 178 UNDERLINE = 3, 179 BLINK = 4, 180 REVERSE = 7, 181 HIDDEN = 8 182 }; 183 184 /*! 185 * Base colour values for use with 'linux' and 'xterm' escape sequences. 186 * For foreground values add 30, for backgound values add 40. 187 */ 188 enum ConsoleColour 189 { 190 BLACK = 0, 191 RED = 1, 192 GREEN = 2, 193 YELLOW = 3, 194 BLUE = 4, 195 MAGENTA = 5, 196 CYAN = 6, 197 WHITE = 7 198 }; 199 200 /*! 201 * Set the display attribute and colours. 202 * \param attr - attibute. 203 * \param fg - foreground (text) colour. 204 * \param bg - background colour. 205 */ 206 void textcolour( ConsoleAttr attr, ConsoleColour fg, ConsoleColour bg ); 207 208 private: 209 210 bool colour_term_; /*!< true if tty supports colour escape sequences */ 211 }; 212 213 /////////////////////////////////////////////////////////////////////////////// 214 215 /*! 216 * \class FileAppender 217 */ 218 class FileAppender : public Logger::Appender 219 { 220 public: 221 222 /*! 223 * ctor, 224 * \param path - directory where the log file(s) are written. 225 * \param basename - the basename for each log file. The extension ".log" 226 * is appended automatically. 227 * \param max_size - maximum size for each file. 228 */ 229 FileAppender( const std::string& path, 230 const std::string& basename, 231 ssize_t max_size = 0); 232 233 virtual ~FileAppender(); 234 235 virtual void write( Logger::LogLevel level, const std::string& msg ); 236 237 private: 238 239 FileAppender( const FileAppender& ); 240 FileAppender& operator = ( const FileAppender& ); 241 242 void open(); 243 void rollover(); 244 245 private: 246 247 std::string path_; 248 std::string basename_; 249 ssize_t max_size_; 250 std::ofstream fout_; 251 }; 252 253 /////////////////////////////////////////////////////////////////////////////// 254 255 /*! 256 * \class SyslogAppender 257 */ 258 class SyslogAppender : public Logger::Appender 259 { 260 public: 261 262 /*! 263 * ctor, 264 * \param name - identifier prepended to each message by the syslog daemon. 265 */ 266 SyslogAppender( const std::string& name ); 267 268 virtual ~SyslogAppender(); 269 270 virtual void write( Logger::LogLevel level, const std::string& msg ); 271 272 private: 273 274 SyslogAppender( const SyslogAppender& ); 275 SyslogAppender& operator = ( const SyslogAppender& ); 276 277 private: 278 279 std::string name_; 280 }; 281 282 /////////////////////////////////////////////////////////////////////////////// 283 284 285 /* Log macros providing a stream compatible interface. One macro per log level. 286 * 287 * Usage: 288 * LOGNOTICE("Initialising..."); 289 * LOGDEBUG("Received " << count << " bytes."); 290 */ 291 #define LOGDEBUG(message) do { \ 292 std::stringstream _ss; \ 293 _ss << message; \ 294 Logger::instance().write(Logger::LOGLEVEL_DEBUG, _ss.str()); \ 295 } while(0) 296 297 #define LOGINFO(message) do { \ 298 std::stringstream _ss; \ 299 _ss << message; \ 300 Logger::instance().write(Logger::LOGLEVEL_INFO, _ss.str()); \ 301 } while(0) 302 303 #define LOGNOTICE(message) do { \ 304 std::stringstream _ss; \ 305 _ss << message; \ 306 Logger::instance().write(Logger::LOGLEVEL_NOTICE, _ss.str()); \ 307 } while(0) 308 309 #define LOGWARN(message) do { \ 310 std::stringstream _ss; \ 311 _ss << message; \ 312 Logger::instance().write(Logger::LOGLEVEL_WARN, _ss.str()); \ 313 } while(0) 314 315 #define LOGERROR(message) do { \ 316 std::stringstream _ss; \ 317 _ss << message; \ 318 Logger::instance().write(Logger::LOGLEVEL_ERR, _ss.str()); \ 319 } while(0) 320 321 #define LOGCRIT(message) do { \ 322 std::stringstream _ss; \ 323 _ss << message; \ 324 Logger::instance().write(Logger::LOGLEVEL_CRIT, _ss.str()); \ 325 } while(0) 326 327 #define LOGALERT(message) do { \ 328 std::stringstream _ss; \ 329 _ss << message; \ 330 Logger::instance().write(Logger::LOGLEVEL_ALERT, _ss.str()); \ 331 } while(0) 332 333 #define LOGEMERG(message) do { \ 334 std::stringstream _ss; \ 335 _ss << message; \ 336 Logger::instance().write(Logger::LOGLEVEL_EMERG, _ss.str()); \ 337 } while(0) 338 339 340 #endif //_LOGGER_H 341 342 343 /* 344 * vim:ts=4:set nu: 345 */ 346
| No admin address has been configured | ViewVC Help |
| Powered by ViewVC 1.0.8 |