From a59b5bbace7ed2de08da671251a43e0c0a885305 Mon Sep 17 00:00:00 2001 From: okaestne Date: Sun, 4 Sep 2022 21:58:50 +0200 Subject: [PATCH] feat: entry meta functions possibility to modify the metadata string of each Entry --- Log.cpp | 51 +++++++++++++++++++++++++++++++++------------------ Log.h | 19 ++++++++++++++++--- test.cpp | 10 ++++++++++ 3 files changed, 59 insertions(+), 21 deletions(-) diff --git a/Log.cpp b/Log.cpp index 0e5f14a..bc09104 100644 --- a/Log.cpp +++ b/Log.cpp @@ -137,31 +137,33 @@ void log(Level lvl, std::stringbuf* strb) { } } -LeveledSink fatal(Level::fatal); -LeveledSink error(Level::error); -LeveledSink warn(Level::warn); -LeveledSink note(Level::note); -LeveledSink info(Level::info); -LeveledSink debug(Level::debug); -LeveledSink trace(Level::trace); +LeveledSink fatal{Level::fatal}; +LeveledSink error{Level::error}; +LeveledSink warn{Level::warn}; +LeveledSink note{Level::note}; +LeveledSink info{Level::info}; +LeveledSink debug{Level::debug}; +LeveledSink trace{Level::trace}; /* * class Entry */ -Entry::Entry(Level lvl) : lvl(lvl) { - addMetadataHeader(); +Entry::Entry(Level lvl) : lvl{lvl} { + for(auto metafunc : entryMetaFunctions) { + metafunc(ss, *this); + } } Entry::~Entry() { log(lvl, ss.rdbuf()); } -void Entry::addMetadataHeader() { - static const char* LevelTag[] = {"", "[FATAL] ", "[ERROR] ", "[WARN ] ", - "[NOTE ] ", "[INFO ] ", "[DEBUG] ", "[TRACE] "}; +std::vector entryMetaFunctions; + +std::ostream& defaultEntryMetaTime(std::ostream& os, const Entry& e) { + (void) e; // unused - // datetime using namespace std::chrono; auto now = system_clock::to_time_t(system_clock::now()); auto tm = *std::localtime(&now); @@ -169,16 +171,31 @@ void Entry::addMetadataHeader() { // MinGW doesn't support the ISO8601 formatting characters like "%F" and "%T" // ref: https://sourceforge.net/p/mingw-w64/bugs/793/ // Therefore, use a more verbose time string - ss << "[" << std::put_time(&tm, "%Y-%m-%d %H:%M:%S") << "]"; + return os << "[" << std::put_time(&tm, "%Y-%m-%d %H:%M:%S") << "]"; +} - // log level - ss << LevelTag[static_cast(lvl)]; +std::ostream& defaultEntryMetaLevel(std::ostream& os, const Entry& e) { + static const char* LevelTag[] = { + "", "[FATAL]", "[ERROR]", "[WARN ]", "[NOTE ]", "[INFO ]", "[DEBUG]", "[TRACE]" + }; + return os << LevelTag[static_cast(e.getLevel())]; } void init() { // add default console logger if (outputs.empty()) outputs.push_back(new ConsoleOutput()); + + // set default entry metadata printing functions + auto space = [](std::ostream& os, const Entry& e) -> std::ostream& { + (void) e; + return os << ' '; + }; + entryMetaFunctions = { + defaultEntryMetaTime, + defaultEntryMetaLevel, + space + }; } void stop() { @@ -203,6 +220,4 @@ void setColoredOutput(bool enabled) { ((ConsoleOutput*) outputs.at(0))->setColoredOutput(enabled); // has to exist } -LeveledSink::LeveledSink(Level level) : level(level) {} - } // namespace Log \ No newline at end of file diff --git a/Log.h b/Log.h index c94b6fe..ffd2be9 100644 --- a/Log.h +++ b/Log.h @@ -1,7 +1,9 @@ #pragma once +#include #include // std::stringstream (buffer for log entries) #include +#include #ifndef LOG_USEMUTEX #define LOG_USEMUTEX 0 @@ -27,7 +29,7 @@ void setColoredOutput(bool enabled); class Entry { private: std::stringstream ss; - Level lvl; + const Level lvl; void addMetadataHeader(); @@ -36,21 +38,32 @@ public: Entry(Entry&&) = default; ~Entry(); + Level getLevel() const { + return lvl; + } + + using MetaFunction = std::function; + template Entry& operator<<(const T& msg) { ss << msg; return *this; } }; +extern std::vector entryMetaFunctions; + +std::ostream& defaultEntryMetaTime(std::ostream&, const Entry&); +std::ostream& defaultEntryMetaLevel(std::ostream&, const Entry&); + class LeveledSink { private: Level level; public: - LeveledSink(Level level); + LeveledSink(Level level) : level{level} {}; template Entry operator<<(const T& msg) { - Entry entry(level); + Entry entry{level}; entry << msg; return entry; } diff --git a/test.cpp b/test.cpp index 57804c6..5dacfde 100644 --- a/test.cpp +++ b/test.cpp @@ -44,6 +44,16 @@ int main() { // log streams + colors Log::setColoredOutput(true); Log::setConsoleLogLevel(Log::Level::trace); + + // add entry meta function + Log::entryMetaFunctions.insert( + Log::entryMetaFunctions.cend() - 1, + [](std::ostream& os, const Log::Entry& e) -> std::ostream& { + (void) e; + return os << "[banana]"; + } + ); + std::cout << "=== Log level debug ===" << std::endl; Log::trace << "trace msg @Lvl trace; " << 42 << "; " << 3.14159; Log::debug << "dbg msg @Lvl trace; " << 42 << "; " << 3.14159;