1 /* 2 Copyright (c) 2012 Boris Moiseev (cyberbobs at gmail dot com) 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License version 2.1 6 as published by the Free Software Foundation and appearing in the file 7 LICENSE.LGPL included in the packaging of this file. 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 Lesser General Public License for more details. 13 */ 14 #ifndef LOGGER_H 15 #define LOGGER_H 16 17 // Qt 18 #include <QString> 19 #include <QDebug> 20 #include <QDateTime> 21 22 // Local 23 #include "CuteLogger_global.h" 24 class AbstractAppender; 25 26 27 class Logger; 28 CUTELOGGERSHARED_EXPORT Logger* cuteLoggerInstance(); 29 #define cuteLogger cuteLoggerInstance() 30 31 32 #define LOG_TRACE CuteMessageLogger(cuteLoggerInstance(), Logger::Trace, __FILE__, __LINE__, Q_FUNC_INFO).write 33 #define LOG_DEBUG CuteMessageLogger(cuteLoggerInstance(), Logger::Debug, __FILE__, __LINE__, Q_FUNC_INFO).write 34 #define LOG_INFO CuteMessageLogger(cuteLoggerInstance(), Logger::Info, __FILE__, __LINE__, Q_FUNC_INFO).write 35 #define LOG_WARNING CuteMessageLogger(cuteLoggerInstance(), Logger::Warning, __FILE__, __LINE__, Q_FUNC_INFO).write 36 #define LOG_ERROR CuteMessageLogger(cuteLoggerInstance(), Logger::Error, __FILE__, __LINE__, Q_FUNC_INFO).write 37 #define LOG_FATAL CuteMessageLogger(cuteLoggerInstance(), Logger::Fatal, __FILE__, __LINE__, Q_FUNC_INFO).write 38 39 #define LOG_CTRACE(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Trace, __FILE__, __LINE__, Q_FUNC_INFO, category).write() 40 #define LOG_CDEBUG(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Debug, __FILE__, __LINE__, Q_FUNC_INFO, category).write() 41 #define LOG_CINFO(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Info, __FILE__, __LINE__, Q_FUNC_INFO, category).write() 42 #define LOG_CWARNING(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Warning, __FILE__, __LINE__, Q_FUNC_INFO, category).write() 43 #define LOG_CERROR(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Error, __FILE__, __LINE__, Q_FUNC_INFO, category).write() 44 #define LOG_CFATAL(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Fatal, __FILE__, __LINE__, Q_FUNC_INFO, category).write() 45 46 #define LOG_TRACE_TIME LoggerTimingHelper loggerTimingHelper(cuteLoggerInstance(), Logger::Trace, __FILE__, __LINE__, Q_FUNC_INFO); loggerTimingHelper.start 47 #define LOG_DEBUG_TIME LoggerTimingHelper loggerTimingHelper(cuteLoggerInstance(), Logger::Debug, __FILE__, __LINE__, Q_FUNC_INFO); loggerTimingHelper.start 48 #define LOG_INFO_TIME LoggerTimingHelper loggerTimingHelper(cuteLoggerInstance(), Logger::Info, __FILE__, __LINE__, Q_FUNC_INFO); loggerTimingHelper.start 49 50 #define LOG_ASSERT(cond) ((!(cond)) ? cuteLoggerInstance()->writeAssert(__FILE__, __LINE__, Q_FUNC_INFO, #cond) : qt_noop()) 51 #define LOG_ASSERT_X(cond, msg) ((!(cond)) ? cuteLoggerInstance()->writeAssert(__FILE__, __LINE__, Q_FUNC_INFO, msg) : qt_noop()) 52 53 #define LOG_CATEGORY(category) \ 54 private:\ 55 Logger* cuteLoggerInstance()\ 56 {\ 57 static Logger customCuteLoggerInstance(category);\ 58 return &customCuteLoggerInstance;\ 59 }\ 60 61 #define LOG_GLOBAL_CATEGORY(category) \ 62 private:\ 63 Logger* cuteLoggerInstance()\ 64 {\ 65 static Logger customCuteLoggerInstance(category);\ 66 customCuteLoggerInstance.logToGlobalInstance(category, true);\ 67 return &customCuteLoggerInstance;\ 68 }\ 69 70 71 class LoggerPrivate; 72 class CUTELOGGERSHARED_EXPORT Logger 73 { 74 Q_DISABLE_COPY(Logger) 75 76 public: 77 Logger(); 78 Logger(const QString& defaultCategory); 79 ~Logger(); 80 81 //! Describes the possible severity levels of the log records 82 enum LogLevel 83 { 84 Trace, //!< Trace level. Can be used for mostly unneeded records used for internal code tracing. 85 Debug, //!< Debug level. Useful for non-necessary records used for the debugging of the software. 86 Info, //!< Info level. Can be used for informational records, which may be interesting for not only developers. 87 Warning, //!< Warning. May be used to log some non-fatal warnings detected by your application. 88 Error, //!< Error. May be used for a big problems making your application work wrong but not crashing. 89 Fatal //!< Fatal. Used for unrecoverable errors, crashes the application right after the log record is written. 90 }; 91 92 //! Sets the timing display mode for the LOG_TRACE_TIME, LOG_DEBUG_TIME and LOG_INFO_TIME macros 93 enum TimingMode 94 { 95 TimingAuto, //!< Show time in seconds, if it exceeds 10s (default) 96 TimingMs //!< Always use milliseconds to display 97 }; 98 99 static QString levelToString(LogLevel logLevel); 100 static LogLevel levelFromString(const QString& s); 101 102 static Logger* globalInstance(); 103 104 void registerAppender(AbstractAppender* appender); 105 void registerCategoryAppender(const QString& category, AbstractAppender* appender); 106 107 void removeAppender(AbstractAppender* appender); 108 109 void logToGlobalInstance(const QString& category, bool logToGlobal = false); 110 111 void setDefaultCategory(const QString& category); 112 QString defaultCategory() const; 113 114 void write(const QDateTime& timeStamp, LogLevel logLevel, const char* file, int line, const char* function, const char* category, 115 const QString& message); 116 void write(LogLevel logLevel, const char* file, int line, const char* function, const char* category, const QString& message); 117 QDebug write(LogLevel logLevel, const char* file, int line, const char* function, const char* category); 118 119 void writeAssert(const char* file, int line, const char* function, const char* condition); 120 121 private: 122 void write(const QDateTime& timeStamp, LogLevel logLevel, const char* file, int line, const char* function, const char* category, 123 const QString& message, bool fromLocalInstance); 124 Q_DECLARE_PRIVATE(Logger) 125 LoggerPrivate* d_ptr; 126 }; 127 128 129 class CUTELOGGERSHARED_EXPORT CuteMessageLogger 130 { 131 Q_DISABLE_COPY(CuteMessageLogger) 132 133 public: 134 Q_DECL_CONSTEXPR CuteMessageLogger(Logger* l, Logger::LogLevel level, const char* file, int line, const char* function) 135 : m_l(l), 136 m_level(level), 137 m_file(file), 138 m_line(line), 139 m_function(function), 140 m_category(0) 141 {} 142 143 Q_DECL_CONSTEXPR CuteMessageLogger(Logger* l, Logger::LogLevel level, const char* file, int line, const char* function, const char* category) 144 : m_l(l), 145 m_level(level), 146 m_file(file), 147 m_line(line), 148 m_function(function), 149 m_category(category) 150 {} 151 152 void write(const char* msg, ...) const 153 #if defined(Q_CC_GNU) && !defined(__INSURE__) 154 # if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG) 155 __attribute__ ((format (gnu_printf, 2, 3))) 156 # else 157 __attribute__ ((format (printf, 2, 3))) 158 # endif 159 #endif 160 ; 161 162 void write(const QString& msg) const; 163 164 QDebug write() const; 165 166 private: 167 Logger* m_l; 168 Logger::LogLevel m_level; 169 const char* m_file; 170 int m_line; 171 const char* m_function; 172 const char* m_category; 173 }; 174 175 176 class CUTELOGGERSHARED_EXPORT LoggerTimingHelper 177 { 178 Q_DISABLE_COPY(LoggerTimingHelper) 179 180 public: 181 inline explicit LoggerTimingHelper(Logger* l, Logger::LogLevel logLevel, const char* file, int line, 182 const char* function) 183 : m_logger(l), 184 m_logLevel(logLevel), 185 m_timingMode(Logger::TimingAuto), 186 m_file(file), 187 m_line(line), 188 m_function(function) 189 {} 190 191 void start(const char* msg, ...) 192 #if defined(Q_CC_GNU) && !defined(__INSURE__) 193 # if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG) 194 __attribute__ ((format (gnu_printf, 2, 3))) 195 # else 196 __attribute__ ((format (printf, 2, 3))) 197 # endif 198 #endif 199 ; 200 201 void start(const QString& msg = QString()); 202 void start(Logger::TimingMode mode, const QString& msg); 203 204 ~LoggerTimingHelper(); 205 206 private: 207 Logger* m_logger; 208 QTime m_time; 209 Logger::LogLevel m_logLevel; 210 Logger::TimingMode m_timingMode; 211 const char* m_file; 212 int m_line; 213 const char* m_function; 214 QString m_block; 215 }; 216 217 218 #endif // LOGGER_H 219