WIP
This commit is contained in:
parent
a5e52072fe
commit
762cc48220
|
@ -0,0 +1,141 @@
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
class Log
|
||||||
|
*/
|
||||||
|
|
||||||
|
// static member
|
||||||
|
std::vector<Log::Output*> Log::outputs;
|
||||||
|
|
||||||
|
void Log::init() {
|
||||||
|
// add default console logger
|
||||||
|
if (outputs.empty())
|
||||||
|
outputs.push_back(new Log::ConsoleOutput());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::stop() {
|
||||||
|
for (auto output : outputs)
|
||||||
|
delete output;
|
||||||
|
outputs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::addLogfile(const std::string& filename, Level max) {
|
||||||
|
outputs.push_back(new Log::FileOutput(filename, max));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::addLogfile(const std::string& filename, Level min, Level max) {
|
||||||
|
outputs.push_back(new Log::FileOutput(filename, min, max));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::setConsoleLogLevel(Level lvl) {
|
||||||
|
outputs.at(0)->setLogLevel(lvl); // has to exist
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::setColoredOutput(bool enabled) {
|
||||||
|
((Log::ConsoleOutput*) outputs.at(0))->setColoredOutput(enabled); // has to exist
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::log(Level lvl, std::stringbuf* strb) {
|
||||||
|
for (Output* out : outputs) {
|
||||||
|
out->log(lvl, strb);
|
||||||
|
// reset stringbuffer read pointer to the beginning
|
||||||
|
strb->pubseekpos(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* abstract class Output
|
||||||
|
* default implementations
|
||||||
|
*/
|
||||||
|
|
||||||
|
Log::Output::Output() {}
|
||||||
|
Log::Output::Output(Log::Level lvl_max) : lvl_max(lvl_max) {}
|
||||||
|
Log::Output::~Output() {}
|
||||||
|
|
||||||
|
void Log::Output::log(Log::Level lvl, std::stringbuf* sbuf) {
|
||||||
|
std::ostream* os = getOs(lvl);
|
||||||
|
if (os) {
|
||||||
|
printLogHeader(os, lvl);
|
||||||
|
*os << sbuf << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::Output::setLogLevel(Log::Level lvl) {
|
||||||
|
lvl_max = lvl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::Output::printLogHeader(std::ostream* os, Level lvl) {
|
||||||
|
static const char* LevelTag[] = {"", "[FATAL] ", "[ERROR] ", "[WARN ] ",
|
||||||
|
"[NOTE ] ", "[INFO ] ", "[DEBUG] ", "[TRACE] "};
|
||||||
|
|
||||||
|
// get current date/time
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
|
||||||
|
|
||||||
|
*os << "[" << std::put_time(std::localtime(&now_c), "%F %T") << "]" << LevelTag[lvl];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* class ConsoleOutput
|
||||||
|
*/
|
||||||
|
|
||||||
|
Log::ConsoleOutput::ConsoleOutput() : Output() {}
|
||||||
|
|
||||||
|
bool Log::ConsoleOutput::setColoredOutput(bool enabled) {
|
||||||
|
// TODO: check the terminals compatibility for colors
|
||||||
|
coloredOutput = enabled;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::ConsoleOutput::log(Log::Level lvl, std::stringbuf* sbuf) {
|
||||||
|
static const char* esc_seq_start = "\033[";
|
||||||
|
static const char* esc_seq_reset = "\033[0m";
|
||||||
|
// OFF FATAL ERROR WARN NOTE INFO DEBUG TRACE
|
||||||
|
static const char* color_codes[] = {"", "1;31;40m", "31m", "33m", "96m", "32m", "0m", "0m"};
|
||||||
|
|
||||||
|
std::ostream* os = getOs(lvl);
|
||||||
|
|
||||||
|
if (os) {
|
||||||
|
// print colors if enabled
|
||||||
|
if (coloredOutput)
|
||||||
|
*os << esc_seq_start << color_codes[lvl];
|
||||||
|
|
||||||
|
Output::printLogHeader(os, lvl);
|
||||||
|
*os << sbuf;
|
||||||
|
|
||||||
|
// reset color at end of the line
|
||||||
|
if (coloredOutput)
|
||||||
|
*os << esc_seq_reset;
|
||||||
|
|
||||||
|
*os << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream* Log::ConsoleOutput::getOs(Log::Level lvl) {
|
||||||
|
// out of scope?
|
||||||
|
if (!lvl || lvl > lvl_max)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// stderr for FATAL, ERROR, WARN
|
||||||
|
if (lvl <= Log::Level::WARN)
|
||||||
|
return osErr;
|
||||||
|
else
|
||||||
|
return osStd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* class FileOutput
|
||||||
|
* logging to file
|
||||||
|
*/
|
||||||
|
|
||||||
|
Log::FileOutput::FileOutput(const std::string& filename, Log::Level lvl_max)
|
||||||
|
: Output(lvl_max), filename(filename), ofs(filename, std::ofstream::out | std::ofstream::app) {}
|
||||||
|
|
||||||
|
Log::FileOutput::FileOutput(const std::string& filename, Log::Level lvl_min, Log::Level lvl_max)
|
||||||
|
: Output(lvl_max), filename(filename), ofs(filename, std::ofstream::out | std::ofstream::app), lvl_min(lvl_min) {}
|
||||||
|
|
||||||
|
std::ostream* Log::FileOutput::getOs(Log::Level lvl) {
|
||||||
|
if (lvl_min <= lvl && lvl <= lvl_max)
|
||||||
|
return &ofs;
|
||||||
|
return nullptr;
|
||||||
|
}
|
136
Log.h
136
Log.h
|
@ -15,7 +15,7 @@ class Log {
|
||||||
Log() = delete;
|
Log() = delete;
|
||||||
Log(const Log&) = delete;
|
Log(const Log&) = delete;
|
||||||
Log& operator=(const Log&) = delete;
|
Log& operator=(const Log&) = delete;
|
||||||
~Log() = delete;
|
//~Log() = delete;
|
||||||
|
|
||||||
// set up the logger with a ConsoleOutput
|
// set up the logger with a ConsoleOutput
|
||||||
static void init();
|
static void init();
|
||||||
|
@ -26,11 +26,11 @@ class Log {
|
||||||
// abstract base class for a log sink
|
// abstract base class for a log sink
|
||||||
class Output {
|
class Output {
|
||||||
public:
|
public:
|
||||||
Output() {}
|
Output();
|
||||||
Output(Log::Level lvl_max) : lvl_max(lvl_max) {}
|
Output(Log::Level lvl_max);
|
||||||
virtual ~Output() {}
|
virtual ~Output();
|
||||||
virtual void log(Log::Level lvl, std::stringbuf* sbuf);
|
virtual void log(Log::Level lvl, std::stringbuf* sbuf);
|
||||||
virtual void setLogLevel(Log::Level lvl) { lvl_max = lvl; }
|
virtual void setLogLevel(Log::Level lvl);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Log::Level lvl_max = INFO;
|
Log::Level lvl_max = INFO;
|
||||||
|
@ -41,9 +41,9 @@ class Log {
|
||||||
};
|
};
|
||||||
|
|
||||||
// logging to stdout/stderr
|
// logging to stdout/stderr
|
||||||
class ConsoleOutout : public Output {
|
class ConsoleOutput : public Output {
|
||||||
public:
|
public:
|
||||||
ConsoleOutout();
|
ConsoleOutput();
|
||||||
virtual bool setColoredOutput(bool enabled);
|
virtual bool setColoredOutput(bool enabled);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -143,125 +143,3 @@ class Log {
|
||||||
}
|
}
|
||||||
static void log(Level lvl, std::stringbuf* strb);
|
static void log(Level lvl, std::stringbuf* strb);
|
||||||
};
|
};
|
||||||
|
|
||||||
// static member
|
|
||||||
std::vector<Log::Output*> Log::outputs;
|
|
||||||
|
|
||||||
void Log::init() {
|
|
||||||
// add default console logger
|
|
||||||
if (outputs.empty())
|
|
||||||
outputs.push_back(new Log::ConsoleOutout());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Log::stop() {
|
|
||||||
for (auto output : outputs)
|
|
||||||
delete output;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Log::addLogfile(const std::string& filename, Level max) {
|
|
||||||
outputs.push_back(new Log::FileOutput(filename, max));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Log::addLogfile(const std::string& filename, Level min, Level max) {
|
|
||||||
outputs.push_back(new Log::FileOutput(filename, min, max));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Log::setConsoleLogLevel(Level lvl) {
|
|
||||||
outputs.at(0)->setLogLevel(lvl); // has to exist
|
|
||||||
}
|
|
||||||
|
|
||||||
void Log::setColoredOutput(bool enabled) {
|
|
||||||
((Log::ConsoleOutout*) outputs.at(0))->setColoredOutput(enabled); // has to exist
|
|
||||||
}
|
|
||||||
|
|
||||||
void Log::log(Level lvl, std::stringbuf* strb) {
|
|
||||||
for (Output* out : outputs) {
|
|
||||||
out->log(lvl, strb);
|
|
||||||
// reset stringbuffer read pointer to the beginning
|
|
||||||
strb->pubseekpos(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* abstract class Ouput
|
|
||||||
* default implementations
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Log::Output::log(Log::Level lvl, std::stringbuf* sbuf) {
|
|
||||||
std::ostream* os = getOs(lvl);
|
|
||||||
if (os) {
|
|
||||||
printLogHeader(os, lvl);
|
|
||||||
*os << sbuf << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Log::Output::printLogHeader(std::ostream* os, Level lvl) {
|
|
||||||
static const char* LevelTag[] = {"", "[FATAL] ", "[ERROR] ", "[WARN ] ",
|
|
||||||
"[NOTE ] ", "[INFO ] ", "[DEBUG] ", "[TRACE] "};
|
|
||||||
|
|
||||||
// get current date/time
|
|
||||||
auto now = std::chrono::system_clock::now();
|
|
||||||
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
|
|
||||||
|
|
||||||
*os << "[" << std::put_time(std::localtime(&now_c), "%F %T") << "]" << LevelTag[lvl];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ConsoleOutout */
|
|
||||||
|
|
||||||
Log::ConsoleOutout::ConsoleOutout() : Output() {}
|
|
||||||
|
|
||||||
bool Log::ConsoleOutout::setColoredOutput(bool enabled) {
|
|
||||||
// TODO: check the terminals compatibility for colors
|
|
||||||
coloredOutput = enabled;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Log::ConsoleOutout::log(Log::Level lvl, std::stringbuf* sbuf) {
|
|
||||||
static const char* esc_seq_start = "\033[";
|
|
||||||
static const char* esc_seq_reset = "\033[0m";
|
|
||||||
// OFF FATAL ERROR WARN NOTE INFO DEBUG TRACE
|
|
||||||
static const char* color_codes[] = {"", "1;31;40m", "31m", "33m", "96m", "32m", "0m", "0m"};
|
|
||||||
|
|
||||||
std::ostream* os = getOs(lvl);
|
|
||||||
|
|
||||||
if (os) {
|
|
||||||
// print colors if enabled
|
|
||||||
if (coloredOutput)
|
|
||||||
*os << esc_seq_start << color_codes[lvl];
|
|
||||||
|
|
||||||
Output::printLogHeader(os, lvl);
|
|
||||||
*os << sbuf;
|
|
||||||
|
|
||||||
// reset color at end of the line
|
|
||||||
if (coloredOutput)
|
|
||||||
*os << esc_seq_reset;
|
|
||||||
|
|
||||||
*os << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream* Log::ConsoleOutout::getOs(Log::Level lvl) {
|
|
||||||
// out of scope?
|
|
||||||
if (!lvl || lvl > lvl_max)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
// stderr for FATAL, ERROR, WARN
|
|
||||||
if (lvl <= Log::Level::WARN)
|
|
||||||
return osErr;
|
|
||||||
else
|
|
||||||
return osStd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FileOutput ( logging to file ) */
|
|
||||||
|
|
||||||
Log::FileOutput::FileOutput(const std::string& filename, Log::Level lvl_max)
|
|
||||||
: Output(lvl_max), filename(filename), ofs(filename, std::ofstream::out | std::ofstream::app) {}
|
|
||||||
|
|
||||||
Log::FileOutput::FileOutput(const std::string& filename, Log::Level lvl_min, Log::Level lvl_max)
|
|
||||||
: Output(lvl_max), filename(filename), ofs(filename, std::ofstream::out | std::ofstream::app), lvl_min(lvl_min) {}
|
|
||||||
|
|
||||||
std::ostream* Log::FileOutput::getOs(Log::Level lvl) {
|
|
||||||
if (lvl_min <= lvl && lvl <= lvl_max)
|
|
||||||
return &ofs;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
Loading…
Reference in New Issue