log.h 9.73 KB
/* ****************************************************************************
 * Copyright 2019 Open Systems Development BV                                 *
 *                                                                            *
 * Permission is hereby granted, free of charge, to any person obtaining a    *
 * copy of this software and associated documentation files (the "Software"), *
 * to deal in the Software without restriction, including without limitation  *
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
 * and/or sell copies of the Software, and to permit persons to whom the      *
 * Software is furnished to do so, subject to the following conditions:       *
 *                                                                            *
 * The above copyright notice and this permission notice shall be included in *
 * all copies or substantial portions of the Software.                        *
 *                                                                            *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    *
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        *
 * DEALINGS IN THE SOFTWARE.                                                  *
 * ***************************************************************************/

#ifndef OSDEV_COMPONENTS_LOG_H
#define OSDEV_COMPONENTS_LOG_H

// local
#include "logutilslibexport.h"

// qt
#include <QString>
#include <QMutex>

class QObject;

namespace osdev  {
namespace components {

#define LogDebug(context, text)                                                     \
    if (osdev::components::Log::level() <= osdev::components::LogLevel::Debug)      \
    {                                                                               \
        osdev::components::Log::debug(__FILE__, __LINE__, context, text);           \
    }

#define LogObject(context, object)                                                  \
    if (osdev::components::Log::level() <= osdev::components::LogLevel::Debug)      \
    {                                                                               \
        osdev::components::Log::logObject(__FILE__, __LINE__, context, object);     \
    }

#define LogInfo(context, text)                                                      \
    if (osdev::components::Log::level() <= osdev::components::LogLevel::Info)       \
    {                                                                               \
        osdev::components::Log::info(__FILE__, __LINE__, context,text);             \
    }

#define LogWarning(context, text)                                                   \
    if (osdev::components::Log::level() <= osdev::components::LogLevel::Warning)    \
    {                                                                               \
        osdev::components::Log::warning(__FILE__, __LINE__, context, text);         \
    }

#define LogError(context, text)                                                     \
    if (osdev::components::Log::level() <= osdev::components::LogLevel::Error)      \
    {                                                                               \
        osdev::components::Log::error(__FILE__, __LINE__, context, text);           \
    }

#define LogTrace(context, text)                                                     \
    if (osdev::components::Log::level() <= osdev::components::LogLevel::Trace)      \
    {                                                                               \
        osdev::components::Log::trace(__FILE__, __LINE__, context, text);           \
    }


enum class LogLevel
{
    Trace,
    Debug,
    Info,
    Warning,
    Error
};

/*! \class Log
    \brief Basic logging mechanism.
*/
class LOGUTILSLIBINTERFACE Log
{
public:
    /**
     * @brief Initialise the logging mechanism
     * @param context The main context
     * @param logFile Logfile if available
     * @param logDepth Initial log-depth
     */
    static void init( const QString& context,
                      const QString& logFile = QString(),
                      LogLevel logDepth = LogLevel::Info );

    //! Shutdown the logging mechanism.
    static void terminate();

    /**
     * @brief Log a trace message in a category.
     * @param file Name of the source-file
     * @param line The line number in the source-file
     * @param category The category of the message.
     * @param message The string to print.
     */
    static void trace( const char* file, int line,
                      const QString& category, const QString& message );

    /**
     * @brief Log a debug message in a category.
     * @param file Name of the source-file
     * @param line The line number in the source-file
     * @param category The category of the message.
     * @param message The string to print.
     */
    static void debug(const char* file, int line,
                      const QString& category, const QString& message);

    /**
     * @brief Log an info message in a category.
     * @param file Name of the source-file
     * @param line The line number in the source-file
     * @param category The category of the message.
     * @param message The string to print.
     */
    static void info( const char* file, int line,
                      const QString& category, const QString& message );

    /**
     * @brief Log a warning message in a category.
     * @param file Name of the source-file
     * @param line The line number in the source-file
     * @param category The category of the message.
     * @param message The string to print.
     */
    static void warning( const char* file, int line,
                         const QString& category, const QString& message );

    /**
     * @brief Log an error message in a category.
     * @param file Name of the source-file
     * @param line The line number in the source-file
     * @param category The category of the message.
     * @param message The string to print.
     */
    static void error( const char* file, int line,
                       const QString& category, const QString& message );

    /**
     * @brief Dump a complete Qt Object in the logging stream at LogLevel::Debug
     * @param file Name of the source-file
     * @param line The line number in the source-file
     * @param category The category of the message
     * @param object The object to print
     */
    static void logObject( const char* file, int line,
                           const QString& category, QObject* object );

    /**
     * @return The current log level.
     */
    static LogLevel level()
    {
        return s_logLevel;
    }

protected:
    /**
     * @brief Log a debug message in a category.
     * @param category The category of the message.
     * @param message The string to print.
     */
    static void debug(const QString& category, const QString& message);

    /**
     * @brief Log an info message in a category.
     * @param category The category of the message.
     * @param message The string to print.
     */
    static void info( const QString& category, const QString& message );

    /**
     * @brief Log a warning message in a category.
     * @param category The category of the message.
     * @param message The string to print.
     */
    static void warning( const QString& category, const QString& message );

    /**
     * @brief Log an error message in a category.
     * @param category The category of the message.
     * @param message The string to print.
     */
    static void error( const QString& category, const QString& message );

    /**
     * @brief Log a trace message in a category.
     * @param category The category of the message.
     * @param message The string to print.
     */
    static void trace( const QString& category, const QString& message );

    /**
     * @brief Dump a complete Qt Object in the logging stream at LogLevel::Info
     * @param category The category of the message
     * @param object The object to print
     */
    static void logObject( const QString& category, QObject* object );

    //! Create a convenient timestamp
    static QString getDateTime();

    /**
     * @brief Write the message to the logfile
     * @param category The category of the message.
     * @param message The string to print.
     * @param level Selected log level
     */
    static void writeLog( const QString& category,
                          const QString& message,
                          LogLevel level );

    /**
     * @brief Log an error message in a category.
     * @param category The category of the message.
     * @param message The string to print.
     * @param level Selected log level
     */
    static void log(const QString& category,
                    const QString& message,
                    LogLevel level);

private:
    /**
     * @brief Put filename, line-number and message in one string
     * @param file Source-file
     * @param line Line in source-file
     * @param message The string to print
     * @return Formatted string with file, line and message
     */
    static QString fileinfoMessage(const char* file, int line,
                                   const QString& message);

    //! The main context.
    static QString s_context;

    //! The name of the LogFile.
    static QString s_fileName;

    //! The amount of logging
    static LogLevel s_logLevel;

    //! Mutex to keep it thread-safe
    static QMutex   m_mutex;
};

} // End namespace components
} // End namespace osdev

#endif // OSDEV_COMPONENTS_LOG_H