Last active
March 24, 2025 01:38
-
-
Save Vivian-A/8a0bfc5292eeb9182bd8e1f069b01dc0 to your computer and use it in GitHub Desktop.
Really lightweight, header only, console, C++ logger
This file contains hidden or 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
#ifndef LUMBERJACK_H | |
#define LUMBERJACK_H | |
#include <iostream> | |
#include <sstream> | |
#include <mutex> | |
#include <string> | |
#include <ctime> | |
#include <iomanip> | |
enum class LogLevel { | |
TRACE, | |
DEBUG, | |
INFO, | |
WARN, | |
ERROR, | |
FATAL | |
}; | |
class lumberjack { | |
public: | |
inline static auto currentLevel = LogLevel::INFO; | |
inline static std::mutex logMutex; | |
inline static bool colorEnabled = true; | |
static void setLevel(const LogLevel level) { currentLevel = level; } | |
static LogLevel getLevel() { return currentLevel; } | |
static void enableColor() { colorEnabled = true; } | |
static void disableColor() { colorEnabled = false; } | |
template<typename... Args> | |
static void log(const LogLevel level, const Args&... args) { | |
if (level >= currentLevel) { | |
std::lock_guard lock(logMutex); | |
std::ostringstream stream; | |
// Timestamp | |
const auto t = std::time(nullptr); | |
const auto tm = *std::localtime(&t); | |
stream << std::put_time(&tm, "%H:%M:%S") << " "; | |
// Colored level tag | |
if (colorEnabled) { | |
switch(level) { | |
case LogLevel::TRACE: stream << "\033[37m"; break; | |
case LogLevel::DEBUG: stream << "\033[36m"; break; | |
case LogLevel::INFO: stream << "\033[32m"; break; | |
case LogLevel::WARN: stream << "\033[33m"; break; | |
case LogLevel::ERROR: stream << "\033[31m"; break; | |
case LogLevel::FATAL: stream << "\033[31;1m"; break; | |
} | |
} | |
stream << levelToString(level); | |
if (colorEnabled) { | |
stream << "\033[0m"; // Reset color | |
} | |
// Message | |
(stream << ... << args) << '\n'; | |
// Output | |
(level >= LogLevel::ERROR ? std::cerr : std::cout) << stream.str(); | |
} | |
} | |
lumberjack() = delete; | |
private: | |
static const char* levelToString(const LogLevel level) { | |
switch(level) { | |
case LogLevel::TRACE: return "[TRACE] "; | |
case LogLevel::DEBUG: return "[DEBUG] "; | |
case LogLevel::INFO: return "[INFO] "; | |
case LogLevel::WARN: return "[WARN] "; | |
case LogLevel::ERROR: return "[ERROR] "; | |
case LogLevel::FATAL: return "[FATAL] "; | |
default: return "[UNKNOWN] "; | |
} | |
} | |
}; | |
// Helper macros | |
#define LOG_TRACE(...) lumberjack::log(LogLevel::TRACE, __VA_ARGS__) | |
#define LOG_DEBUG(...) lumberjack::log(LogLevel::DEBUG, __VA_ARGS__) | |
#define LOG_INFO(...) lumberjack::log(LogLevel::INFO, __VA_ARGS__) | |
#define LOG_WARN(...) lumberjack::log(LogLevel::WARN, __VA_ARGS__) | |
#define LOG_ERROR(...) lumberjack::log(LogLevel::ERROR, __VA_ARGS__) | |
#define LOG_FATAL(...) lumberjack::log(LogLevel::FATAL, __VA_ARGS__) | |
#endif // LUMBERJACK_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Wrote this for my 3d engine, figured I might as well put it up.