1#pragma once
2
3/****************************************************************************************
4 ** QLogger is a library to register and print logs into a file.
5 ** Copyright (C) 2021 Francesc Martinez
6 **
7 ** LinkedIn: www.linkedin.com/in/cescmm/
8 ** Web: www.francescmm.com
9 **
10 ** This library is free software; you can redistribute it and/or
11 ** modify it under the terms of the GNU Lesser General Public
12 ** License as published by the Free Software Foundation; either
13 ** version 2 of the License, or (at your option) any later version.
14 **
15 ** This library is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ** Lesser General Public License for more details.
19 **
20 ** You should have received a copy of the GNU Lesser General Public
21 ** License along with this library; if not, write to the Free Software
22 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 ***************************************************************************************/
24
25#include <QLoggerLevel.h>
26
27#include <QMutex>
28#include <QMap>
29#include <QVariant>
30
31namespace QLogger
32{
33
34class QLoggerWriter;
35
36/**
37 * @brief The QLoggerManager class manages the different destination files that we would like to have.
38 */
39class QLoggerManager
40{
41public:
42 /**
43 * @brief Gets an instance to the QLoggerManager.
44 * @return A pointer to the instance.
45 */
46 static QLoggerManager *getInstance();
47
48 /**
49 * @brief This method creates a QLoogerWriter that stores the name of the file and the log
50 * level assigned to it. Here is added to the map the different modules assigned to each
51 * log file. The method returns <em>false</em> if a module is configured to be stored in
52 * more than one file.
53 *
54 * @param fileDest The file name and path to print logs.
55 * @param module The module that will be stored in the file.
56 * @param level The maximum level allowed.
57 * @param fileFolderDestination The complete folder destination.
58 * @param mode The logging mode.
59 * @param fileSuffixIfFull The filename suffix if the file is full.
60 * @param messageOptions Specifies what elements are displayed in one line of log message.
61 * @return Returns true if any error have been done.
62 */
63 bool addDestination(const QString &fileDest, const QString &module, LogLevel level = LogLevel::Warning,
64 const QString &fileFolderDestination = QString(), LogMode mode = LogMode::OnlyFile,
65 LogFileDisplay fileSuffixIfFull = LogFileDisplay::DateTime,
66 LogMessageDisplays messageOptions = LogMessageDisplay::Default, bool notify = true);
67 /**
68 * @brief This method creates a QLoogerWriter that stores the name of the file and the log
69 * level assigned to it. Here is added to the map the different modules assigned to each
70 * log file. The method returns <em>false</em> if a module is configured to be stored in
71 * more than one file.
72 *
73 * @param fileDest The file name and path to print logs.
74 * @param modules The modules that will be stored in the file.
75 * @param level The maximum level allowed.
76 * @param fileFolderDestination The complete folder destination.
77 * @param mode The logging mode.
78 * @param fileSuffixIfFull The filename suffix if the file is full.
79 * @param messageOptions Specifies what elements are displayed in one line of log message.
80 * @return Returns true if any error have been done.
81 */
82 bool addDestination(const QString &fileDest, const QStringList &modules, LogLevel level = LogLevel::Warning,
83 const QString &fileFolderDestination = QString(), LogMode mode = LogMode::OnlyFile,
84 LogFileDisplay fileSuffixIfFull = LogFileDisplay::DateTime,
85 LogMessageDisplays messageOptions = LogMessageDisplay::Default, bool notify = true);
86 /**
87 * @brief Clears old log files from the current storage folder.
88 *
89 * @param fileFolderDestination The destination folder.
90 * @param days Minimum age of log files to delete. Logs older than
91 * this value will be removed. If days is -1, deletes any log file.
92 */
93 static void clearFileDestinationFolder(const QString &fileFolderDestination, int days = -1);
94 /**
95 * @brief enqueueMessage Enqueues a message in the corresponding QLoggerWritter.
96 * @param module The module that writes the message.
97 * @param level The level of the message.
98 * @param message The message to log.
99 * @param function The function in the file where the log comes from.
100 * @param file The file that logs.
101 * @param line The line in the file where the log comes from.
102 */
103 void enqueueMessage(const QString &module, LogLevel level, const QString &message, const QString &function,
104 const QString &file, int line);
105
106 /**
107 * @brief Whether the QLogger is paused or not.
108 */
109 bool isPaused() const { return mIsStop; }
110
111 /**
112 * @brief pause Pauses all QLoggerWriters.
113 */
114 void pause();
115
116 /**
117 * @brief resume Resumes all QLoggerWriters that where paused.
118 */
119 void resume();
120
121 /**
122 * @brief getDefaultFileDestinationFolder Gets the defaut file destination folder.
123 * @return The file destination folder
124 */
125 QString getDefaultFileDestinationFolder() const { return mDefaultFileDestinationFolder; }
126
127 /**
128 * @brief getDefaultMode Gets the default log mode.
129 * @return The log mode
130 */
131 LogMode getDefaultMode() const { return mDefaultMode; }
132
133 /**
134 * @brief getDefaultLevel Gets the default log level.
135 * @return The log level
136 */
137 LogLevel getDefaultLevel() const { return mDefaultLevel; }
138
139 /**
140 * @brief Sets default values for QLoggerWritter parameters. Usefull for multiple QLoggerWritter.
141 */
142 void setDefaultFileDestinationFolder(const QString &fileDestinationFolder);
143 void setDefaultFileDestination(const QString &fileDestination) { mDefaultFileDestination = fileDestination; }
144 void setDefaultFileSuffixIfFull(LogFileDisplay fileSuffixIfFull) { mDefaultFileSuffixIfFull = fileSuffixIfFull; }
145
146 void setDefaultLevel(LogLevel level) { mDefaultLevel = level; }
147 void setDefaultMode(LogMode mode) { mDefaultMode = mode; }
148 void setDefaultMaxFileSize(int maxFileSize) { mDefaultMaxFileSize = maxFileSize; }
149 void setDefaultMessageOptions(LogMessageDisplays messageOptions) { mDefaultMessageOptions = messageOptions; }
150
151 /**
152 * @brief overwriteLogMode Overwrites the logging mode in all the destinations. Sets the default logging mode.
153 *
154 * @param mode The new log mode
155 */
156 void overwriteLogMode(LogMode mode);
157 /**
158 * @brief overwriteLogLevel Overwrites the log level in all the destinations. Sets the default log level.
159 *
160 * @param level The new log level
161 */
162 void overwriteLogLevel(LogLevel level);
163 /**
164 * @brief overwriteMaxFileSize Overwrites the maximum file size in all the destinations. Sets the default max file
165 * size.
166 *
167 * @param maxSize The new file size
168 */
169 void overwriteMaxFileSize(int maxSize);
170
171private:
172 /**
173 * @brief Checks if the logger is stop
174 */
175 bool mIsStop = false;
176
177 /**
178 * @brief Map that stores the module and the file it is assigned.
179 */
180 QMap<QString, QLoggerWriter *> mModuleDest;
181
182 /**
183 * @brief Defines the queue of messages when no writters have been set yet.
184 */
185 QMultiMap<QString, QVector<QVariant>> mNonWriterQueue;
186
187 /**
188 * @brief Default values for QLoggerWritter parameters. Usefull for multiple QLoggerWritter.
189 */
190 QString mDefaultFileDestinationFolder;
191 QString mDefaultFileDestination;
192 LogFileDisplay mDefaultFileSuffixIfFull = LogFileDisplay::DateTime;
193
194 LogMode mDefaultMode = LogMode::OnlyFile;
195 LogLevel mDefaultLevel = LogLevel::Warning;
196 int mDefaultMaxFileSize = 1024 * 1024; //! @note 1Mio
197 LogMessageDisplays mDefaultMessageOptions = LogMessageDisplay::Default;
198
199 /**
200 * @brief Mutex to make the method thread-safe.
201 */
202 QMutex mMutex { QMutex::Recursive };
203
204 /**
205 * @brief Default builder of the class. It starts the thread.
206 */
207 QLoggerManager() = default;
208
209 /**
210 * @brief Destructor
211 */
212 ~QLoggerManager();
213
214 /**
215 * @brief Initializes and returns a new instance of QLoggerWriter with the given parameters.
216 * @param fileDest The file name and path to print logs.
217 * @param level The maximum level allowed.
218 * @param fileFolderDestination The complete folder destination.
219 * @param mode The logging mode.
220 * @param fileSuffixIfFull The filename suffix if the file is full.
221 * @param messageOptions Specifies what elements are displayed in one line of log message.
222 * @return the newly created QLoggerWriter instance.
223 */
224 QLoggerWriter *createWriter(const QString &fileDest, LogLevel level, const QString &fileFolderDestination,
225 LogMode mode, LogFileDisplay fileSuffixIfFull, LogMessageDisplays messageOptions) const;
226
227 void startWriter(const QString &module, QLoggerWriter *log, LogMode mode, bool notify);
228
229 /**
230 * @brief Checks the queue and writes the messages if the writer is the correct one. The queue is emptied
231 * for that module.
232 * @param module The module to dequeue the messages from
233 */
234 void writeAndDequeueMessages(const QString &module);
235};
236
237/**
238 * @brief Here is done the call to write the message in the module. First of all is confirmed
239 * that the log level we want to write is less or equal to the level defined when we create the
240 * destination.
241 *
242 * @param module The module that the message references.
243 * @param level The level of the message.
244 * @param message The message.
245 * @param function The function in the file where the log comes from.
246 * @param file The file that logs.
247 * @param line The line in the file where the log comes from.
248 */
249extern void QLog_(const QString &module, QLogger::LogLevel level, const QString &message, const QString &function,
250 const QString &file = QString(), int line = -1);
251
252}
253
254#ifndef QLog_Trace
255/**
256 * @brief Used to store Trace level messages.
257 * @param module The module that the message references.
258 * @param message The message.
259 */
260# define QLog_Trace(module, message) \
261 QLogger::QLoggerManager::getInstance()->enqueueMessage(module, QLogger::LogLevel::Trace, message, __FUNCTION__, \
262 __FILE__, __LINE__)
263#endif
264
265#ifndef QLog_Debug
266/**
267 * @brief Used to store Debug level messages.
268 * @param module The module that the message references.
269 * @param message The message.
270 */
271# define QLog_Debug(module, message) \
272 QLogger::QLoggerManager::getInstance()->enqueueMessage(module, QLogger::LogLevel::Debug, message, __FUNCTION__, \
273 __FILE__, __LINE__)
274#endif
275
276#ifndef QLog_Info
277/**
278 * @brief Used to store Info level messages.
279 * @param module The module that the message references.
280 * @param message The message.
281 */
282# define QLog_Info(module, message) \
283 QLogger::QLoggerManager::getInstance()->enqueueMessage(module, QLogger::LogLevel::Info, message, __FUNCTION__, \
284 __FILE__, __LINE__)
285#endif
286
287#ifndef QLog_Warning
288/**
289 * @brief Used to store Warning level messages.
290 * @param module The module that the message references.
291 * @param message The message.
292 */
293# define QLog_Warning(module, message) \
294 QLogger::QLoggerManager::getInstance()->enqueueMessage(module, QLogger::LogLevel::Warning, message, \
295 __FUNCTION__, __FILE__, __LINE__)
296#endif
297
298#ifndef QLog_Error
299/**
300 * @brief Used to store Error level messages.
301 * @param module The module that the message references.
302 * @param message The message.
303 */
304# define QLog_Error(module, message) \
305 QLogger::QLoggerManager::getInstance()->enqueueMessage(module, QLogger::LogLevel::Error, message, __FUNCTION__, \
306 __FILE__, __LINE__)
307#endif
308
309#ifndef QLog_Fatal
310/**
311 * @brief Used to store Fatal level messages.
312 * @param module The module that the message references.
313 * @param message The message.
314 */
315# define QLog_Fatal(module, message) \
316 QLogger::QLoggerManager::getInstance()->enqueueMessage(module, QLogger::LogLevel::Fatal, message, __FUNCTION__, \
317 __FILE__, __LINE__)
318#endif
319