From c85d997021d8fb8fb416aa428b3cea291a019820 Mon Sep 17 00:00:00 2001 From: Manuel Dobusch Date: Mon, 7 Apr 2014 14:44:54 +0200 Subject: [PATCH] Utility: Logging Added logging utility classes supposed to be used for all your logging needs, e.g. instead of cout reviewer=ebsi --- src/lib/CMakeLists.txt | 11 +- src/lib/utility/logging/LogManager.cpp | 103 ++++++++++++++ src/lib/utility/logging/LogManager.h | 53 +++++++ src/lib/utility/logging/LogMessage.h | 31 +++++ src/lib/utility/logging/Logger.cpp | 15 ++ src/lib/utility/logging/Logger.h | 26 ++++ src/lib/utility/logging/logging.h | 33 +++++ src/test/CMakeLists.txt | 2 + src/test/LogManagerTestSuite.h | 183 +++++++++++++++++++++++++ 9 files changed, 455 insertions(+), 2 deletions(-) create mode 100644 src/lib/utility/logging/LogManager.cpp create mode 100644 src/lib/utility/logging/LogManager.h create mode 100644 src/lib/utility/logging/LogMessage.h create mode 100644 src/lib/utility/logging/Logger.cpp create mode 100644 src/lib/utility/logging/Logger.h create mode 100644 src/lib/utility/logging/logging.h create mode 100644 src/test/LogManagerTestSuite.h diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index b7b60dff..5e6a34ee 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -54,10 +54,17 @@ add_files( gui/GuiElement.h gui/GuiElementFactory.cpp gui/GuiElementFactory.h - + + utility/logging/Logger.cpp + utility/logging/Logger.h + utility/logging/logging.h + utility/logging/LogManager.cpp + utility/logging/LogManager.h + utility/logging/LogMessage.h + utility/ConfigManager.cpp utility/ConfigManager.h - + Application.cpp Application.h ApplicationSettings.cpp diff --git a/src/lib/utility/logging/LogManager.cpp b/src/lib/utility/logging/LogManager.cpp new file mode 100644 index 00000000..c60bdbda --- /dev/null +++ b/src/lib/utility/logging/LogManager.cpp @@ -0,0 +1,103 @@ +#include "utility/logging/LogManager.h" +#include "utility/logging/LogMessage.h" + +std::shared_ptr LogManager::getInstance() +{ + if (s_instance.use_count() == 0) + { + s_instance = std::shared_ptr(new LogManager()); + } + return s_instance; +} + +void LogManager::destroyInstance() +{ + s_instance.reset(); +} + +LogManager::~LogManager() +{ +} + +void LogManager::addLogger(std::shared_ptr logger) +{ + m_loggers.push_back(logger); +} + +void LogManager::removeLogger(std::shared_ptr logger) +{ + std::vector>::iterator it = std::find(m_loggers.begin(), m_loggers.end(), logger); + if (it != m_loggers.end()) + { + m_loggers.erase(it); + } +} + +void LogManager::removeLoggersByType(const std::string& type) +{ + for (int i = 0; i < m_loggers.size(); i++) + { + if (m_loggers[i]->getType().c_str() == type.c_str()) + { + m_loggers.erase(m_loggers.begin() + i); + i--; + } + } +} + +int LogManager::getLoggerCount() const +{ + return m_loggers.size(); +} + +void LogManager::logInfo( + const std::string& message, + const std::string& file, + const std::string& function, + const unsigned int line +) +{ + for (int i = 0; i < m_loggers.size(); i++) + { + m_loggers[i]->logInfo(LogMessage(message, file, function, line, getTime())); + } +} + +void LogManager::logWarning( + const std::string& message, + const std::string& file, + const std::string& function, + const unsigned int line +) +{ + for (int i = 0; i < m_loggers.size(); i++) + { + m_loggers[i]->logWarning(LogMessage(message, file, function, line, getTime())); + } +} + +void LogManager::logError( + const std::string& message, + const std::string& file, + const std::string& function, + const unsigned int line +) +{ + for (int i = 0; i < m_loggers.size(); i++) + { + m_loggers[i]->logError(LogMessage(message, file, function, line, getTime())); + } +} + +std::shared_ptr LogManager::s_instance; + +LogManager::LogManager() +{ +} + +tm LogManager::getTime() +{ + time_t time; + std::time(&time); + return *std::localtime(&time); +} diff --git a/src/lib/utility/logging/LogManager.h b/src/lib/utility/logging/LogManager.h new file mode 100644 index 00000000..6d0fe2b5 --- /dev/null +++ b/src/lib/utility/logging/LogManager.h @@ -0,0 +1,53 @@ +#ifndef LOG_MANAGER_H +#define LOG_MANAGER_H + +#include +#include + +#include "utility/logging/Logger.h" + +class LogManager +{ +public: + static std::shared_ptr getInstance(); + static void destroyInstance(); + + ~LogManager(); + + void addLogger(std::shared_ptr logger); + void removeLogger(std::shared_ptr logger); + void removeLoggersByType(const std::string& type); + int getLoggerCount() const; + + void logInfo( + const std::string& message, + const std::string& file, + const std::string& function, + const unsigned int line + ); + void logWarning( + const std::string& message, + const std::string& file, + const std::string& function, + const unsigned int line + ); + void logError( + const std::string& message, + const std::string& file, + const std::string& function, + const unsigned int line + ); + +private: + static std::shared_ptr s_instance; + + LogManager(); + LogManager(const LogManager&); + void operator=(const LogManager&); + + tm getTime(); + + std::vector > m_loggers; +}; + +#endif // LOG_MANAGER_H diff --git a/src/lib/utility/logging/LogMessage.h b/src/lib/utility/logging/LogMessage.h new file mode 100644 index 00000000..44da8c5d --- /dev/null +++ b/src/lib/utility/logging/LogMessage.h @@ -0,0 +1,31 @@ +#ifndef LOG_MESSAGE_H +#define LOG_MESSAGE_H + +#include +#include + +struct LogMessage +{ +public: + LogMessage( + const std::string& message, + const std::string& fileName, + const std::string& functionName, + const unsigned int line, + const std::tm& time + ) + : message(message) + , fileName(fileName) + , functionName(functionName) + , line(line) + , time(time) + {} + + const std::string message; + const std::string fileName; + const std::string functionName; + const unsigned int line; + const std::tm time; +}; + +#endif // LOG_MESSAGE_H \ No newline at end of file diff --git a/src/lib/utility/logging/Logger.cpp b/src/lib/utility/logging/Logger.cpp new file mode 100644 index 00000000..575f2242 --- /dev/null +++ b/src/lib/utility/logging/Logger.cpp @@ -0,0 +1,15 @@ +#include "utility/logging/Logger.h" + +Logger::Logger(const std::string& type) + : m_type(type) +{ +} + +Logger::~Logger() +{ +} + +std::string Logger::getType() const +{ + return m_type; +} diff --git a/src/lib/utility/logging/Logger.h b/src/lib/utility/logging/Logger.h new file mode 100644 index 00000000..4106a255 --- /dev/null +++ b/src/lib/utility/logging/Logger.h @@ -0,0 +1,26 @@ +#ifndef LOGGER_H +#define LOGGER_H + +#include +#include + +#include "utility/logging/LogMessage.h" + +class Logger +{ +public: + Logger(const std::string& type); + virtual ~Logger(); + + std::string getType() const; + + virtual void logInfo(const LogMessage& message) = 0; + virtual void logWarning(const LogMessage& message) = 0; + virtual void logError(const LogMessage& message) = 0; + +private: + const std::string m_type; +}; + + +#endif diff --git a/src/lib/utility/logging/logging.h b/src/lib/utility/logging/logging.h new file mode 100644 index 00000000..10008c60 --- /dev/null +++ b/src/lib/utility/logging/logging.h @@ -0,0 +1,33 @@ +#ifndef LOGGING_H +#define LOGGING_H + +#include "utility/logging/LogManager.h" + +/** +* @brief Makros to simplify usage of the log manager +*/ +#define LOG_INFO(str) \ + do \ + { \ + std::string s((str)); \ + LogManager::getInstance()->logInfo(s, __FILE__, __FUNCTION__, __LINE__); \ + } \ + while(0) \ + +#define LOG_WARNING(str) \ + do \ + { \ + std::string s((str)); \ + LogManager::getInstance()->logWarning(s, __FILE__, __FUNCTION__, __LINE__); \ + } \ + while(0) \ + +#define LOG_ERROR(str) \ + do \ + { \ + std::string s((str)); \ + LogManager::getInstance()->logError(s, __FILE__, __FUNCTION__, __LINE__); \ + } \ + while(0) \ + +#endif // LOGGING_H diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 394872aa..913d3b51 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -1,5 +1,7 @@ add_files( TEST_FILES + ConfigManagerTestSuite.h + LogManagerTestSuite.h UtilityTestSuite.h ) diff --git a/src/test/LogManagerTestSuite.h b/src/test/LogManagerTestSuite.h new file mode 100644 index 00000000..db1cd272 --- /dev/null +++ b/src/test/LogManagerTestSuite.h @@ -0,0 +1,183 @@ +#include "cxxtest/TestSuite.h" + +#include "utility/logging/logging.h" + +class LogManagerTestSuite : public CxxTest::TestSuite +{ +public: + void test_new_logger_can_be_added_to_manager() + { + std::shared_ptr logger = std::make_shared(); + + int countBeforeAdd = LogManager::getInstance()->getLoggerCount(); + LogManager::getInstance()->addLogger(logger); + int countAfterAdd = LogManager::getInstance()->getLoggerCount(); + LogManager::getInstance()->removeLogger(logger); + + TS_ASSERT_EQUALS(1, countAfterAdd - countBeforeAdd); + } + + void test_logger_can_be_removed_from_manager() + { + std::shared_ptr logger = std::make_shared(); + + int countBeforeAdd = LogManager::getInstance()->getLoggerCount(); + LogManager::getInstance()->addLogger(logger); + LogManager::getInstance()->removeLogger(logger); + int countAfterRemove = LogManager::getInstance()->getLoggerCount(); + + TS_ASSERT_EQUALS(countBeforeAdd, countAfterRemove); + } + + void test_logger_logs_message() + { + std::string log = "test"; + std::shared_ptr logger = std::make_shared(); + + LogManager::getInstance()->addLogger(logger); + + LOG_INFO(log); + int logCount = logger->getMessageCount(); + std::string lastLog = logger->getLastMessage(); + + LogManager::getInstance()->removeLogger(logger); + + TS_ASSERT_EQUALS(1, logCount); + TS_ASSERT_EQUALS(log, lastLog); + } + + void test_logger_logs_warning() + { + std::string log = "test"; + std::shared_ptr logger = std::make_shared(); + + LogManager::getInstance()->addLogger(logger); + + LOG_WARNING(log); + int logCount = logger->getWarningCount(); + std::string lastLog = logger->getLastWarning(); + + LogManager::getInstance()->removeLogger(logger); + + TS_ASSERT_EQUALS(1, logCount); + TS_ASSERT_EQUALS(log, lastLog); + } + + void test_logger_logs_error() + { + std::string log = "test"; + std::shared_ptr logger = std::make_shared(); + + LogManager::getInstance()->addLogger(logger); + + LOG_ERROR(log); + int logCount = logger->getErrorCount(); + std::string lastLog = logger->getLastError(); + + LogManager::getInstance()->removeLogger(logger); + + TS_ASSERT_EQUALS(1, logCount); + TS_ASSERT_EQUALS(log, lastLog); + } + +private: + class TestLogger: public Logger + { + public: + TestLogger(); + ~TestLogger(); + + void reset(); + int getMessageCount() const; + int getWarningCount() const; + int getErrorCount() const; + + std::string getLastMessage() const; + std::string getLastWarning() const; + std::string getLastError() const; + + void logInfo(const LogMessage& message); + void logWarning(const LogMessage& message); + void logError(const LogMessage& message); + + private: + int m_logMessageCount; + int m_logWarningCount; + int m_logErrorCount; + + std::string m_lastMessage; + std::string m_lastWarning; + std::string m_lastError; + }; +}; + + +LogManagerTestSuite::TestLogger::TestLogger() + : Logger("TestLogger") + , m_logMessageCount(0) + , m_logWarningCount(0) + , m_logErrorCount(0) + , m_lastMessage("") + , m_lastWarning("") + , m_lastError("") +{ +} + +LogManagerTestSuite::TestLogger::~TestLogger() +{ +} + +void LogManagerTestSuite::TestLogger::reset() +{ + m_logMessageCount = 0; + m_logWarningCount = 0; + m_logErrorCount = 0; +} + +int LogManagerTestSuite::TestLogger::getMessageCount() const +{ + return m_logMessageCount; +} + +int LogManagerTestSuite::TestLogger::getWarningCount() const +{ + return m_logWarningCount; +} + +int LogManagerTestSuite::TestLogger::getErrorCount() const +{ + return m_logErrorCount; +} + +std::string LogManagerTestSuite::TestLogger::getLastMessage() const +{ + return m_lastMessage; +} + +std::string LogManagerTestSuite::TestLogger::getLastWarning() const +{ + return m_lastWarning; +} + +std::string LogManagerTestSuite::TestLogger::getLastError() const +{ + return m_lastError; +} + +void LogManagerTestSuite::TestLogger::logInfo(const LogMessage& message) +{ + m_lastMessage = message.message; + m_logMessageCount++; +} + +void LogManagerTestSuite::TestLogger::logWarning(const LogMessage& message) +{ + m_lastWarning = message.message; + m_logWarningCount++; +} + +void LogManagerTestSuite::TestLogger::logError(const LogMessage& message) +{ + m_lastError = message.message; + m_logErrorCount++; +}