Tidied Logger
This commit is contained in:
@@ -7,7 +7,7 @@ namespace Bloom
|
|||||||
void Logger::configure(ProjectConfig& projectConfig) {
|
void Logger::configure(ProjectConfig& projectConfig) {
|
||||||
if (projectConfig.debugLoggingEnabled) {
|
if (projectConfig.debugLoggingEnabled) {
|
||||||
Logger::debugPrintingEnabled = true;
|
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;
|
Logger::warningPrintingEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::log(const std::string& message, LogLevel logLevel, bool print) {
|
void Logger::log(const LogEntry& logEntry) {
|
||||||
auto lock = std::unique_lock(Logger::logMutex);
|
|
||||||
auto logEntry = LogEntry(message, logLevel);
|
|
||||||
Logger::logEntries.push_back(logEntry);
|
|
||||||
auto index = Logger::logEntries.size();
|
|
||||||
static auto timezoneAbbreviation = DateTime::getTimeZoneAbbreviation(logEntry.timestamp).toStdString();
|
static auto timezoneAbbreviation = DateTime::getTimeZoneAbbreviation(logEntry.timestamp).toStdString();
|
||||||
|
|
||||||
if (print) {
|
const auto lock = std::unique_lock(Logger::printMutex);
|
||||||
// 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;
|
|
||||||
|
|
||||||
if (!logEntry.threadName.empty()) {
|
// Print the timestamp and id in a green font color:
|
||||||
std::cout << " [" << logEntry.threadName << "]";
|
std::cout << "\033[32m";
|
||||||
}
|
std::cout << logEntry.timestamp.toString("yyyy-MM-dd hh:mm:ss ").toStdString()
|
||||||
|
+ timezoneAbbreviation;
|
||||||
|
|
||||||
/*
|
if (!logEntry.threadName.empty()) {
|
||||||
* The index serves as an ID for each log entry. Just here for convenience when referencing specific
|
std::cout << " [" << logEntry.threadName << "]";
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,42 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <cstdint>
|
||||||
#include <map>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
|
||||||
#include <QTimeZone>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
#include "src/ProjectConfig.hpp"
|
#include "src/ProjectConfig.hpp"
|
||||||
#include "src/Helpers/DateTime.hpp"
|
#include "src/Helpers/DateTime.hpp"
|
||||||
|
|
||||||
namespace Bloom
|
namespace Bloom
|
||||||
{
|
{
|
||||||
enum class LogLevel
|
static_assert(std::atomic<std::uint32_t>::is_always_lock_free);
|
||||||
|
|
||||||
|
enum class LogLevel: std::uint8_t
|
||||||
{
|
{
|
||||||
INFO = 1,
|
INFO,
|
||||||
WARNING = 2,
|
WARNING,
|
||||||
ERROR = 3,
|
ERROR,
|
||||||
DEBUG = 4,
|
DEBUG,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LogEntry
|
class LogEntry
|
||||||
{
|
{
|
||||||
std::string threadName;
|
public:
|
||||||
|
std::uint32_t id = ++(LogEntry::lastLogId);
|
||||||
std::string message;
|
std::string message;
|
||||||
LogLevel logLevel;
|
LogLevel logLevel;
|
||||||
QDateTime timestamp = DateTime::currentDateTime();
|
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
|
// Get thread name
|
||||||
std::array<char, 16> threadNameBuf = {};
|
std::array<char, 16> 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
|
* 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).
|
* main thread "Bloom" (to prevent confusion).
|
||||||
@@ -43,12 +48,13 @@ namespace Bloom
|
|||||||
this->threadName = this->threadName == "Bloom" ? "MT" : this->threadName;
|
this->threadName = this->threadName == "Bloom" ? "MT" : this->threadName;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
static inline std::atomic<std::uint32_t> lastLogId = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Super simple thread safe static Logger class for basic logging.
|
* Super simple thread safe static Logger class for basic logging.
|
||||||
*
|
|
||||||
* TODO: Add the ability to dump the logs to a file.
|
|
||||||
*/
|
*/
|
||||||
class Logger
|
class Logger
|
||||||
{
|
{
|
||||||
@@ -57,48 +63,38 @@ namespace Bloom
|
|||||||
|
|
||||||
static void silence();
|
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) {
|
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) {
|
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) {
|
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) {
|
static void debug(const std::string& message) {
|
||||||
Logger::log(message, LogLevel::DEBUG, Logger::debugPrintingEnabled);
|
if (Logger::debugPrintingEnabled) {
|
||||||
|
Logger::log(LogEntry(message, LogLevel::DEBUG));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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<LogEntry> logEntries;
|
|
||||||
|
|
||||||
static inline bool errorPrintingEnabled = true;
|
static inline bool errorPrintingEnabled = true;
|
||||||
static inline bool warningPrintingEnabled = true;
|
static inline bool warningPrintingEnabled = true;
|
||||||
static inline bool infoPrintingEnabled = true;
|
static inline bool infoPrintingEnabled = true;
|
||||||
static inline bool debugPrintingEnabled = false;
|
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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user