feat: entry meta functions
possibility to modify the metadata string of each Entry
This commit is contained in:
parent
6ecbc406d7
commit
a59b5bbace
51
Log.cpp
51
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<Entry::MetaFunction> 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<int>(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<int>(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
|
19
Log.h
19
Log.h
|
@ -1,7 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <sstream> // std::stringstream (buffer for log entries)
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<std::ostream&(std::ostream&, const Entry&)>;
|
||||
|
||||
template <typename T> Entry& operator<<(const T& msg) {
|
||||
ss << msg;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
extern std::vector<Entry::MetaFunction> 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 <typename T> Entry operator<<(const T& msg) {
|
||||
Entry entry(level);
|
||||
Entry entry{level};
|
||||
entry << msg;
|
||||
return entry;
|
||||
}
|
||||
|
|
10
test.cpp
10
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;
|
||||
|
|
Loading…
Reference in New Issue