diff --git a/src/Logger/Logger.cpp b/src/Logger/Logger.cpp index a51333c2..fa308de2 100644 --- a/src/Logger/Logger.cpp +++ b/src/Logger/Logger.cpp @@ -7,7 +7,7 @@ namespace Bloom void Logger::configure(ProjectConfig& projectConfig) { if (projectConfig.debugLoggingEnabled) { Logger::debugPrintingEnabled = true; - Logger::debug("Debug log printing has been enabled."); + Logger::debug("Debug log printing has been enabled"); } } @@ -18,54 +18,46 @@ namespace Bloom Logger::warningPrintingEnabled = false; } - void Logger::log(const std::string& message, LogLevel logLevel, bool print) { - auto lock = std::unique_lock(Logger::logMutex); - auto logEntry = LogEntry(message, logLevel); - Logger::logEntries.push_back(logEntry); - auto index = Logger::logEntries.size(); + void Logger::log(const LogEntry& logEntry) { static auto timezoneAbbreviation = DateTime::getTimeZoneAbbreviation(logEntry.timestamp).toStdString(); - if (print) { - // Print the timestamp and index in a green font color: - std::cout << "\033[32m"; - std::cout << logEntry.timestamp.toString("yyyy-MM-dd hh:mm:ss ").toStdString() - + timezoneAbbreviation; + const auto lock = std::unique_lock(Logger::printMutex); - if (!logEntry.threadName.empty()) { - std::cout << " [" << logEntry.threadName << "]"; - } + // Print the timestamp and id in a green font color: + std::cout << "\033[32m"; + std::cout << logEntry.timestamp.toString("yyyy-MM-dd hh:mm:ss ").toStdString() + + timezoneAbbreviation; - /* - * The index serves as an ID for each log entry. Just here for convenience when referencing specific - * log entries. - */ - std::cout << " [" << index << "]: "; - std::cout << "\033[0m"; - - switch (logLevel) { - case LogLevel::ERROR: { - // Errors in red - std::cout << "\033[31m"; - std::cout << "[ERROR] "; - break; - } - case LogLevel::WARNING: { - // Warnings in yellow - std::cout << "\033[33m"; - std::cout << "[WARNING] "; - break; - } - case LogLevel::INFO: { - std::cout << "[INFO] "; - break; - } - case LogLevel::DEBUG: { - std::cout << "[DEBUG] "; - break; - } - } - - std::cout << logEntry.message << "\033[0m" << std::endl; + if (!logEntry.threadName.empty()) { + std::cout << " [" << logEntry.threadName << "]"; } + + std::cout << " [" << logEntry.id << "]: "; + std::cout << "\033[0m"; + + switch (logEntry.logLevel) { + case LogLevel::ERROR: { + // Errors in red + std::cout << "\033[31m"; + std::cout << "[ERROR] "; + break; + } + case LogLevel::WARNING: { + // Warnings in yellow + std::cout << "\033[33m"; + std::cout << "[WARNING] "; + break; + } + case LogLevel::INFO: { + std::cout << "[INFO] "; + break; + } + case LogLevel::DEBUG: { + std::cout << "[DEBUG] "; + break; + } + } + + std::cout << logEntry.message << "\033[0m" << std::endl; } } diff --git a/src/Logger/Logger.hpp b/src/Logger/Logger.hpp index 124ff95b..c2ab29fc 100644 --- a/src/Logger/Logger.hpp +++ b/src/Logger/Logger.hpp @@ -1,37 +1,42 @@ #pragma once -#include -#include +#include #include -#include -#include #include +#include #include "src/ProjectConfig.hpp" #include "src/Helpers/DateTime.hpp" namespace Bloom { - enum class LogLevel + static_assert(std::atomic::is_always_lock_free); + + enum class LogLevel: std::uint8_t { - INFO = 1, - WARNING = 2, - ERROR = 3, - DEBUG = 4, + INFO, + WARNING, + ERROR, + DEBUG, }; - struct LogEntry + class LogEntry { - std::string threadName; + public: + std::uint32_t id = ++(LogEntry::lastLogId); std::string message; LogLevel logLevel; QDateTime timestamp = DateTime::currentDateTime(); + std::string threadName; - LogEntry(std::string message, LogLevel logLevel): message(std::move(message)), logLevel(logLevel) { + LogEntry(std::string message, LogLevel logLevel) + : message(std::move(message)) + , logLevel(logLevel) + { // Get thread name std::array threadNameBuf = {}; - if (pthread_getname_np(pthread_self(), threadNameBuf.data(), threadNameBuf.size()) == 0) { + if (::pthread_getname_np(::pthread_self(), threadNameBuf.data(), threadNameBuf.size()) == 0) { /* * The name of the main thread is also the name of the process, so we have to name the * main thread "Bloom" (to prevent confusion). @@ -43,12 +48,13 @@ namespace Bloom this->threadName = this->threadName == "Bloom" ? "MT" : this->threadName; } }; + + private: + static inline std::atomic lastLogId = 0; }; /** * Super simple thread safe static Logger class for basic logging. - * - * TODO: Add the ability to dump the logs to a file. */ class Logger { @@ -57,48 +63,38 @@ namespace Bloom static void silence(); - static void setInfoPrinting(bool enabled) { - Logger::infoPrintingEnabled = enabled; - } - - static void setWarningPrinting(bool enabled) { - Logger::warningPrintingEnabled = enabled; - } - - static void setErrorPrinting(bool enabled) { - Logger::errorPrintingEnabled = enabled; - } - static void info(const std::string& message) { - Logger::log(message, LogLevel::INFO, Logger::infoPrintingEnabled); + if (Logger::infoPrintingEnabled) { + Logger::log(LogEntry(message, LogLevel::INFO)); + } } static void warning(const std::string& message) { - Logger::log(message, LogLevel::WARNING, Logger::warningPrintingEnabled); + if (Logger::warningPrintingEnabled) { + Logger::log(LogEntry(message, LogLevel::WARNING)); + } } static void error(const std::string& message) { - Logger::log(message, LogLevel::ERROR, Logger::errorPrintingEnabled); + if (Logger::errorPrintingEnabled) { + Logger::log(LogEntry(message, LogLevel::ERROR)); + } } static void debug(const std::string& message) { - Logger::log(message, LogLevel::DEBUG, Logger::debugPrintingEnabled); + if (Logger::debugPrintingEnabled) { + Logger::log(LogEntry(message, LogLevel::DEBUG)); + } } private: - /** - * We keep a record of every log entry for future processing. Maybe dumping to a file or something - * of that nature when a fatal error occurs. - */ - static inline std::vector logEntries; - static inline bool errorPrintingEnabled = true; static inline bool warningPrintingEnabled = true; static inline bool infoPrintingEnabled = true; static inline bool debugPrintingEnabled = false; - static inline std::mutex logMutex; + static inline std::mutex printMutex; - static void log(const std::string& message, LogLevel logLevel, bool print); + static void log(const LogEntry& logEntry); }; }