Mercurial > public > ostc_companion
diff 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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Utils/Log.h Thu Nov 27 18:40:28 2025 +0100 @@ -0,0 +1,251 @@ +////////////////////////////////////////////////////////////////////////////// +/// \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
