diff options
Diffstat (limited to 'rbutil/rbutilqt/logger/Logger.h')
-rw-r--r-- | rbutil/rbutilqt/logger/Logger.h | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/rbutil/rbutilqt/logger/Logger.h b/rbutil/rbutilqt/logger/Logger.h new file mode 100644 index 0000000000..d056dfc25d --- /dev/null +++ b/rbutil/rbutilqt/logger/Logger.h | |||
@@ -0,0 +1,319 @@ | |||
1 | /* | ||
2 | Copyright (c) 2010 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 | * \file Logger.h | ||
18 | * \brief A file containing the description of Logger class and and additional useful macros for logging | ||
19 | */ | ||
20 | |||
21 | // Qt | ||
22 | #include <QString> | ||
23 | #include <QDebug> | ||
24 | class QDateTime; | ||
25 | |||
26 | // Local | ||
27 | #include "CuteLogger_global.h" | ||
28 | class AbstractAppender; | ||
29 | |||
30 | |||
31 | //! Writes the trace log record | ||
32 | /** | ||
33 | * This macro is the convinient way to call Logger::write(). It uses the common preprocessor macros \c __FILE__, | ||
34 | * \c __LINE__ and the standart Qt \c Q_FUNC_INFO macros to automatically determine the needed parameters to call | ||
35 | * Logger::write(). | ||
36 | * | ||
37 | * \note This and other (LOG_INFO() etc...) macros uses the variadic macro arguments to give convinient usage form for | ||
38 | * the different versions of Logger::write() (using the QString or const char* argument or returning the QDebug class | ||
39 | * instance). Not all compilers will support this. Please, consider reviewing your compiler documentation to ensure | ||
40 | * it support __VA_ARGS__ macro. | ||
41 | * | ||
42 | * It is checked to work with GCC 4.4 or later. | ||
43 | * | ||
44 | * \sa Logger::LogLevel | ||
45 | * \sa Logger::write() | ||
46 | */ | ||
47 | #define LOG_TRACE(...) Logger::write(Logger::Trace, __FILE__, __LINE__, Q_FUNC_INFO, ##__VA_ARGS__) | ||
48 | |||
49 | //! Writes the debug log record | ||
50 | /** | ||
51 | * This macro records the info log record using the Logger::write() function. It works identically to the LOG_TRACE() | ||
52 | * macro. | ||
53 | * | ||
54 | * \sa LOG_TRACE() | ||
55 | * \sa Logger::LogLevel | ||
56 | * \sa Logger::write() | ||
57 | */ | ||
58 | #define LOG_DEBUG(...) Logger::write(Logger::Debug, __FILE__, __LINE__, Q_FUNC_INFO, ##__VA_ARGS__) | ||
59 | |||
60 | //! Write the info log record | ||
61 | /** | ||
62 | * This macro records the info log record using the Logger::write() function. It works identically to the LOG_TRACE() | ||
63 | * macro. | ||
64 | * | ||
65 | * \sa LOG_TRACE() | ||
66 | * \sa Logger::LogLevel | ||
67 | * \sa Logger::write() | ||
68 | */ | ||
69 | #define LOG_INFO(...) Logger::write(Logger::Info, __FILE__, __LINE__, Q_FUNC_INFO, ##__VA_ARGS__) | ||
70 | |||
71 | //! Write the warning log record | ||
72 | /** | ||
73 | * This macro records the warning log record using the Logger::write() function. It works identically to the LOG_TRACE() | ||
74 | * macro. | ||
75 | * | ||
76 | * \sa LOG_TRACE() | ||
77 | * \sa Logger::LogLevel | ||
78 | * \sa Logger::write() | ||
79 | */ | ||
80 | #define LOG_WARNING(...) Logger::write(Logger::Warning, __FILE__, __LINE__, Q_FUNC_INFO, ##__VA_ARGS__) | ||
81 | |||
82 | //! Write the error log record | ||
83 | /** | ||
84 | * This macro records the error log record using the Logger::write() function. It works identically to the LOG_TRACE() | ||
85 | * macro. | ||
86 | * | ||
87 | * \sa LOG_TRACE() | ||
88 | * \sa Logger::LogLevel | ||
89 | * \sa Logger::write() | ||
90 | */ | ||
91 | #define LOG_ERROR(...) Logger::write(Logger::Error, __FILE__, __LINE__, Q_FUNC_INFO, ##__VA_ARGS__) | ||
92 | |||
93 | //! Write the fatal log record | ||
94 | /** | ||
95 | * This macro records the fatal log record using the Logger::write() function. It works identically to the LOG_TRACE() | ||
96 | * macro. | ||
97 | * | ||
98 | * \note Recording of the log record using the Logger::Fatal log level will lead to calling the STL abort() | ||
99 | * function, which will interrupt the running of your software and begin the writing of the core dump. | ||
100 | * | ||
101 | * \sa LOG_TRACE() | ||
102 | * \sa Logger::LogLevel | ||
103 | * \sa Logger::write() | ||
104 | */ | ||
105 | #define LOG_FATAL(...) Logger::write(Logger::Fatal, __FILE__, __LINE__, Q_FUNC_INFO, ##__VA_ARGS__) | ||
106 | |||
107 | //! Check the assertion | ||
108 | /** | ||
109 | * This macro is a convinient and recommended to use way to call Logger::writeAssert() function. It uses the | ||
110 | * preprocessor macros (as the LOG_DEBUG() does) to fill the necessary arguments of the Logger::writeAssert() call. It | ||
111 | * also uses undocumented but rather mature and stable \c qt_noop() function (which does nothing) when the assertion | ||
112 | * is true. | ||
113 | * | ||
114 | * Example: | ||
115 | * \code | ||
116 | * bool b = checkSomething(); | ||
117 | * ... | ||
118 | * LOG_ASSERT(b == true); | ||
119 | * \endcode | ||
120 | * | ||
121 | * \sa Logger::writeAssert() | ||
122 | */ | ||
123 | #define LOG_ASSERT(cond) ((!(cond)) ? Logger::writeAssert(__FILE__, __LINE__, Q_FUNC_INFO, #cond) : qt_noop()) | ||
124 | |||
125 | |||
126 | /** | ||
127 | * \mainpage | ||
128 | * | ||
129 | * Logger is a simple way to write the history of your application lifecycle to any target logging device (which is | ||
130 | * called Appender and may write to any target you will implement with it: console, text file, XML or something - you | ||
131 | * choose) and to map logging message to a class, function, source file and line of code which it is called from. | ||
132 | * | ||
133 | * Some simple appenders (which may be considered an examples) are provided with the logger itself: see ConsoleAppender | ||
134 | * and FileAppender documentation. | ||
135 | * | ||
136 | * It supports using it in a multithreaded applications, so ALL of its functions are thread safe. | ||
137 | * | ||
138 | * Simple usage example: | ||
139 | * \code | ||
140 | * #include <QCoreApplication> | ||
141 | * | ||
142 | * #include <Logger.h> | ||
143 | * #include <ConsoleAppender.h> | ||
144 | * | ||
145 | * int main(int argc, char* argv[]) | ||
146 | * { | ||
147 | * QCoreApplication app(argc, argv); | ||
148 | * ... | ||
149 | * ConsoleAppender* consoleAppender = new ConsoleAppender(); | ||
150 | * consoleAppender->setFormat("[%-7l] <%C> %m\n"); | ||
151 | * Logger::registerAppender(consoleAppender); | ||
152 | * ... | ||
153 | * LOG_INFO("Starting the application"); | ||
154 | * int result = app.exec(); | ||
155 | * ... | ||
156 | * if (result) | ||
157 | * LOG_WARNING() << "Something went wrong." << "Result code is" << result; | ||
158 | * | ||
159 | * return result; | ||
160 | * } | ||
161 | * \endcode | ||
162 | * | ||
163 | * Logger internally uses the lazy-initialized singleton object and needs no definite initialization, but you may | ||
164 | * consider registering a log appender before calling any log recording functions or macros. | ||
165 | * | ||
166 | * The library design of Logger allows you to simply mass-replace all occurrences of qDebug and similiar calls with | ||
167 | * similiar Logger macros (e.g. LOG_DEBUG) | ||
168 | * | ||
169 | * \note Logger uses a singleton class which must live through all the application life cycle and cleans it on the | ||
170 | * destruction of the QCoreApplication (or QApplication) instance. It needs a QCoreApplication instance to be | ||
171 | * created before any of the Logger's functions are called. | ||
172 | * | ||
173 | * \sa AbstractAppender | ||
174 | * \sa LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_FATAL | ||
175 | * \sa LOG_ASSERT | ||
176 | */ | ||
177 | |||
178 | //! Very simple but rather powerful component which may be used for logging your application activities. | ||
179 | class CUTELOGGERSHARED_EXPORT Logger | ||
180 | { | ||
181 | public: | ||
182 | //! Describes the possible severity levels of the log records | ||
183 | enum LogLevel | ||
184 | { | ||
185 | Trace, //!< Trace level. Can be used for mostly unneeded records used for internal code tracing. | ||
186 | Debug, //!< Debug level. Useful for non-necessary records used for the debugging of the software. | ||
187 | Info, //!< Info level. Can be used for informational records, which may be interesting for not only developers. | ||
188 | Warning, //!< Warning. May be used to log some non-fatal warnings detected by your application. | ||
189 | Error, //!< Error. May be used for a big problems making your application work wrong but not crashing. | ||
190 | Fatal //!< Fatal. Used for unrecoverable errors, crashes the application right after the log record is written. | ||
191 | }; | ||
192 | |||
193 | //! Converts the LogLevel enum value to its string representation | ||
194 | /** | ||
195 | * \param logLevel Log level to convert | ||
196 | * | ||
197 | * \sa LogLevel | ||
198 | * \sa levelFromString() | ||
199 | */ | ||
200 | static QString levelToString(LogLevel logLevel); | ||
201 | |||
202 | //! Converts the LogLevel string representation to enum value | ||
203 | /** | ||
204 | * Comparation of the strings is case independent. If the log level string provided cannot be understood | ||
205 | * Logger::Debug is returned. | ||
206 | * | ||
207 | * \param s String to be decoded | ||
208 | * | ||
209 | * \sa LogLevel | ||
210 | * \sa levelToString() | ||
211 | */ | ||
212 | static LogLevel levelFromString(const QString& s); | ||
213 | |||
214 | //! Registers the appender to write the log records to | ||
215 | /** | ||
216 | * On the log writing call (using one of the macros or the write() function) Logger traverses through the list of | ||
217 | * the appenders and writes a log records to the each of them. Please, look through the AbstractAppender | ||
218 | * documentation to understand the concept of appenders. | ||
219 | * | ||
220 | * If no appenders was added to Logger, it falls back to logging into the \c std::cerr STL stream. | ||
221 | * | ||
222 | * \param appender Appender to register in the Logger | ||
223 | * | ||
224 | * \note Logger takes ownership on the appender and it will delete it on the application exit. According to this, | ||
225 | * appenders must be created on heap to prevent double destruction of the appender. | ||
226 | * | ||
227 | * \sa AbstractAppender | ||
228 | */ | ||
229 | static void registerAppender(AbstractAppender* appender); | ||
230 | |||
231 | //! Writes the log record | ||
232 | /** | ||
233 | * Writes the log records with the supplied arguments to all the registered appenders. | ||
234 | * | ||
235 | * \note It is not recommended to call this function directly. Instead of this you can just call one of the macros | ||
236 | * (LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_FATAL) that will supply all the needed | ||
237 | * information to this function. | ||
238 | * | ||
239 | * \param timeStamp - the time stamp of the record | ||
240 | * \param logLevel - the log level of the record | ||
241 | * \param file - the name of the source file that requested the log record | ||
242 | * \param line - the line of the code of source file that requested the log record | ||
243 | * \param function - name of the function that requested the log record | ||
244 | * \param message - log message | ||
245 | * | ||
246 | * \note Recording of the log record using the Logger::Fatal log level will lead to calling the STL abort() | ||
247 | * function, which will interrupt the running of your software and begin the writing of the core dump. | ||
248 | * | ||
249 | * \sa LogLevel | ||
250 | * \sa LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_FATAL | ||
251 | * \sa AbstractAppender | ||
252 | */ | ||
253 | static void write(const QDateTime& timeStamp, LogLevel logLevel, const char* file, int line, const char* function, | ||
254 | const QString& message); | ||
255 | |||
256 | /** | ||
257 | * This is the overloaded function provided for the convinience. It behaves identically to the above function. | ||
258 | * | ||
259 | * This function uses the current timestamp obtained with \c QDateTime::currentDateTime(). | ||
260 | * | ||
261 | * \sa write() | ||
262 | */ | ||
263 | static void write(LogLevel logLevel, const char* file, int line, const char* function, const QString& message); | ||
264 | |||
265 | /** | ||
266 | * This is the overloaded function provided for the convinience. It behaves identically to the above function. | ||
267 | * | ||
268 | * This function uses the current timestamp obtained with \c QDateTime::currentDateTime(). Also it supports writing | ||
269 | * <tt>const char*</tt> instead of \c QString and converts it internally using the \c QString::fromAscii(). If you | ||
270 | * want this function to support the non-ascii strings, you will need to setup the codec using the | ||
271 | * \c QTextCodec::setCodecForCStrings() | ||
272 | * | ||
273 | * \sa write() | ||
274 | */ | ||
275 | static void write(LogLevel logLevel, const char* file, int line, const char* function, const char* message, ...); | ||
276 | |||
277 | /** | ||
278 | * This is the overloaded function provided for the convinience. It behaves identically to the above function. | ||
279 | * | ||
280 | * This function doesn't accept any log message as argument. It returns the \c QDebug object that can be written | ||
281 | * using the stream functions. For example, you may like to write: | ||
282 | * \code | ||
283 | * LOG_DEBUG() << "This is the size" << size << "of the element" << elementName; | ||
284 | * \endcode | ||
285 | * instead of writing | ||
286 | * \code | ||
287 | * LOG_DEBUG(QString(QLatin1String("This is the size %1x%2 of the element %3")) | ||
288 | * .arg(size.x()).arg(size.y()).arg(elementName)); | ||
289 | * \endcode | ||
290 | * | ||
291 | * Please consider reading the Qt Reference Documentation for the description of the QDebug class usage syntax. | ||
292 | * | ||
293 | * \note This overload is definitely more pleasant to use than the first write() overload, but it behaves definitely | ||
294 | * slower than all the above overloads. | ||
295 | * | ||
296 | * \sa write() | ||
297 | */ | ||
298 | static QDebug write(LogLevel logLevel, const char* file, int line, const char* function); | ||
299 | |||
300 | //! Writes the assertion | ||
301 | /** | ||
302 | * This function writes the assertion record using the write() function. | ||
303 | * | ||
304 | * The assertion record is always written using the Logger::Fatal log level which leads to the abortation of the | ||
305 | * program and generation of the core dump (if supported). | ||
306 | * | ||
307 | * The message written to the appenders will be identical to the \c condition argument prefixed with the | ||
308 | * <tt>ASSERT:</tt> notification. | ||
309 | * | ||
310 | * \note It is not recommended to call this function directly. Instead of this you can just call the LOG_ASSERT | ||
311 | * macro that will supply all the needed information to this function. | ||
312 | * | ||
313 | * \sa LOG_ASSERT | ||
314 | * \sa write() | ||
315 | */ | ||
316 | static void writeAssert(const char* file, int line, const char* function, const char* condition); | ||
317 | }; | ||
318 | |||
319 | #endif // LOGGER_H | ||