| 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 | |
| 31 | namespace QLogger |
| 32 | { |
| 33 | |
| 34 | class QLoggerWriter; |
| 35 | |
| 36 | /** |
| 37 | * @brief The QLoggerManager class manages the different destination files that we would like to have. |
| 38 | */ |
| 39 | class QLoggerManager |
| 40 | { |
| 41 | public: |
| 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 | |
| 171 | private: |
| 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 | */ |
| 249 | extern 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 | |