Created
March 12, 2024 16:16
-
-
Save ZanzyTHEbar/ef56acd3dbc3a7754d2000646cdd47d6 to your computer and use it in GitHub Desktop.
Logger using variadic templating
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <algorithm> | |
#include <fstream> | |
#include <iostream> | |
#include <sstream> | |
#include <string> | |
#include <utilities/helpers.hpp> | |
class Logger { | |
public: | |
enum LogLevel_e : uint8_t { DEBUG, INFO, WARN, ERROR, FATAL, NUM_LOG_LEVELS }; | |
protected: | |
std::string checkLogLevel(LogLevel_e log_level) { | |
static const std::array<std::string, NUM_LOG_LEVELS> logLevelStrings = { | |
"DEBUG", "INFO", "WARN", "ERROR", "FATAL"}; | |
if (log_level >= 0 && log_level < NUM_LOG_LEVELS) | |
return logLevelStrings[log_level]; | |
return "UNKNOWN"; | |
} | |
template <typename... Args> | |
std::string handleInput(Args... args) { | |
std::stringstream ss; | |
// Fold expression to concatenate arguments | |
(ss << ... << args); | |
std::string message = ss.str(); | |
return message; | |
} | |
virtual std::string getID() { return std::string(""); }; | |
public: | |
Logger() = default; | |
virtual ~Logger() = default; | |
template <typename... Args> | |
std::string format_string(const std::string& format, Args... args) { | |
int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + | |
1; // Extra space for '\0' | |
if (size_s <= 0) { | |
std::cout << "Error during formatting."; | |
return ""; | |
} | |
auto size = static_cast<size_t>(size_s); | |
std::unique_ptr<char[]> buf(new char[size]); | |
std::snprintf(buf.get(), size, format.c_str(), args...); | |
return std::string(buf.get(), | |
buf.get() + size - 1); // We don't want the '\0' inside | |
} | |
// Templated log function to handle various data types and arguments | |
template <typename... Args> | |
void log(LogLevel_e log_level, Args... args) { | |
std::string message = handleInput(args...); | |
std::string logLevel = checkLogLevel(log_level); | |
std::string logMessage = | |
format_string("[%s - %s]: %s", logLevel.c_str(), this->getID().c_str(), | |
message.c_str()); | |
std::cout << logMessage << '\n'; | |
} | |
template <typename... Args> | |
void log(Args... args) { | |
std::string message = handleInput(args...); | |
std::string logLevel = checkLogLevel(LogLevel_e::INFO); | |
std::string logMessage = | |
Helpers::format_string("[%s - %s]: %s", logLevel.c_str(), | |
this->getID().c_str(), message.c_str()); | |
std::cout << logMessage << '\n'; | |
} | |
}; | |
typedef Logger::LogLevel_e LogLevel_t; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment