Mercurial > public > ostc_companion
view Utils/Log.h @ 1:0b3630a29ad8
Initial version based on previous repository.
Project was ported to QT6 and in now cmake based.
| author | Ideenmodellierer <tiefenrauscher@web.de> |
|---|---|
| date | Thu, 27 Nov 2025 18:40:28 +0100 |
| parents | |
| children |
line wrap: on
line source
////////////////////////////////////////////////////////////////////////////// /// \file Log.h /// \brief Basic logging tool /// \author JD Gascuel. /// \copyright (c) 2011-2016 JD Gascuel. All rights reserved. /// $Id$ ////////////////////////////////////////////////////////////////////////////// // // BSD 2-Clause License: // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF // THE POSSIBILITY OF SUCH DAMAGE. // ////////////////////////////////////////////////////////////////////////////// // HISTORY // 2013-07-01 jDG: Creation. // 2016-05-24 jDG: BSD-2 version. #ifndef LOG_H #define LOG_H #include <QString> #include <QStringList> #include <QByteArray> //class QStringList; //class QByteArray; #define LOG_MAX_MESSAGE_LENGTH 2048 ////////////////////////////////////////////////////////////////////////////// /// \brief Basic logging tool /// /// /// Provides easy and centralized log messages for the application. /// Typical usage: /// \code /// main(int argc, char* argv[]) /// { /// Log::autoLoad(argc, argv); // Read XML configuration. /// LOG_TRACE("... "); // Just a tick where we are. /// /// LOG_INFO("Main started"); // Visible message (users can see it). /// LOG_TRACE("Now argc=" << argc); /// LOG_TRACE("Invisible message, only for log files"); /// LOG_DEBUG("Invisible, and logged only if run with a "-d" argument"); /// } /// \endcode /// /// \note that message destination can be multiple, and are the responsability /// of the LogAppender class hierarchy. /// /// \sa LogAppender, LogConsole, LogFile. class Log { /// Application's reference. static QString _applicationPath; static QString _applicationName; public: ////////////////////////////////////////////////////////////////////////// /// \{ /// \name Record message and context //------------------------------------------------------------------------ /// \brief Log level: severity scale. enum Level { LEVEL_NOERROR = 0, LEVEL_DEBUG, ///< The most verbose one, used only during debug session. LEVEL_TRACE, ///< Messages to be put in silent log files, for post-mortem analysis. LEVEL_INFO, ///< General information send to the final user. LEVEL_WARNING, ///< Error reported to the user (eg. with a Qt warning box. \sa LogAppenderWindow). LEVEL_THROW, ///< Error that is mean to be catched, and corrected automatically. LEVEL_ERROR ///< Fatal error that cannot be recovered. The program should halt. }; //------------------------------------------------------------------------ const Level level; ///< Event's log level. const QString file; ///< Source file that fired the log event. const int line; ///< Source line that fired the log event. const QString function; ///< Function (and class) that fired the event. QString message; ///< The log message itself. /// \} ////////////////////////////////////////////////////////////////////////// /// \{ /// \name Global services //------------------------------------------------------------------------ /// \brief Minimal error level to log. /// /// Defaults to LEVEL_TRACE. static Level minLevel; //------------------------------------------------------------------------ /// \brief Initialize the log system, by loading some XML config. /// /// Might be used to change logging configuration of installed /// applications. //------------------------------------------------------------------------ /// Initialize the log system, by loading some XML config. static void autoLoad(int argc, char *argv[]); //------------------------------------------------------------------------ /// \brief Initialize the log system, without configurations. /// /// Then one can instanciate LogAppender classes in a static way. static void init(int& argc, char* argv[]); //------------------------------------------------------------------------ /// \brief End the log systems, closing all appenders. static void close(); //------------------------------------------------------------------------ /// \brief Utility to retrieve where the executable was installed. static inline QString applicationPath(); /// \brief Utility to retrieve the executable's name. static inline QString applicationName(); /// \} protected: /// \brief Constructor /// /// All message are to be created by a LogAction instance, responsible /// to build-up the message, and to send it to LogAppender instances. Log(Level level, const char *file, int line, const char *function); }; inline QString Log::applicationPath() { return _applicationPath; } inline QString Log::applicationName() { return _applicationName; } ////////////////////////////////////////////////////////////////////////////// /// \brief Creates a Log event. /// /// Uses object's destructor to send the Log into all registered log appenders. class LogAction : public Log { public: /// Starts a log line, with timestamp and source-stamp. LogAction(Level level, const char* file, int line, const char* function); /// Finish (and print) a log line. ~LogAction(); /// Appends a single char to the log line. LogAction& operator<<(char msg); /// Appends a single char to the log line. LogAction& operator<<(unsigned char msg); /// Appends a C string to the log line. LogAction& operator<<(const char* msg); /// Appends a Qt's wide-char string to the log line, converted to Latin1. LogAction& operator<<(const QString& msg); /// Appends a list of Qt's wide-char strings. LogAction& operator<<(const QStringList& msg); /// Appends a Qt's single-byte-string to the log line. LogAction& operator<<(const QByteArray& msg); /// Appends a float/double to the log line. LogAction& operator<<(double value); /// Appends a signed int/short/byte to the log line. LogAction& operator<<(int value); /// Appends an unsigned int/short/byte to the log line. LogAction& operator<<(unsigned int value); // Resole ambiguities for the C++ compiler. /// Appends a signed long to the log line. LogAction& operator<<(long value); /// Appends an unsigned long to the log line. LogAction& operator<<(unsigned long value); /// Appends a signed long long to the log line. LogAction& operator<<(long long value); /// Appends an unsigned long long to the log line. LogAction& operator<<(unsigned long long value); /// Print any pointer as an Hex address: LogAction& operator<<(const void* ptr); }; #ifndef LOG_FUNCTION_ # if defined __PRETTY_FUNCTION__ # define LOG_FUNCTION_ __PRETTY_FUNCTION__ # elif defined __FUNCSIG__ # define LOG_FUNCTION_ __FUNCSIG__ # elif defined __FUNCTION__ # define LOG_FUNCTION_ __FUNCTION__ # elif defined __func__ # define LOG_FUNCTION_ __func__ # elif defined LINUX # define LOG_FUNCTION_ __PRETTY_FUNCTION__ # else # define LOG_FUNCTION_ __FILE__ # endif #endif #define LOG_DEBUG(msg) do { if( Log::minLevel <= Log::LEVEL_DEBUG ) LogAction(Log::LEVEL_DEBUG, __FILE__, __LINE__, LOG_FUNCTION_ ) << msg; } while(0) #define LOG_TRACE(msg) do { if( Log::minLevel <= Log::LEVEL_TRACE ) LogAction(Log::LEVEL_TRACE, __FILE__, __LINE__, LOG_FUNCTION_ ) << msg; } while(0) #define LOG_INFO(msg) do { if( Log::minLevel <= Log::LEVEL_INFO ) LogAction(Log::LEVEL_INFO, __FILE__, __LINE__, LOG_FUNCTION_ ) << msg; } while(0) #define LOG_WARNING(msg) do { if( Log::minLevel <= Log::LEVEL_WARNING) LogAction(Log::LEVEL_WARNING, __FILE__, __LINE__, LOG_FUNCTION_ ) << msg; } while(0) #define LOG_ERROR(msg) do { if( Log::minLevel <= Log::LEVEL_ERROR ) LogAction(Log::LEVEL_ERROR, __FILE__, __LINE__, LOG_FUNCTION_ ) << msg; } while(0) #include <sstream> // Für std::ostringstream #include "Exception.h" // Hilfsmakros für stringification #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #define LOG_THROW_E(EXCEPTION, msg) \ do { \ LogAction log(Log::LEVEL_THROW, __FILE__, __LINE__, LOG_FUNCTION_ ); \ log << msg; \ throw EXCEPTION(log.message); \ } while(0) #define LOG_THROW(msg) \ do { \ LogAction log(Log::LEVEL_THROW, __FILE__, __LINE__, LOG_FUNCTION_ ); \ log << msg; \ throw ::Exception(log.message); \ } while(0) #define assert(e) \ do { if( !(e) ) \ LOG_THROW("Assert: " #e); \ } while(0) #endif // LOG_H
