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::unordered_map<uint8_t, LogProcessFunction> LogProcessFunctionMap;
template<typename StreamType>
template<typename LoggerName>
class Logger {
public:
Logger(StreamType& stream) : _ostream(&stream) {}
using Type = LoggerName;
bool isRunning() const;
unsigned int count() const;
Logger(std::ostream& stream) : _ostream(&stream) {}
bool run();
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 {
bool isRunning() const {
return _running && bool(_runningThread);
}
}
template <typename ST>
unsigned int Logger<ST>::count() const {
unsigned int count() const {
return _queue.size();
}
}
template <typename ST>
bool Logger<ST>::run() {
bool run() {
auto this_type = static_cast<Type*>(this);
if (!isRunning()) {
_runningThread = std::make_shared<std::thread>([&]{
while(this->isRunning()) {
this->flush();
while(this_type->isRunning()) {
this_type->flush();
}
});
}
return isRunning();
}
}
template <typename ST>
bool Logger<ST>::stop() {
bool stop() {
if (isRunning()) {
_running = false;
_runningThread->join();
@ -114,15 +65,84 @@ bool Logger<ST>::stop() {
flush();
}
return isRunning();
}
}
template <typename ST>
LogEvent Logger<ST>::pop() {
LogEvent pop() {
std::shared_ptr<LogEvent> event;
_queue.pop(event);
process(*event);
static_cast<Type*>(this)->process(*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
#endif // _NB_LOGGER

View File

@ -42,7 +42,7 @@ int main() {
}
} catch(const std::exception& 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 running: " << log.isRunning() << std::endl;
log.error(e);