#ifndef _LOGGER_H_ #define _LOGGER_H_ #include "log_queue.h" #include #include #include #include #include #include class logger { private: std::atomic _enabled; std::stringstream _logLine; log_queue _queue; typedef std::chrono::high_resolution_clock hr_clock; typedef std::chrono::system_clock sys_clock; typedef std::chrono::system_clock::time_point sys_tp; typedef std::chrono::high_resolution_clock::time_point hr_tp; public: logger(); void set_enabled(bool enabled); template void log_info(const char* s, const Args&... args) { log("info", s, args...); } template void log_warning(const char* s, const Args&... args) { log("warning", s, args...); } template void log_error(const char* s, const Args&... args) { log("error", s, args...); } private: template void log(const char* log_level, const char* s, const Args&... args) { if (_enabled) { _queue.add_log(std::bind(&logger::log_impl, this, s, args..., sys_clock::now(), hr_clock::now(), log_level)); } } template void log_impl(const char* s, const Args&... args, sys_tp sc, hr_tp hrc, const char* log_level) { _logLine.str(""); //_logLine << "[" << hrc.time_since_epoch().count() << "] "; char tm_buffer[50]; std::time_t tm = std::chrono::system_clock::to_time_t(sc); std::strftime(tm_buffer, 50, "%F %T", std::localtime(&tm)); _logLine << "[" << tm_buffer << "] "; _logLine << "[" << log_level << "] "; form_log_line(s, args...); std::cout << _logLine.str() << std::endl; } void form_log_line(const char* s); template void form_log_line(const char* s, const T& value, const Args&... args) { while (*s) { if (*s == '%' && *++s != '%') { _logLine << value; return form_log_line(s, args...); } _logLine << *s++; } throw std::runtime_error("extra arguments provided"); } }; extern logger ulog; #endif // _LOGGER_H_