Commit fe467aa587c648b6018532b7b7bbb2ed1feed656

Authored by Steven de Ridder
0 parents

Initial commit MIT-licenced logutils to open_source

.gitignore 0 → 100644
  1 +++ a/.gitignore
  1 +build/
  2 +CMakeLists.txt.user
... ...
CMakeLists.txt 0 → 100644
  1 +++ a/CMakeLists.txt
  1 +cmake_minimum_required(VERSION 3.0)
  2 +LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
  3 +
  4 +# Check to see if there is versioning information available
  5 +if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/osdev_versioning/cmake)
  6 + LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/osdev_versioning/cmake)
  7 + include(osdevversion)
  8 +endif()
  9 +
  10 +include(projectheader)
  11 +project_header(osdev_logutils)
  12 +
  13 +add_subdirectory(src)
  14 +add_subdirectory(tests)
  15 +
  16 +# include(packaging)
  17 +# package_component()
... ...
README.md 0 → 100644
  1 +++ a/README.md
... ...
cmake 0 → 120000
  1 +++ a/cmake
  1 +../cmake/
0 2 \ No newline at end of file
... ...
src/CMakeLists.txt 0 → 100644
  1 +++ a/src/CMakeLists.txt
  1 +cmake_minimum_required(VERSION 3.0)
  2 +LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake)
  3 +include(projectheader)
  4 +project_header(logutils)
  5 +
  6 +# find_library( log4cplus REQUIRED )
  7 +find_package( Qt5Core REQUIRED )
  8 +find_package( Qt5Sql REQUIRED )
  9 +
  10 +include_directories( SYSTEM
  11 + ${Qt5Core_INCLUDE_DIRS}
  12 + ${CMAKE_CURRENT_SOURCE_DIR}/../global
  13 +)
  14 +
  15 +include(compiler)
  16 +
  17 +set(SRC_LIST
  18 + ${CMAKE_CURRENT_SOURCE_DIR}/log.cpp
  19 + ${CMAKE_CURRENT_SOURCE_DIR}/threadcontext.cpp
  20 +)
  21 +
  22 +include(library)
  23 +add_libraries(
  24 + ${Qt5Core_LIBRARIES}
  25 + # ${log4cplus_LIBRARIES}
  26 +)
  27 +
  28 +include(installation)
  29 +install_component()
... ...
src/log.cpp 0 → 100644
  1 +++ a/src/log.cpp
  1 +/* **************************************************************************************************************************************************************************
  2 + * Copyright 2019 Open Systems Development BV *
  3 + * *
  4 + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), *
  5 + * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, *
  6 + * 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: *
  7 + * *
  8 + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. *
  9 + * *
  10 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
  11 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR *
  12 + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, *
  13 + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
  14 + * **************************************************************************************************************************************************************************/
  15 +
  16 +// std
  17 +#include <ios>
  18 +#include <iomanip>
  19 +#include <sstream>
  20 +#include <thread>
  21 +
  22 +//#include "timeutils.h"
  23 +#include "log.h"
  24 +#include "threadcontext.h"
  25 +
  26 +#include <QBuffer>
  27 +#include <QByteArray>
  28 +#include <QDataStream>
  29 +#include <QDateTime>
  30 +#include <QDebug>
  31 +#include <QFile>
  32 +#include <QFileInfo>
  33 +#include <QIODevice>
  34 +#include <QObject>
  35 +#include <QMutexLocker>
  36 +
  37 +namespace osdev {
  38 +namespace components {
  39 +
  40 +namespace {
  41 +
  42 +QString toString(LogLevel level)
  43 +{
  44 + switch(level)
  45 + {
  46 + case LogLevel::Trace:
  47 + return "T";
  48 + case LogLevel::Debug:
  49 + return "D";
  50 + case LogLevel::Info:
  51 + return "I";
  52 + case LogLevel::Warning:
  53 + return "W";
  54 + case LogLevel::Error:
  55 + return "E";
  56 + }
  57 + return "U";
  58 +}
  59 +
  60 +} // anonymous
  61 +
  62 +QString Log::s_context = QString();
  63 +QString Log::s_fileName = QString();
  64 +LogLevel Log::s_logLevel = LogLevel::Debug;
  65 +QMutex Log::m_mutex;
  66 +
  67 +void Log::init(const QString& context, const QString& logFile, LogLevel logDepth)
  68 +{
  69 + s_logLevel = logDepth;
  70 + s_context = context;
  71 +
  72 + if ( !logFile.isEmpty() )
  73 + {
  74 + s_fileName = logFile;
  75 + }
  76 +}
  77 +
  78 +void Log::terminate()
  79 +{
  80 + s_context.clear();
  81 + s_fileName.clear();
  82 + s_logLevel = LogLevel::Info;
  83 +}
  84 +
  85 +void Log::log(const QString& category, const QString& message, LogLevel level)
  86 +{
  87 + QMutexLocker lock( &m_mutex );
  88 +
  89 + QString logCategory = s_context + '|' + toString(level) + '|' + ThreadContext::instance().context() + '|' + category;
  90 + QString logMessage = message;
  91 + if(logMessage.isEmpty())
  92 + {
  93 + static const QString emptyMessage("--");
  94 + logMessage = emptyMessage;
  95 + }
  96 + else
  97 + {
  98 + // Replace % signs.
  99 + logMessage.replace('%', "%%");
  100 + }
  101 +
  102 + writeLog( logCategory, logMessage, level );
  103 +}
  104 +
  105 +QString Log::fileinfoMessage(const char* file, int line, const QString& message)
  106 +{
  107 + static const QString templ("%1:%2| %3");
  108 + QFileInfo fi(file);
  109 + return templ.arg( fi.fileName() ).arg(line).arg(message);
  110 +}
  111 +
  112 +void Log::trace(const QString &category, const QString &message)
  113 +{
  114 + log(category, message, LogLevel::Trace);
  115 +}
  116 +
  117 +void Log::debug(const QString& category, const QString& message)
  118 +{
  119 + log( category, message, LogLevel::Debug );
  120 +}
  121 +
  122 +void Log::info(const QString& category, const QString& message)
  123 +{
  124 + log( category, message, LogLevel::Info );
  125 +}
  126 +
  127 +void Log::warning(const QString& category, const QString& message)
  128 +{
  129 + log(category, message, LogLevel::Warning );
  130 +}
  131 +
  132 +void Log::error(const QString& category, const QString& message)
  133 +{
  134 + log(category, message, LogLevel::Error );
  135 +}
  136 +
  137 +void Log::logObject(const QString& category, QObject* object)
  138 +{
  139 + QBuffer buffer;
  140 + buffer.open(QIODevice::ReadWrite);
  141 +
  142 + QDataStream datastream(&buffer);
  143 + QString data;
  144 +
  145 + datastream << object;
  146 + datastream >> data;
  147 +
  148 + log( category, data, LogLevel::Debug );
  149 +}
  150 +
  151 +void Log::trace(const char *file, int line, const QString &category, const QString &message)
  152 +{
  153 + log(category, fileinfoMessage(file, line, message), LogLevel::Trace );
  154 +}
  155 +
  156 +void Log::debug(const char* file, int line, const QString& category, const QString& message)
  157 +{
  158 + log( category, fileinfoMessage(file, line, message), LogLevel::Debug );
  159 +}
  160 +
  161 +void Log::info(const char* file, int line, const QString& category, const QString& message)
  162 +{
  163 + log( category, fileinfoMessage(file, line, message), LogLevel::Info );
  164 +}
  165 +
  166 +void Log::warning(const char* file, int line, const QString& category, const QString& message)
  167 +{
  168 + log( category, fileinfoMessage(file, line, message), LogLevel::Warning);
  169 +}
  170 +
  171 +void Log::error(const char* file, int line, const QString& category, const QString& message)
  172 +{
  173 + log( category, fileinfoMessage(file, line, message), LogLevel::Error );
  174 +}
  175 +
  176 +void Log::logObject(const char* file, int line, const QString& category, QObject* object)
  177 +{
  178 + QBuffer buffer;
  179 + buffer.open(QIODevice::ReadWrite);
  180 +
  181 + QDataStream datastream(&buffer);
  182 + QString data;
  183 +
  184 + datastream << object;
  185 + datastream >> data;
  186 +
  187 + log( " [LOGOBJECT] " + category, fileinfoMessage(file, line, data), LogLevel::Debug );
  188 +}
  189 +
  190 +QString Log::getDateTime()
  191 +{
  192 + return QDateTime::currentDateTime().toString( "dd-MM-yyyy HH:mm:ss.zzz" );
  193 +}
  194 +
  195 +void Log::writeLog(const QString& category, const QString& message, LogLevel level)
  196 +{
  197 +
  198 + if ( level >= s_logLevel )
  199 + {
  200 + std::ostringstream threadIdStr;
  201 + threadIdStr << std::right << std::setfill('0') << std::setw(12) << std::hex << std::this_thread::get_id();
  202 +
  203 + QString logLine;
  204 + QTextStream(&logLine) << getDateTime() << '|' << threadIdStr.str().c_str() << '|' << category << '|' << message;
  205 + if ( !s_fileName.isEmpty() )
  206 + {
  207 + QFile mFile( s_fileName );
  208 + if ( !mFile.open( QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text ) )
  209 + {
  210 + qWarning() << "Error opening the logfile : " << s_fileName << " for writing.";
  211 + qWarning() << logLine;
  212 + }
  213 + else
  214 + {
  215 + QTextStream out( &mFile );
  216 + out << logLine << '\n';
  217 + mFile.close();
  218 + }
  219 + }
  220 + else
  221 + {
  222 + qDebug() << logLine;
  223 + }
  224 + }
  225 +}
  226 +
  227 +} /* End namespace components */
  228 +} /* End namespace osdev */
... ...
src/log.h 0 → 100644
  1 +++ a/src/log.h
  1 +/* **************************************************************************************************************************************************************************
  2 + * Copyright 2019 Open Systems Development BV *
  3 + * *
  4 + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), *
  5 + * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, *
  6 + * 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: *
  7 + * *
  8 + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. *
  9 + * *
  10 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
  11 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR *
  12 + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, *
  13 + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
  14 + * **************************************************************************************************************************************************************************/
  15 +
  16 +#ifndef OSDEV_COMPONENTS_LOG_H
  17 +#define OSDEV_COMPONENTS_LOG_H
  18 +
  19 +// local
  20 +#include "logutilslibexport.h"
  21 +
  22 +// qt
  23 +#include <QString>
  24 +#include <QMutex>
  25 +
  26 +class QObject;
  27 +
  28 +namespace osdev {
  29 +namespace components {
  30 +
  31 +#define LogDebug(context, text) \
  32 + if (osdev::components::Log::level() <= osdev::components::LogLevel::Debug) \
  33 + { \
  34 + osdev::components::Log::debug(__FILE__, __LINE__, context, text); \
  35 + }
  36 +
  37 +#define LogObject(context, object) \
  38 + if (osdev::components::Log::level() <= osdev::components::LogLevel::Debug) \
  39 + { \
  40 + osdev::components::Log::logObject(__FILE__, __LINE__, context, object); \
  41 + }
  42 +
  43 +#define LogInfo(context, text) \
  44 + if (osdev::components::Log::level() <= osdev::components::LogLevel::Info) \
  45 + { \
  46 + osdev::components::Log::info(__FILE__, __LINE__, context,text); \
  47 + }
  48 +
  49 +#define LogWarning(context, text) \
  50 + if (osdev::components::Log::level() <= osdev::components::LogLevel::Warning) \
  51 + { \
  52 + osdev::components::Log::warning(__FILE__, __LINE__, context, text); \
  53 + }
  54 +
  55 +#define LogError(context, text) \
  56 + if (osdev::components::Log::level() <= osdev::components::LogLevel::Error) \
  57 + { \
  58 + osdev::components::Log::error(__FILE__, __LINE__, context, text); \
  59 + }
  60 +
  61 +#define LogTrace(context, text) \
  62 + if (osdev::components::Log::level() <= osdev::components::LogLevel::Trace) \
  63 + { \
  64 + osdev::components::Log::trace(__FILE__, __LINE__, context, text); \
  65 + }
  66 +
  67 +
  68 +enum class LogLevel
  69 +{
  70 + Trace,
  71 + Debug,
  72 + Info,
  73 + Warning,
  74 + Error
  75 +};
  76 +
  77 +/*! \class Log
  78 + \brief Basic logging mechanism.
  79 +*/
  80 +class LOGUTILSLIBINTERFACE Log
  81 +{
  82 +public:
  83 + /**
  84 + * @brief Initialise the logging mechanism
  85 + * @param context The main context
  86 + * @param logFile Logfile if available
  87 + * @param logDepth Initial log-depth
  88 + */
  89 + static void init( const QString& context,
  90 + const QString& logFile = QString(),
  91 + LogLevel logDepth = LogLevel::Info );
  92 +
  93 + //! Shutdown the logging mechanism.
  94 + static void terminate();
  95 +
  96 + /**
  97 + * @brief Log a trace message in a category.
  98 + * @param file Name of the source-file
  99 + * @param line The line number in the source-file
  100 + * @param category The category of the message.
  101 + * @param message The string to print.
  102 + */
  103 + static void trace( const char* file, int line,
  104 + const QString& category, const QString& message );
  105 +
  106 + /**
  107 + * @brief Log a debug message in a category.
  108 + * @param file Name of the source-file
  109 + * @param line The line number in the source-file
  110 + * @param category The category of the message.
  111 + * @param message The string to print.
  112 + */
  113 + static void debug(const char* file, int line,
  114 + const QString& category, const QString& message);
  115 +
  116 + /**
  117 + * @brief Log an info message in a category.
  118 + * @param file Name of the source-file
  119 + * @param line The line number in the source-file
  120 + * @param category The category of the message.
  121 + * @param message The string to print.
  122 + */
  123 + static void info( const char* file, int line,
  124 + const QString& category, const QString& message );
  125 +
  126 + /**
  127 + * @brief Log a warning message in a category.
  128 + * @param file Name of the source-file
  129 + * @param line The line number in the source-file
  130 + * @param category The category of the message.
  131 + * @param message The string to print.
  132 + */
  133 + static void warning( const char* file, int line,
  134 + const QString& category, const QString& message );
  135 +
  136 + /**
  137 + * @brief Log an error message in a category.
  138 + * @param file Name of the source-file
  139 + * @param line The line number in the source-file
  140 + * @param category The category of the message.
  141 + * @param message The string to print.
  142 + */
  143 + static void error( const char* file, int line,
  144 + const QString& category, const QString& message );
  145 +
  146 + /**
  147 + * @brief Dump a complete Qt Object in the logging stream at LogLevel::Debug
  148 + * @param file Name of the source-file
  149 + * @param line The line number in the source-file
  150 + * @param category The category of the message
  151 + * @param object The object to print
  152 + */
  153 + static void logObject( const char* file, int line,
  154 + const QString& category, QObject* object );
  155 +
  156 + /**
  157 + * @return The current log level.
  158 + */
  159 + static LogLevel level()
  160 + {
  161 + return s_logLevel;
  162 + }
  163 +
  164 +protected:
  165 + /**
  166 + * @brief Log a debug message in a category.
  167 + * @param category The category of the message.
  168 + * @param message The string to print.
  169 + */
  170 + static void debug(const QString& category, const QString& message);
  171 +
  172 + /**
  173 + * @brief Log an info message in a category.
  174 + * @param category The category of the message.
  175 + * @param message The string to print.
  176 + */
  177 + static void info( const QString& category, const QString& message );
  178 +
  179 + /**
  180 + * @brief Log a warning message in a category.
  181 + * @param category The category of the message.
  182 + * @param message The string to print.
  183 + */
  184 + static void warning( const QString& category, const QString& message );
  185 +
  186 + /**
  187 + * @brief Log an error message in a category.
  188 + * @param category The category of the message.
  189 + * @param message The string to print.
  190 + */
  191 + static void error( const QString& category, const QString& message );
  192 +
  193 + /**
  194 + * @brief Log a trace message in a category.
  195 + * @param category The category of the message.
  196 + * @param message The string to print.
  197 + */
  198 + static void trace( const QString& category, const QString& message );
  199 +
  200 + /**
  201 + * @brief Dump a complete Qt Object in the logging stream at LogLevel::Info
  202 + * @param category The category of the message
  203 + * @param object The object to print
  204 + */
  205 + static void logObject( const QString& category, QObject* object );
  206 +
  207 + //! Create a convenient timestamp
  208 + static QString getDateTime();
  209 +
  210 + /**
  211 + * @brief Write the message to the logfile
  212 + * @param category The category of the message.
  213 + * @param message The string to print.
  214 + * @param level Selected log level
  215 + */
  216 + static void writeLog( const QString& category,
  217 + const QString& message,
  218 + LogLevel level );
  219 +
  220 + /**
  221 + * @brief Log an error message in a category.
  222 + * @param category The category of the message.
  223 + * @param message The string to print.
  224 + * @param level Selected log level
  225 + */
  226 + static void log(const QString& category,
  227 + const QString& message,
  228 + LogLevel level);
  229 +
  230 +private:
  231 + /**
  232 + * @brief Put filename, line-number and message in one string
  233 + * @param file Source-file
  234 + * @param line Line in source-file
  235 + * @param message The string to print
  236 + * @return Formatted string with file, line and message
  237 + */
  238 + static QString fileinfoMessage(const char* file, int line,
  239 + const QString& message);
  240 +
  241 + //! The main context.
  242 + static QString s_context;
  243 +
  244 + //! The name of the LogFile.
  245 + static QString s_fileName;
  246 +
  247 + //! The amount of logging
  248 + static LogLevel s_logLevel;
  249 +
  250 + //! Mutex to keep it thread-safe
  251 + static QMutex m_mutex;
  252 +};
  253 +
  254 +} // End namespace components
  255 +} // End namespace osdev
  256 +
  257 +#endif // OSDEV_COMPONENTS_LOG_H
... ...
src/logutilslibexport.h 0 → 100644
  1 +++ a/src/logutilslibexport.h
  1 +/* **************************************************************************************************************************************************************************
  2 + * Copyright 2019 Open Systems Development BV *
  3 + * *
  4 + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), *
  5 + * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, *
  6 + * 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: *
  7 + * *
  8 + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. *
  9 + * *
  10 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
  11 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR *
  12 + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, *
  13 + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
  14 + * **************************************************************************************************************************************************************************/
  15 +
  16 +#ifndef OSDEV_CAELUS_LOGUTILSLIBEXPORT_H
  17 +#define OSDEV_CAELUS_LOGUTILSLIBEXPORT_H
  18 +
  19 +#ifdef WIN32
  20 +
  21 +#ifdef LOGUTILSLIB
  22 +#define LOGUTILSLIBINTERFACE __declspec(dllexport)
  23 +#else
  24 +#define LOGUTILSLIBINTERFACE __declspec(dllimport)
  25 +#endif
  26 +
  27 +#else
  28 +#define LOGUTILSLIBINTERFACE
  29 +#endif
  30 +
  31 +
  32 +#endif
... ...
src/threadcontext.cpp 0 → 100644
  1 +++ a/src/threadcontext.cpp
  1 +/* **************************************************************************************************************************************************************************
  2 + * Copyright 2019 Open Systems Development BV *
  3 + * *
  4 + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), *
  5 + * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, *
  6 + * 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: *
  7 + * *
  8 + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. *
  9 + * *
  10 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
  11 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR *
  12 + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, *
  13 + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
  14 + * **************************************************************************************************************************************************************************/
  15 +
  16 +#include "threadcontext.h"
  17 +
  18 +// std
  19 +#include <thread>
  20 +
  21 +using namespace osdev::components;
  22 +
  23 +ThreadContextScope::ThreadContextScope(const QString& _context)
  24 + : m_previousContext(ThreadContext::instance().context())
  25 +{
  26 + ThreadContext::instance().setContext(_context);
  27 +}
  28 +
  29 +ThreadContextScope::~ThreadContextScope()
  30 +{
  31 + ThreadContext::instance().setContext(m_previousContext);
  32 +}
  33 +
  34 +// static
  35 +ThreadContext& ThreadContext::instance()
  36 +{
  37 + static thread_local ThreadContext tc;
  38 + return tc;
  39 +}
  40 +
  41 +ThreadContext::ThreadContext()
  42 + : m_context("default")
  43 +{
  44 +}
  45 +
... ...
src/threadcontext.h 0 → 100644
  1 +++ a/src/threadcontext.h
  1 +/* **************************************************************************************************************************************************************************
  2 + * Copyright 2019 Open Systems Development BV *
  3 + * *
  4 + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), *
  5 + * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, *
  6 + * 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: *
  7 + * *
  8 + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. *
  9 + * *
  10 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
  11 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR *
  12 + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, *
  13 + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
  14 + * **************************************************************************************************************************************************************************/
  15 +
  16 +#ifndef OSDEV_COMPONENTS_THREADCONTEXT_H
  17 +#define OSDEV_COMPONENTS_THREADCONTEXT_H
  18 +
  19 +// Qt
  20 +#include <QString>
  21 +
  22 +namespace osdev {
  23 +namespace components {
  24 +
  25 +/**
  26 + * @brief Set the current thread context.
  27 + * The context is restored to the previous context when this object goes out of scope.
  28 + * @note This object is meant to be used on the stack.
  29 + */
  30 +class ThreadContextScope
  31 +{
  32 +public:
  33 + /**
  34 + * @brief Construct a scoped object that sets the current thread context.
  35 + * @param context The context that will be used by the logging framework.
  36 + */
  37 + explicit ThreadContextScope(const QString& context);
  38 + ~ThreadContextScope();
  39 +
  40 + // Non copyable and non movable
  41 + ThreadContextScope(const ThreadContextScope&) = delete;
  42 + ThreadContextScope& operator=(const ThreadContextScope&) = delete;
  43 + ThreadContextScope(ThreadContextScope&&) = delete;
  44 + ThreadContextScope& operator=(ThreadContextScope&&) = delete;
  45 +
  46 +private:
  47 + QString m_previousContext; ///< Copy of the previous context.
  48 +};
  49 +
  50 +/**
  51 + * @brief Add context to a thread.
  52 + * For every thread only one specific instance of this object will exist.
  53 + * @note Contexts can only be set by using a ThreadContextScope object.
  54 + */
  55 +class ThreadContext
  56 +{
  57 +
  58 +// Contexts can only be set by using a ThreadContextScope object.
  59 +friend class ThreadContextScope;
  60 +
  61 +public:
  62 + static ThreadContext& instance();
  63 +
  64 + /**
  65 + * @brief Return the thread context.
  66 + */
  67 + const QString& context() const
  68 + {
  69 + return m_context;
  70 + }
  71 +
  72 +private:
  73 + /**
  74 + * @brief Set the thread context.
  75 + */
  76 + void setContext(const QString& contextString)
  77 + {
  78 + m_context = contextString;
  79 + }
  80 +
  81 + /**
  82 + * Construct a ThreadContext object.
  83 + * The context is set to "default"
  84 + */
  85 + ThreadContext();
  86 +
  87 + // Non copyable and non movable
  88 + ThreadContext(const ThreadContext&) = delete;
  89 + ThreadContext& operator=(const ThreadContext&) = delete;
  90 + ThreadContext(ThreadContext&&) = delete;
  91 + ThreadContext& operator=(ThreadContext&&) = delete;
  92 +
  93 + QString m_context; ///< The context string
  94 +};
  95 +
  96 +} /* End namespace components */
  97 +} /* End namespace osdev */
  98 +
  99 +#endif // OSDEV_COMPONENTS_THREADCONTEXT_H
... ...
tests/CMakeLists.txt 0 → 100644
  1 +++ a/tests/CMakeLists.txt
  1 +cmake_minimum_required(VERSION 3.0)
  2 +LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
  3 +
  4 +include(projectheader)
  5 +project_header(test_logutils)
  6 +
  7 +include_directories( SYSTEM
  8 + ${CMAKE_CURRENT_SOURCE_DIR}/../../src
  9 +)
  10 +
  11 +include(compiler)
  12 +set(SRC_LIST
  13 +)
  14 +
  15 +# add_executable( ${PROJECT_NAME}
  16 +# ${SRC_LIST}
  17 +# )
  18 +
  19 +# target_link_libraries(
  20 +# ${PROJECT_NAME}
  21 +# )
  22 +
  23 +# set_target_properties( ${PROJECT_NAME} PROPERTIES
  24 +# RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
  25 +# LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
  26 +# ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/archive
  27 +# )
  28 +
  29 +# include(installation)
  30 +# install_application()
... ...