Polished Logger template, semi working

This commit is contained in:
NaifBanana 2026-01-19 04:05:26 -06:00
parent 847bf3a078
commit f8a8813b3e
2 changed files with 82 additions and 62 deletions

View File

@ -30,83 +30,34 @@ struct LogEvent{
typedef std::string (*LogProcessFunction)(const LoggerTimePoint&, const std::string&); typedef std::string (*LogProcessFunction)(const LoggerTimePoint&, const std::string&);
typedef std::unordered_map<uint8_t, LogProcessFunction> LogProcessFunctionMap; typedef std::unordered_map<uint8_t, LogProcessFunction> LogProcessFunctionMap;
template<typename StreamType> template<typename LoggerName>
class Logger { class Logger {
public: public:
Logger(StreamType& stream) : _ostream(&stream) {} using Type = LoggerName;
bool isRunning() const; Logger(std::ostream& stream) : _ostream(&stream) {}
unsigned int count() const;
bool run(); bool isRunning() const {
bool stop();
LogEvent pop();
void flush() {
while(_queue.size()) {
pop();
}
}
void deleteAll() {
_queue.empty();
}
void msg(const std::string& _msg, uint8_t lvl=0) {
_queue.push(LogEvent{
std::chrono::system_clock::now(),
lvl,
_msg,
std::this_thread::get_id(),
get_pid()
});
}
void warn(const std::string& _msg, uint8_t lvl=1) {
msg(_msg, lvl);
}
void warn(const std::exception& _err, uint8_t lvl=1) {
msg(_err.what(), lvl);
}
void error(const std::string& _msg, uint8_t lvl=0xFF) {
msg(_msg, lvl);
}
void error(const std::exception& _err, uint8_t lvl=0xFF) {
msg(_err.what(), lvl);
}
protected:
virtual void process(const LogEvent& event) {
uint8_t lvl = event.lvl;
*_ostream << "\n";
}
ThreadsafeQueue<LogEvent> _queue;
StreamType* const _ostream;
std::atomic<bool> _running;
std::shared_ptr<std::thread> _runningThread = nullptr;
};
template <typename ST>
bool Logger<ST>::isRunning() const {
return _running && bool(_runningThread); return _running && bool(_runningThread);
} }
template <typename ST> unsigned int count() const {
unsigned int Logger<ST>::count() const {
return _queue.size(); return _queue.size();
} }
template <typename ST> bool run() {
bool Logger<ST>::run() { auto this_type = static_cast<Type*>(this);
if (!isRunning()) { if (!isRunning()) {
_runningThread = std::make_shared<std::thread>([&]{ _runningThread = std::make_shared<std::thread>([&]{
while(this->isRunning()) { while(this_type->isRunning()) {
this->flush(); this_type->flush();
} }
}); });
} }
return isRunning(); return isRunning();
} }
template <typename ST> bool stop() {
bool Logger<ST>::stop() {
if (isRunning()) { if (isRunning()) {
_running = false; _running = false;
_runningThread->join(); _runningThread->join();
@ -116,13 +67,82 @@ bool Logger<ST>::stop() {
return isRunning(); return isRunning();
} }
template <typename ST> LogEvent pop() {
LogEvent Logger<ST>::pop() {
std::shared_ptr<LogEvent> event; std::shared_ptr<LogEvent> event;
_queue.pop(event); _queue.pop(event);
process(*event); static_cast<Type*>(this)->process(*event);
return *event; return *event;
} }
void flush() {
while(_queue.size()) {
pop();
}
}
void deleteAll() {
_queue.empty();
}
template <typename T>
void log(const T&, const uint8_t);
void log(const std::string& msg, const uint8_t& lvl) {
_queue.push(LogEvent{
std::chrono::system_clock::now(),
lvl,
msg,
std::this_thread::get_id(),
get_pid(),
});
}
void log(const std::exception& err, const uint8_t& lvl) {
_queue.push(LogEvent{
std::chrono::system_clock::now(),
lvl,
err.what(),
std::this_thread::get_id(),
get_pid(),
});
}
void msg(const std::string& msg, const uint8_t& lvl=0x00) {
static_cast<Type>(this)->log(msg, lvl);
}
void warn(const std::string& msg, const uint8_t& lvl=0x01) {
static_cast<Type>(this)->log(msg, lvl);
}
void warn(const std::exception& err, const uint8_t lvl=0x01) {
static_cast<Type>(this)->log(err, lvl);
}
void error(const std::string& msg, const uint8_t lvl=0xFF) {
static_cast<Type>(this)->log(msg, lvl);
}
void error(const std::exception& err, const uint8_t lvl=0xFF) {
static_cast<Type*>(this)->log(err, lvl);
}
protected:
void process(const LogEvent&);
ThreadsafeQueue<LogEvent> _queue;
std::ostream* const _ostream;
std::atomic<bool> _running;
std::shared_ptr<std::thread> _runningThread = nullptr;
};
class BasicLogger : public Logger<BasicLogger> {
public:
using Base = Logger<BasicLogger>;
BasicLogger(std::ostream& stream) : Base(stream) {}
virtual void process(const LogEvent& event) {
*_ostream << event.msg << "\n";
}
};
} // namespace nb } // namespace nb
#endif // _NB_LOGGER #endif // _NB_LOGGER

View File

@ -42,7 +42,7 @@ int main() {
} }
} catch(const std::exception& e) { } catch(const std::exception& e) {
// THROW(Error, Error::ErrorCodes::UNDEFINED, e); // THROW(Error, Error::ErrorCodes::UNDEFINED, e);
Logger log(std::cout); BasicLogger log(std::cout);
std::cout << "Logger is starting: " << log.run() << std::endl; std::cout << "Logger is starting: " << log.run() << std::endl;
std::cout << "Logger is running: " << log.isRunning() << std::endl; std::cout << "Logger is running: " << log.isRunning() << std::endl;
log.error(e); log.error(e);