Skip to content

Commit

Permalink
Merge pull request #15 from uPiscium/develop
Browse files Browse the repository at this point in the history
Fix logger interface and add example loggers.
  • Loading branch information
uPiscium authored Jul 1, 2024
2 parents ca21690 + 569713b commit 3ae2a9c
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 166 deletions.
2 changes: 1 addition & 1 deletion impls/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function(SetLibs)
endfunction()

function(Build)
add_library(${PROJECT_NAME} STATIC defines.cpp manager.cpp)
add_library(${PROJECT_NAME} STATIC loggers.cpp manager.cpp)
set_target_properties(
${PROJECT_NAME} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
Expand Down
30 changes: 0 additions & 30 deletions impls/defines.cpp

This file was deleted.

18 changes: 18 additions & 0 deletions impls/loggers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "../includes/loggers.hpp"

namespace TerreateLogger::Loggers {
using namespace TerreateLogger::Defines;

MultiLogger::~MultiLogger() {
for (auto &logger : loggers) {
delete logger.second;
}
}

void MultiLogger::Log(Str const &log) {
for (auto &logger : loggers) {
logger.second->Log(log);
}
}

} // namespace TerreateLogger::Loggers
37 changes: 14 additions & 23 deletions impls/manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,29 @@
namespace TerreateLogger::Manager {
using namespace TerreateLogger::Defines;

LoggerManager &GetManager() {
static LoggerManager manager;
return manager;
}

LoggerManager::~LoggerManager() {
for (auto logger : mLoggers) {
delete logger;
for (auto &logger : mLoggers) {
delete logger.second;
}
}

Vec<ILogger *> const &LoggerManager::AcquireLoggers() {
LoggerManager &manager = GetManager();
return manager.GetLoggers();
}

void LoggerManager::Log(LogData const &log) {
LoggerManager &manager = GetManager();
for (auto logger : manager.GetLoggers()) {
logger->Log(log);
ILogger *LoggerManager::GetLogger(Str const &loggerName) {
auto logger = mLoggers.find(loggerName);
if (logger != mLoggers.end()) {
return logger->second;
}
return nullptr;
}

void LoggerManager::Dump(Str const &path) {
LoggerManager &manager = GetManager();
for (auto logger : manager.GetLoggers()) {
logger->Dump(path);
void LoggerManager::AddLog(Str const &log) {
for (auto &logger : mLoggers) {
logger.second->Log(log);
}
}

void LoggerManager::Register(ILogger *logger) {
LoggerManager &manager = GetManager();
manager.mLoggers.push_back(logger);
LoggerManager &LoggerManager::AcquireManager() {
static LoggerManager manager;
return manager;
}

} // namespace TerreateLogger::Manager
68 changes: 36 additions & 32 deletions includes/ILogger.hpp
Original file line number Diff line number Diff line change
@@ -1,49 +1,53 @@
#ifndef __TL_LOGGER_BASE_HPP__
#define __TL_LOGGER_BASE_HPP__
#ifndef __TL_LOGGER_HPP__
#define __TL_LOGGER_HPP__

#include "defines.hpp"

namespace TerreateLogger::Base {
namespace TerreateLogger::Interface {
using namespace TerreateLogger::Defines;

class ILogger {
private:
using LogFunc = Func<LogData(LogData const &)>;

protected:
Vec<LogData> mLogs;
LogFunc mCriticalCallback;
LogFunc mErrorCallback;
LogFunc mWarningCallback;
LogFunc mInfoCallback;
LogFunc mDebugCallback;
LogFunc mTraceCallback;
Str mLoggerName = "";

private:
ILogger(ILogger const &) = delete;
ILogger &operator=(ILogger const &) = delete;

public:
ILogger() {}
virtual ~ILogger() {}

virtual Vec<LogData> const &GetLogs() const { return mLogs; }

virtual void SetCriticalCallback(LogFunc callback) {
mCriticalCallback = callback;
}
virtual void SetErrorCallback(LogFunc callback) { mErrorCallback = callback; }
virtual void SetWarningCallback(LogFunc callback) {
mWarningCallback = callback;
/*
* @brief: Default constructor
* @note: Logger name is empty by default
*/
ILogger() = default;
/*
* @brief: Constructor with logger name
* @param: name: Logger name
*/
ILogger(Str const &name) { this->SetLoggerName(name); }
virtual ~ILogger() = default;

/*
* @brief: Get logger name
* @return: Logger name
*/
virtual Str GetLoggerName() const { return mLoggerName; }

/*
* @brief: Set logger name
* @param: loggerName: Logger name
*/
virtual void SetLoggerName(Str const &loggerName) {
mLoggerName = loggerName;
}
virtual void SetInfoCallback(LogFunc callback) { mInfoCallback = callback; }
virtual void SetDebugCallback(LogFunc callback) { mDebugCallback = callback; }
virtual void SetTraceCallback(LogFunc callback) { mTraceCallback = callback; }

virtual void Log(LogData const &log) = 0;
virtual void Dump(Str const &path) = 0;
/*
* @brief: Log message
* @param: log: Log message
* @note: Pure virtual function. You must implement this function in derived
*/
virtual void Log(Str const &log) = 0;
};
} // namespace TerreateLogger::Interface

} // namespace TerreateLogger::Base

#endif // __TL_LOGGER_BASE_HPP__
#endif // __TL_LOGGER_HPP__
1 change: 1 addition & 0 deletions includes/TerreateLogger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "ILogger.hpp"
#include "defines.hpp"
#include "loggers.hpp"
#include "manager.hpp"

#endif // __TERREATE_LOGGER_HPP__
31 changes: 6 additions & 25 deletions includes/defines.hpp
Original file line number Diff line number Diff line change
@@ -1,37 +1,18 @@
#ifndef __TL_DEFINES_HPP__
#define __TL_DEFINES_HPP__

#include <functional>
#include <iostream>
#include <cstdint>
#include <string>
#include <unordered_map>
#include <vector>

namespace TerreateLogger::Defines {

using Uint = unsigned int;
using Str = std::string;
// STL types
typedef uint64_t Uint64;
typedef std::string Str;
template <typename T> using Vec = std::vector<T>;
template <typename T> using Func = std::function<T>;

enum class LogLevel { CRITICAL, ERROR, WARNING, INFO, DEBUG, TRACE };

Str LogLevelToString(LogLevel const &level);

struct LogData {
LogLevel level;
Str file;
Str func;
Uint line;
Str msg;
};

#define TLLOG(level, msg) \
TerreateLogger::Defines::LogData { \
level, Str(__FILE__), Str(__func__), __LINE__, msg \
}
template <typename K, typename V> using Map = std::unordered_map<K, V>;

} // namespace TerreateLogger::Defines

std::ostream &operator<<(std::ostream &stream,
TerreateLogger::Defines::LogData const &log);
#endif // __TL_DEFINES_HPP__
71 changes: 71 additions & 0 deletions includes/loggers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifndef __TL_LOGGERS_HPP__
#define __TL_LOGGERS_HPP__

#include <fstream>
#include <iostream>

#include "ILogger.hpp"
#include "defines.hpp"

namespace TerreateLogger::Loggers {
using namespace TerreateLogger::Defines;
using namespace TerreateLogger::Interface;

class MultiLogger : public ILogger {
protected:
Map<Str, ILogger *> loggers;

private:
MultiLogger(MultiLogger const &) = delete;
MultiLogger &operator=(MultiLogger const &) = delete;

public:
MultiLogger() = default;
MultiLogger(Str const &name) : ILogger(name) {}
virtual ~MultiLogger() override;

void AddLogger(Str const &name, ILogger *logger) { loggers[name] = logger; }
void RemoveLogger(Str const &name) { loggers.erase(name); }

virtual void Log(Str const &message) override;
};

class ConsoleLogger : public ILogger {
private:
ConsoleLogger(ConsoleLogger const &) = delete;
ConsoleLogger &operator=(ConsoleLogger const &) = delete;

public:
ConsoleLogger() = default;
ConsoleLogger(Str const &name) : ILogger(name) {}
virtual ~ConsoleLogger() override {}

virtual void Log(Str const &message) override {
std::cout << message << std::endl;
}
};

class FileLogger : public ILogger {
protected:
std::ofstream mFile;

private:
FileLogger(FileLogger const &) = delete;
FileLogger &operator=(FileLogger const &) = delete;

public:
FileLogger(Str const &name) : ILogger(name) {
mFile.open((name + ".txt").c_str(), std::ios::app);
}
FileLogger(Str const &name, Str const &filename) : ILogger(name) {
mFile.open(filename, std::ios::app);
}
virtual ~FileLogger() override {}

virtual void Log(Str const &message) override {
mFile << message << std::endl;
}
};
} // namespace TerreateLogger::Loggers

#endif // __TL_LOGGERS_HPP__
47 changes: 35 additions & 12 deletions includes/manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,51 @@

namespace TerreateLogger::Manager {
using namespace TerreateLogger::Defines;
using namespace TerreateLogger::Base;
using namespace TerreateLogger::Interface;

class LoggerManager {
private:
friend LoggerManager &GetManager();

Vec<ILogger *> mLoggers;
Map<Str, ILogger *> mLoggers;

private:
LoggerManager() {}
~LoggerManager();
LoggerManager(LoggerManager const &) = delete;
LoggerManager &operator=(LoggerManager const &) = delete;

public:
Vec<ILogger *> const &GetLoggers() const { return mLoggers; }
private:
/*
* @brief: Construct a new LoggerManager object
*/
LoggerManager() = default;
~LoggerManager();

/*
* @brief: Get the Logger object
* @param: loggerName: Logger name to get
* @return: ILogger* / nullptr (if not found)
*/
ILogger *GetLogger(Str const &loggerName);

/*
* @brief: Add a logger to the manager
* @param: logger: ILogger object to add
* @note: This function will take ownership of the logger so DO NOT delete it
* by yourself after adding it to the manager
*/
void AddLogger(ILogger *logger) {
mLoggers[logger->GetLoggerName()] = logger;
}
/*
* @brief: Log a message to all loggers
* @param: log: Message to log
*/
void AddLog(Str const &log);

public:
static Vec<ILogger *> const &AcquireLoggers();
static void Log(LogData const &log);
static void Dump(Str const &path);
static void Register(ILogger *logger);
static LoggerManager &AcquireManager();
static void Register(ILogger *logger) { AcquireManager().AddLogger(logger); }
static void Log(Str const &log) { AcquireManager().AddLog(log); }
};

} // namespace TerreateLogger::Manager

#endif // __TL_MANAGER_HPP__
Loading

0 comments on commit 3ae2a9c

Please sign in to comment.