CuteLogger
Fast and simple logging solution for Qt based applications
Logger.h
Go to the documentation of this file.
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 #include <QElapsedTimer>
22 
23 // Local
24 #include "CuteLogger_global.h"
25 class AbstractAppender;
26 
27 
28 class Logger;
29 CUTELOGGERSHARED_EXPORT Logger* cuteLoggerInstance();
30 #define cuteLogger cuteLoggerInstance()
31 
32 
33 #define LOG_TRACE CuteMessageLogger(cuteLoggerInstance(), Logger::Trace, __FILE__, __LINE__, Q_FUNC_INFO).write
34 #define LOG_DEBUG CuteMessageLogger(cuteLoggerInstance(), Logger::Debug, __FILE__, __LINE__, Q_FUNC_INFO).write
35 #define LOG_INFO CuteMessageLogger(cuteLoggerInstance(), Logger::Info, __FILE__, __LINE__, Q_FUNC_INFO).write
36 #define LOG_WARNING CuteMessageLogger(cuteLoggerInstance(), Logger::Warning, __FILE__, __LINE__, Q_FUNC_INFO).write
37 #define LOG_ERROR CuteMessageLogger(cuteLoggerInstance(), Logger::Error, __FILE__, __LINE__, Q_FUNC_INFO).write
38 #define LOG_FATAL CuteMessageLogger(cuteLoggerInstance(), Logger::Fatal, __FILE__, __LINE__, Q_FUNC_INFO).write
39 
40 #define LOG_CTRACE(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Trace, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
41 #define LOG_CDEBUG(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Debug, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
42 #define LOG_CINFO(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Info, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
43 #define LOG_CWARNING(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Warning, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
44 #define LOG_CERROR(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Error, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
45 #define LOG_CFATAL(category) CuteMessageLogger(cuteLoggerInstance(), Logger::Fatal, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
46 
47 #define LOG_TRACE_TIME LoggerTimingHelper loggerTimingHelper(cuteLoggerInstance(), Logger::Trace, __FILE__, __LINE__, Q_FUNC_INFO); loggerTimingHelper.start
48 #define LOG_DEBUG_TIME LoggerTimingHelper loggerTimingHelper(cuteLoggerInstance(), Logger::Debug, __FILE__, __LINE__, Q_FUNC_INFO); loggerTimingHelper.start
49 #define LOG_INFO_TIME LoggerTimingHelper loggerTimingHelper(cuteLoggerInstance(), Logger::Info, __FILE__, __LINE__, Q_FUNC_INFO); loggerTimingHelper.start
50 
51 #define LOG_ASSERT(cond) ((!(cond)) ? cuteLoggerInstance()->writeAssert(__FILE__, __LINE__, Q_FUNC_INFO, #cond) : qt_noop())
52 #define LOG_ASSERT_X(cond, msg) ((!(cond)) ? cuteLoggerInstance()->writeAssert(__FILE__, __LINE__, Q_FUNC_INFO, msg) : qt_noop())
53 
54 #if (__cplusplus >= 201103L)
55 #include <functional>
56 
57 #define LOG_CATEGORY(category) \
58  Logger customCuteLoggerInstance{category};\
59  std::function<Logger*()> cuteLoggerInstance = [&customCuteLoggerInstance]() {\
60  return &customCuteLoggerInstance;\
61  };\
62 
63 #define LOG_GLOBAL_CATEGORY(category) \
64  Logger customCuteLoggerInstance{category, true};\
65  std::function<Logger*()> cuteLoggerInstance = [&customCuteLoggerInstance]() {\
66  return &customCuteLoggerInstance;\
67  };\
68 
69 #else
70 
71 #define LOG_CATEGORY(category) \
72  Logger* cuteLoggerInstance()\
73  {\
74  static Logger customCuteLoggerInstance(category);\
75  return &customCuteLoggerInstance;\
76  }\
77 
78 #define LOG_GLOBAL_CATEGORY(category) \
79  Logger* cuteLoggerInstance()\
80  {\
81  static Logger customCuteLoggerInstance(category);\
82  customCuteLoggerInstance.logToGlobalInstance(category, true);\
83  return &customCuteLoggerInstance;\
84  }\
85 
86 #endif
87 
88 
89 class LoggerPrivate;
90 class CUTELOGGERSHARED_EXPORT Logger
91 {
92  Q_DISABLE_COPY(Logger)
93 
94  public:
95  Logger();
96  Logger(const QString& defaultCategory, bool writeToGlobalInstance = false);
97  ~Logger();
98 
100  enum LogLevel
101  {
107  Fatal
108  };
109 
112  {
114  TimingMs
115  };
116 
117  static QString levelToString(LogLevel logLevel);
118  static LogLevel levelFromString(const QString& s);
119 
120  static Logger* globalInstance();
121 
122  void registerAppender(AbstractAppender* appender);
123  void registerCategoryAppender(const QString& category, AbstractAppender* appender);
124 
125  void removeAppender(AbstractAppender* appender);
126 
127  void logToGlobalInstance(const QString& category, bool logToGlobal = false);
128 
129  void setDefaultCategory(const QString& category);
130  QString defaultCategory() const;
131 
132  void write(const QDateTime& timeStamp, LogLevel logLevel, const char* file, int line, const char* function, const char* category,
133  const QString& message);
134  void write(LogLevel logLevel, const char* file, int line, const char* function, const char* category, const QString& message);
135 
136  void writeAssert(const char* file, int line, const char* function, const char* condition);
137 
138  private:
139  void write(const QDateTime& timeStamp, LogLevel logLevel, const char* file, int line, const char* function, const char* category,
140  const QString& message, bool fromLocalInstance);
141  Q_DECLARE_PRIVATE(Logger)
142  LoggerPrivate* d_ptr;
143 };
144 
145 
146 class CUTELOGGERSHARED_EXPORT CuteMessageLogger
147 {
148  Q_DISABLE_COPY(CuteMessageLogger)
149 
150  public:
151  CuteMessageLogger(Logger* l, Logger::LogLevel level, const char* file, int line, const char* function)
152  : m_l(l),
153  m_level(level),
154  m_file(file),
155  m_line(line),
156  m_function(function),
157  m_category(nullptr)
158  {}
159 
160  CuteMessageLogger(Logger* l, Logger::LogLevel level, const char* file, int line, const char* function, const char* category)
161  : m_l(l),
162  m_level(level),
163  m_file(file),
164  m_line(line),
165  m_function(function),
166  m_category(category)
167  {}
168 
169  ~CuteMessageLogger();
170 
171  void write(const char* msg, ...)
172 #if defined(Q_CC_GNU) && !defined(__INSURE__)
173 # if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
174  __attribute__ ((format (gnu_printf, 2, 3)))
175 # else
176  __attribute__ ((format (printf, 2, 3)))
177 # endif
178 #endif
179  ;
180 
181  void write(const QString& msg);
182 
183  QDebug write();
184 
185  private:
186  Logger* m_l;
187  Logger::LogLevel m_level;
188  const char* m_file;
189  int m_line;
190  const char* m_function;
191  const char* m_category;
192  QString m_message;
193 };
194 
195 
196 class CUTELOGGERSHARED_EXPORT LoggerTimingHelper
197 {
198  Q_DISABLE_COPY(LoggerTimingHelper)
199 
200  public:
201  inline explicit LoggerTimingHelper(Logger* l, Logger::LogLevel logLevel, const char* file, int line,
202  const char* function)
203  : m_logger(l),
204  m_logLevel(logLevel),
205  m_timingMode(Logger::TimingAuto),
206  m_file(file),
207  m_line(line),
208  m_function(function)
209  {}
210 
211  void start(const char* msg, ...)
212 #if defined(Q_CC_GNU) && !defined(__INSURE__)
213  # if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
214  __attribute__ ((format (gnu_printf, 2, 3)))
215  # else
216  __attribute__ ((format (printf, 2, 3)))
217  # endif
218 #endif
219  ;
220 
221  void start(const QString& msg = QString());
222  void start(Logger::TimingMode mode, const QString& msg);
223 
224  ~LoggerTimingHelper();
225 
226  private:
227  Logger* m_logger;
228  QElapsedTimer m_time;
229  Logger::LogLevel m_logLevel;
230  Logger::TimingMode m_timingMode;
231  const char* m_file;
232  int m_line;
233  const char* m_function;
234  QString m_block;
235 };
236 
237 
238 #endif // LOGGER_H
The AbstractAppender class provides an abstract base class for writing a log entries.
Definition: AbstractAppender.h:26
Very simple but rather powerful component which may be used for logging your application activities.
Definition: Logger.h:91
TimingMode
Sets the timing display mode for the LOG_TRACE_TIME, LOG_DEBUG_TIME and LOG_INFO_TIME macros.
Definition: Logger.h:112
@ TimingAuto
Show time in seconds, if it exceeds 10s (default)
Definition: Logger.h:113
LogLevel
Describes the possible severity levels of the log records.
Definition: Logger.h:101
@ Debug
Debug level. Useful for non-necessary records used for the debugging of the software.
Definition: Logger.h:103
@ Warning
Warning. May be used to log some non-fatal warnings detected by your application.
Definition: Logger.h:105
@ Trace
Trace level. Can be used for mostly unneeded records used for internal code tracing.
Definition: Logger.h:102
@ Info
Info level. Can be used for informational records, which may be interesting for not only developers.
Definition: Logger.h:104
@ Error
Error. May be used for a big problems making your application work wrong but not crashing.
Definition: Logger.h:106