2022-10-20 22:46:17 +08:00
|
|
|
//
|
|
|
|
|
// 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 <chrono>
|
|
|
|
|
#include <cstdarg>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
#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
|
|
|
|
|
|
|
|
|
|
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;
|
2023-04-06 13:34:26 +08:00
|
|
|
bool tmp_verbose_parser_log = false;
|
2023-12-27 23:02:20 +08:00
|
|
|
int _global_log_level = LOG_INFO;
|
2022-10-20 22:46:17 +08:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// void setup_logger(argparse::ArgumentParser parser);
|
|
|
|
|
~PrintfLogger() {
|
|
|
|
|
if (f != NULL) fclose(f);
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-06 13:34:26 +08:00
|
|
|
void enable_logger() {
|
|
|
|
|
tmp_verbose_parser_log = verbose_parser_log;
|
|
|
|
|
verbose_parser_log = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void disable_logger() {
|
|
|
|
|
tmp_verbose_parser_log = verbose_parser_log;
|
|
|
|
|
verbose_parser_log = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void reset_logger() {
|
|
|
|
|
verbose_parser_log = tmp_verbose_parser_log;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-27 23:02:20 +08:00
|
|
|
void set_global_log_level(int value) {
|
|
|
|
|
_global_log_level = value;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-20 22:46:17 +08:00
|
|
|
template <typename... Args>
|
|
|
|
|
void log(int log_level, const char* format, Args&&... args) {
|
|
|
|
|
if (!verbose_parser_log) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-12-27 23:02:20 +08:00
|
|
|
if (log_level >= _global_log_level) {
|
2022-10-20 22:46:17 +08:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-06 13:34:26 +08:00
|
|
|
void log(int log_level, const char* format) {
|
|
|
|
|
if (!verbose_parser_log) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-12-27 23:02:20 +08:00
|
|
|
if (log_level >= _global_log_level) {
|
2023-04-06 13:34:26 +08:00
|
|
|
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;
|
|
|
|
|
puts(format);
|
|
|
|
|
fflush(stdout);
|
|
|
|
|
if (write_log) {
|
|
|
|
|
fprintf(f, "%s", curr_log.c_str());
|
|
|
|
|
fputs(format, f);
|
|
|
|
|
fflush(f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-20 22:46:17 +08:00
|
|
|
template <typename... Args>
|
|
|
|
|
void debug(const char* format, Args&&... args) {
|
2023-04-06 13:34:26 +08:00
|
|
|
if (sizeof...(args) != 0) {
|
|
|
|
|
log(LOG_DEBUG, format, args...);
|
|
|
|
|
} else {
|
|
|
|
|
log(LOG_DEBUG, format);
|
|
|
|
|
}
|
2022-10-20 22:46:17 +08:00
|
|
|
};
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
void verbose(const char* format, Args&&... args) {
|
2023-04-06 13:34:26 +08:00
|
|
|
if (sizeof...(args) != 0) {
|
|
|
|
|
log(LOG_VERBOSE, format, args...);
|
|
|
|
|
} else {
|
|
|
|
|
log(LOG_VERBOSE, format);
|
|
|
|
|
}
|
2022-10-20 22:46:17 +08:00
|
|
|
};
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
void info(const char* format, Args&&... args) {
|
2023-04-06 13:34:26 +08:00
|
|
|
if (sizeof...(args) != 0) {
|
|
|
|
|
log(LOG_INFO, format, args...);
|
|
|
|
|
} else {
|
|
|
|
|
log(LOG_INFO, format);
|
|
|
|
|
}
|
2022-10-20 22:46:17 +08:00
|
|
|
};
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
void notice(const char* format, Args&&... args) {
|
2023-04-06 13:34:26 +08:00
|
|
|
if (sizeof...(args) != 0) {
|
|
|
|
|
log(LOG_NOTICE, format, args...);
|
|
|
|
|
} else {
|
|
|
|
|
log(LOG_NOTICE, format);
|
|
|
|
|
}
|
2022-10-20 22:46:17 +08:00
|
|
|
};
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
void warning(const char* format, Args&&... args) {
|
2023-04-06 13:34:26 +08:00
|
|
|
if (sizeof...(args) != 0) {
|
|
|
|
|
log(LOG_WARN, format, args...);
|
|
|
|
|
} else {
|
|
|
|
|
log(LOG_WARN, format);
|
|
|
|
|
}
|
2022-10-20 22:46:17 +08:00
|
|
|
};
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
void error(const char* format, Args&&... args) {
|
2023-04-06 13:34:26 +08:00
|
|
|
if (sizeof...(args) != 0) {
|
|
|
|
|
log(LOG_ERROR, format, args...);
|
|
|
|
|
} else {
|
|
|
|
|
log(LOG_ERROR, format);
|
|
|
|
|
}
|
2022-10-20 22:46:17 +08:00
|
|
|
};
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
void fatal(const char* format, Args&&... args) {
|
2023-04-06 13:34:26 +08:00
|
|
|
if (sizeof...(args) != 0) {
|
|
|
|
|
log(LOG_FATAL, format, args...);
|
|
|
|
|
} else {
|
|
|
|
|
log(LOG_FATAL, format);
|
|
|
|
|
}
|
2022-10-20 22:46:17 +08:00
|
|
|
};
|
|
|
|
|
template <typename... Args>
|
|
|
|
|
void ok(const char* format, Args&&... args) {
|
2023-04-06 13:34:26 +08:00
|
|
|
if (sizeof...(args) != 0) {
|
|
|
|
|
log(LOG_OK, format, args...);
|
|
|
|
|
} else {
|
|
|
|
|
log(LOG_OK, format);
|
|
|
|
|
}
|
2022-10-20 22:46:17 +08:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
extern PrintfLogger logger;
|
|
|
|
|
|
|
|
|
|
} // namespace utils
|