From c876d3bbefe0dc00c27ca0c12d29da5874946962 Mon Sep 17 00:00:00 2001 From: Dominik Riebeling Date: Wed, 15 Dec 2021 21:04:28 +0100 Subject: rbutil: Merge rbutil with utils folder. rbutil uses several components from the utils folder, and can be considered part of utils too. Having it in a separate folder is an arbitrary split that doesn't help anymore these days, so merge them. This also allows other utils to easily use libtools.make without the need to navigate to a different folder. Change-Id: I3fc2f4de19e3e776553efb5dea5f779dfec0dc21 --- utils/rbutilqt/logger/src/Logger.cpp | 1108 ++++++++++++++++++++++++++++++++++ 1 file changed, 1108 insertions(+) create mode 100644 utils/rbutilqt/logger/src/Logger.cpp (limited to 'utils/rbutilqt/logger/src/Logger.cpp') diff --git a/utils/rbutilqt/logger/src/Logger.cpp b/utils/rbutilqt/logger/src/Logger.cpp new file mode 100644 index 0000000000..689bc42e80 --- /dev/null +++ b/utils/rbutilqt/logger/src/Logger.cpp @@ -0,0 +1,1108 @@ +/* + Copyright (c) 2012 Boris Moiseev (cyberbobs at gmail dot com) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1 + as published by the Free Software Foundation and appearing in the file + LICENSE.LGPL included in the packaging of this file. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. +*/ +// Local +#include "Logger.h" +#include "AbstractAppender.h" +#include "AbstractStringAppender.h" + +// Qt +#include +#include +#include +#include +#include +#include + +#if defined(Q_OS_ANDROID) +# include +# include +#endif + +// STL +#include + + +/** + * \file Logger.h + * \brief A file containing the description of Logger class and and additional useful macros for logging + */ + + +/** + * \mainpage + * + * Logger is a simple way to write the history of your application lifecycle to any target logging device (which is + * called Appender and may write to any target you will implement with it: console, text file, XML or something - you + * choose) and to map logging message to a class, function, source file and line of code which it is called from. + * + * Some simple appenders (which may be considered an examples) are provided with the Logger itself: see ConsoleAppender + * and FileAppender documentation. + * + * It supports using it in a multithreaded applications, so all of its functions are thread safe. + * + * Simple usage example: + * \code + * #include + * + * #include + * #include + * + * int main(int argc, char* argv[]) + * { + * QCoreApplication app(argc, argv); + * ... + * ConsoleAppender* consoleAppender = new ConsoleAppender; + * consoleAppender->setFormat("[%{type:-7}] <%{Function}> %{message}\n"); + * cuteLogger->registerAppender(consoleAppender); + * ... + * LOG_INFO("Starting the application"); + * int result = app.exec(); + * ... + * if (result) + * LOG_WARNING() << "Something went wrong." << "Result code is" << result; + * + * return result; + * } + * \endcode + * + * Logger internally uses the lazy-initialized singleton object and needs no definite initialization, but you may + * consider registering a log appender before calling any log recording functions or macros. + * + * The library design of Logger allows you to simply mass-replace all occurrences of qDebug and similar calls with + * similar Logger macros (e.g. LOG_DEBUG()) + * + * \note Logger uses a singleton global instance which lives through all the application life cycle and self-destroys + * destruction of the QCoreApplication (or QApplication) instance. It needs a QCoreApplication instance to be + * created before any of the Logger's functions are called. + * + * \sa cuteLogger + * \sa LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_FATAL + * \sa LOG_CTRACE, LOG_CDEBUG, LOG_CINFO, LOG_CWARNING, LOG_CERROR, LOG_CFATAL + * \sa LOG_ASSERT + * \sa LOG_TRACE_TIME, LOG_DEBUG_TIME, LOG_INFO_TIME + * \sa AbstractAppender + */ + + +/** + * \def cuteLogger + * + * \brief Macro returning the current instance of Logger object + * + * If you haven't created a local Logger object it returns the same value as the Logger::globalInstance() functions. + * This macro is a recommended way to get an access to the Logger instance used in current class. + * + * Example: + * \code + * ConsoleAppender* consoleAppender = new ConsoleAppender; + * cuteLogger->registerAppender(consoleAppender); + * \endcode + * + * \sa Logger::globalInstance() + */ + + +/** + * \def LOG_TRACE + * + * \brief Writes the trace log record + * + * This macro is the convinient way to call Logger::write(). It uses the common preprocessor macros \c __FILE__, + * \c __LINE__ and the standart Qt \c Q_FUNC_INFO macros to automatically determine the needed parameters to call + * Logger::write(). + * + * \note This and other (LOG_INFO() etc...) macros uses the variadic macro arguments to give convinient usage form for + * the different versions of Logger::write() (using the QString or const char* argument or returning the QDebug class + * instance). Not all compilers will support this. Please, consider reviewing your compiler documentation to ensure + * it support __VA_ARGS__ macro. + * + * \sa Logger::LogLevel + * \sa Logger::write() + */ + + +/** + * \def LOG_DEBUG + * + * \brief Writes the debug log record + * + * This macro records the debug log record using the Logger::write() function. It works similar to the LOG_TRACE() + * macro. + * + * \sa LOG_TRACE() + * \sa Logger::LogLevel + * \sa Logger::write() + */ + + +/** + * \def LOG_INFO + * + * \brief Writes the info log record + * + * This macro records the info log record using the Logger::write() function. It works similar to the LOG_TRACE() + * macro. + * + * \sa LOG_TRACE() + * \sa Logger::LogLevel + * \sa Logger::write() + */ + + +/** + * \def LOG_WARNING + * + * \brief Write the warning log record + * + * This macro records the warning log record using the Logger::write() function. It works similar to the LOG_TRACE() + * macro. + * + * \sa LOG_TRACE() + * \sa Logger::LogLevel + * \sa Logger::write() + */ + + +/** + * \def LOG_ERROR + * + * \brief Write the error log record + * This macro records the error log record using the Logger::write() function. It works similar to the LOG_TRACE() + * macro. + * + * \sa LOG_TRACE() + * \sa Logger::LogLevel + * \sa Logger::write() + */ + + +/** + * \def LOG_FATAL + * + * \brief Write the fatal log record + * + * This macro records the fatal log record using the Logger::write() function. It works similar to the LOG_TRACE() + * macro. + * + * \note Recording of the log record using the Logger::Fatal log level will lead to calling the STL abort() + * function, which will interrupt the running of your software and begin the writing of the core dump. + * + * \sa LOG_TRACE() + * \sa Logger::LogLevel + * \sa Logger::write() + */ + + +/** + * \def LOG_CTRACE(category) + * + * \brief Writes the trace log record to the specific category + * + * This macro is the similar to the LOG_TRACE() macro, but has a category parameter + * to write only to the category appenders (registered using Logger::registerCategoryAppender() method). + * + * \param category category name string + * + * \sa LOG_TRACE() + * \sa Logger::LogLevel + * \sa Logger::registerCategoryAppender() + * \sa Logger::write() + * \sa LOG_CATEGORY(), LOG_GLOBAL_CATEGORY() + */ + + +/** + * \def LOG_CDEBUG + * + * \brief Writes the debug log record to the specific category + * + * This macro records the debug log record using the Logger::write() function. It works similar to the LOG_CTRACE() + * macro. + * + * \sa LOG_CTRACE() + */ + + +/** + * \def LOG_CINFO + * + * \brief Writes the info log record to the specific category + * + * This macro records the info log record using the Logger::write() function. It works similar to the LOG_CTRACE() + * macro. + * + * \sa LOG_CTRACE() + */ + + +/** + * \def LOG_CWARNING + * + * \brief Writes the warning log record to the specific category + * + * This macro records the warning log record using the Logger::write() function. It works similar to the LOG_CTRACE() + * macro. + * + * \sa LOG_CTRACE() + */ + + +/** + * \def LOG_CERROR + * + * \brief Writes the error log record to the specific category + * + * This macro records the error log record using the Logger::write() function. It works similar to the LOG_CTRACE() + * macro. + * + * \sa LOG_CTRACE() + */ + + +/** + * \def LOG_CFATAL + * + * \brief Write the fatal log record to the specific category + * + * This macro records the fatal log record using the Logger::write() function. It works similar to the LOG_CTRACE() + * macro. + * + * \note Recording of the log record using the Logger::Fatal log level will lead to calling the STL abort() + * function, which will interrupt the running of your software and begin the writing of the core dump. + * + * \sa LOG_CTRACE() + */ + + +/** + * \def LOG_CATEGORY(category) + * + * \brief Create logger instance inside your custom class to log all messages to the specified category + * + * This macro is used to pass all log messages inside your custom class to the specific category. + * You must include this macro inside your class declaration (similarly to the Q_OBJECT macro). + * Internally, this macro redefines cuteLoggerInstance() function, creates the local Logger object inside your class and + * sets the default category to the specified parameter. + * + * Thus, any call to cuteLoggerInstance() (for example, inside LOG_TRACE() macro) will return the local Logger object, + * so any logging message will be directed to the default category. + * + * \note This macro does not register any appender to the newly created logger instance. You should register + * logger appenders manually, inside your class. + * + * Usage example: + * \code + * class CustomClass : public QObject + * { + * Q_OBJECT + * LOG_CATEGORY("custom_category") + * ... + * }; + * + * CustomClass::CustomClass(QObject* parent) : QObject(parent) + * { + * cuteLogger->registerAppender(new FileAppender("custom_category_log")); + * LOG_TRACE() << "Trace to the custom category log"; + * } + * \endcode + * + * If used compiler supports C++11 standard, LOG_CATEGORY and LOG_GLOBAL_CATEGORY macros would also work when added + * inside of any scope. It could be useful, for example, to log every single run of a method to a different file. + * + * \code + * void foo() + * { + * QString categoryName = QDateTime::currentDateTime().toString("yyyy-MM-ddThh-mm-ss-zzz"); + * LOG_CATEGORY(categoryName); + * cuteLogger->registerAppender(new FileAppender(categoryName + ".log")); + * ... + * } + * \endcode + * + * \sa Logger::write() + * \sa LOG_TRACE + * \sa Logger::registerCategoryAppender() + * \sa Logger::setDefaultCategory() + * \sa LOG_GLOBAL_CATEGORY + */ + + +/** + * \def LOG_GLOBAL_CATEGORY(category) + * + * \brief Create logger instance inside your custom class to log all messages both to the specified category and to + * the global logger instance. + * + * This macro is similar to LOG_CATEGORY(), but also passes all log messages to the global logger instance appenders. + * It is equal to defining the local category logger using LOG_CATEGORY macro and calling: + * \code cuteLogger->logToGlobalInstance(cuteLogger->defaultCategory(), true); \endcode + * + * \sa LOG_CATEGORY + * \sa Logger::logToGlobalInstance() + * \sa Logger::defaultCategory() + * \sa Logger::registerCategoryAppender() + * \sa Logger::write() + */ + + + +/** + * \def LOG_ASSERT + * + * \brief Check the assertion + * + * This macro is a convinient and recommended to use way to call Logger::writeAssert() function. It uses the + * preprocessor macros (as the LOG_DEBUG() does) to fill the necessary arguments of the Logger::writeAssert() call. It + * also uses undocumented but rather mature and stable \c qt_noop() function (which does nothing) when the assertion + * is true. + * + * Example: + * \code + * bool b = checkSomething(); + * ... + * LOG_ASSERT(b == true); + * \endcode + * + * \sa Logger::writeAssert() + */ + + +/** + * \def LOG_TRACE_TIME + * + * \brief Logs the processing time of current function / code block + * + * This macro automagically measures the function or code of block execution time and outputs it as a Logger::Trace + * level log record. + * + * Example: + * \code + * int foo() + * { + * LOG_TRACE_TIME(); + * ... // Do some long operations + * return 0; + * } // Outputs: Function foo finished in