#ifndef LOG_HPP #define LOG_HPP // comment out to disable logging in general #define log(level, fmt, ...) _log(level, std::source_location::current(), fmt, ##__VA_ARGS__) // comment out to disable logging to file // #define LOG_FILE_LOCATION "linuxSmartie.log.gz" #ifdef log #include #include #include #include #include #ifdef LOG_FILE_LOCATION #include inline std::mutex fmtx; // file logging mutex #endif inline std::mutex cmtx; // console logging mutex enum class LOG { INF, WRN, ERR, DBG, START }; constexpr std::string_view pFname(std::string_view full) { if (auto pos = full.find(' '); pos != std::string_view::npos) full.remove_prefix(pos + 1); if (auto pos = full.rfind('('); pos != std::string_view::npos) full.remove_suffix(full.size() - pos); return full; } template inline void _log(LOG level, const std::source_location& loc, std::format_string str, Args&&... args) { constexpr std::string_view reset = "\033[0m"; constexpr std::string_view pattern = "[{}{}{}] "; std::string_view color = ""; switch (level) { case LOG::INF: color = "\033[1;32m"; break; // bold; green case LOG::WRN: color = "\033[1;33m"; // bold; yellow break; case LOG::ERR: color = "\033[1;31m"; // bold; red break; case LOG::DBG: break; case LOG::START: color = "\033[1;3;5;36m"; // bold; italics; blinking; cyan break; } /* log to console */ { std::scoped_lock lock(cmtx); std::print(pattern, color, pFname(loc.function_name()), reset); std::println(str, std::forward(args)...); } #ifdef LOG_FILE_LOCATION /* log to file */ { auto now = std::chrono::system_clock::now(); auto local = std::chrono::current_zone()->to_local(now); std::string msg = std::format("{:%x %H:%M:%S }", floor(local)); // timestamp std::format_to(std::back_inserter(msg), pattern, color, pFname(loc.function_name()), reset); // tag std::format_to(std::back_inserter(msg), str, std::forward(args)...); // actual log message std::scoped_lock lock(fmtx); gzFile file = gzopen(LOG_FILE_LOCATION, "ab"); if (file) { gzprintf(file, "%s\n", msg.c_str()); gzclose(file); } } #endif } #else #define log(...) #endif #endif