#include #include namespace daggy { GeneralLogger::GeneralLogger(std::ostream &os, LogLevel level) : running_(true) , os_(os) , level_(level) , messageEmiter_(&GeneralLogger::emitMessages, this) { } GeneralLogger::~GeneralLogger() { shutdown(); } void GeneralLogger::shutdown() { if (!running_) return; running_ = false; newMessage_.notify_one(); messageEmiter_.join(); os_.flush(); } void GeneralLogger::setLevel(LogLevel level) { level_ = level; } void GeneralLogger::log(const std::string &msg, LogLevel level) { if (level > level_) { return; } { std::lock_guard lock(messageGuard_); messages_.emplace_back( LogMessage{.level = level, .msg = msg, .time = Clock::now()}); } newMessage_.notify_one(); } void GeneralLogger::log(const std::function &fun, LogLevel level) { if (level > level_) return; log(fun(), level); } void GeneralLogger::emitMessages() { while (running_ || !messages_.empty()) { std::unique_lock lock(messageGuard_); newMessage_.wait(lock, [&] { return !(messages_.empty() && running_); }); for (const auto &msg : messages_) { os_ << timePointToString(msg.time) << " [" << msg.level._to_string() << "] " << msg.msg << '\n'; } os_.flush(); messages_.clear(); } } } // namespace daggy