// // Some logging utilities // 1. "log() << ..." will show a time stamp first // 2. "print(a, b, c)" is python-like print for any a, b, c that has operator<< overloaded. For example, // int a = 10; // double b = 3.14; // std::string c = "Gengjie"; // print(a, b, c); // This code piece will show "10 3.14 Gengjie". // 3. "assert_msg(condition, format, ...)" is python-like assert // #pragma once #include #include #include #include #include #include #include "log_level.h" // #include "argparse.hpp" // need C++20 namespace utils { extern bool verbose_parser_log; // 1. Timer class timer { using clock = std::chrono::high_resolution_clock; private: clock::time_point _start; public: timer(); void start(); double elapsed() const; // seconds std::string get_time_stamp(); }; extern timer tstamp; // 2. Memory class mem_use { public: static double get_current(); // MB static double get_peak(); // MB }; // 3. Easy print // print(a, b, c) inline void print() { std::cout << std::endl; } template void print(const T& t, TAIL... tail) { std::cout << t << ' '; print(tail...); } // "printlog(LOG_LEVEL, a, b, c...)" puts a time stamp in beginning // try to make code compatible with old printlog(int level, const char *format, ...) void printlog(int level, const char* format, ...); void assert_msg(bool condition, const char* format, ...); std::string log_level_ANSI_color(int& log_level); // 4. PrintfLogger format and write to file // Python kind logger, support printf kind format (can be replaced by fmt library) class PrintfLogger { static constexpr bool write_log = false; FILE* f; public: // void setup_logger(argparse::ArgumentParser parser); ~PrintfLogger() { if (f != NULL) fclose(f); } template void log(int log_level, const char* format, Args&&... args) { if (!verbose_parser_log) { return; } if (log_level >= GLOBAL_LOG_LEVEL) { std::string curr_log = tstamp.get_time_stamp(); if (log_level > LOG_INFO) { curr_log += log_level_ANSI_color(log_level); } std::cout << curr_log; printf(format, args...); printf("\n"); fflush(stdout); if (write_log) { fprintf(f, "%s", curr_log.c_str()); fprintf(f, format, args...); fprintf(f, "\n"); fflush(f); } } } template void debug(const char* format, Args&&... args) { log(LOG_DEBUG, format, args...); }; template void verbose(const char* format, Args&&... args) { log(LOG_VERBOSE, format, args...); }; template void info(const char* format, Args&&... args) { log(LOG_INFO, format, args...); }; template void notice(const char* format, Args&&... args) { log(LOG_NOTICE, format, args...); }; template void warning(const char* format, Args&&... args) { log(LOG_WARN, format, args...); }; template void error(const char* format, Args&&... args) { log(LOG_ERROR, format, args...); }; template void fatal(const char* format, Args&&... args) { log(LOG_FATAL, format, args...); }; template void ok(const char* format, Args&&... args) { log(LOG_OK, format, args...); }; }; extern PrintfLogger logger; } // namespace utils