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