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