Skip to content

Commit

Permalink
Add DebugTimer class and change some Logger::error calls to Logger::d…
Browse files Browse the repository at this point in the history
…ebug
  • Loading branch information
aristocratos committed May 21, 2023
1 parent 2e68c0b commit 1fee2bc
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 38 deletions.
70 changes: 69 additions & 1 deletion src/btop_tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,74 @@ namespace Tools {
return (user != NULL ? user : "");
}

DebugTimer::DebugTimer(const string name, bool start, bool delayed_report) : name(name), delayed_report(delayed_report) {
if (start)
this->start();
}

DebugTimer::~DebugTimer() {
if (running)
this->stop(true);
this->force_report();
}

void DebugTimer::start() {
if (running) return;
running = true;
start_time = time_micros();
}

void DebugTimer::stop(bool report) {
if (not running) return;
running = false;
elapsed_time = time_micros() - start_time;
if (report) this->report();
}

void DebugTimer::reset(bool restart) {
running = false;
start_time = 0;
elapsed_time = 0;
if (restart) this->start();
}

void DebugTimer::stop_rename_reset(const string &new_name, bool report, bool restart) {
this->stop(report);
name = new_name;
this->reset(restart);
}

void DebugTimer::report() {
string report_line;
if (start_time == 0 and elapsed_time == 0)
report_line = format("DebugTimer::report() warning -> Timer [{}] has not been started!", name);
else if (running)
report_line = format(custom_locale, "Timer [{}] (running) currently at {:L} μs", name, time_micros() - start_time);
else
report_line = format(custom_locale, "Timer [{}] took {:L} μs", name, elapsed_time);

if (delayed_report)
report_buffer.emplace_back(report_line);
else
Logger::log_write(log_level, report_line);
}

void DebugTimer::force_report() {
if (report_buffer.empty()) return;
for (const auto& line : report_buffer)
Logger::log_write(log_level, line);
report_buffer.clear();
}

uint64_t DebugTimer::elapsed() {
if (running)
return time_micros() - start_time;
return elapsed_time;
}

bool DebugTimer::is_running() {
return running;
}
}

namespace Logger {
Expand Down Expand Up @@ -572,7 +640,7 @@ namespace Logger {
loglevel = v_index(log_levels, level);
}

void log_write(const size_t level, const string& msg) {
void log_write(const Level level, const string& msg) {
if (loglevel < level or logfile.empty()) return;
atomic_lock lck(busy, true);
lose_priv neutered{};
Expand Down
60 changes: 54 additions & 6 deletions src/btop_tools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ namespace Term {
namespace Tools {
constexpr auto SSmax = std::numeric_limits<std::streamsize>::max();

class MyNumPunct : public std::numpunct<char> {
protected:
virtual char do_thousands_sep() const { return '\''; }
virtual std::string do_grouping() const { return "\03"; }
};

size_t wide_ulen(const string& str);
size_t wide_ulen(const std::wstring& w_str);

Expand Down Expand Up @@ -335,7 +341,6 @@ namespace Tools {

//* Convert a celsius value to celsius, fahrenheit, kelvin or rankin and return tuple with new value and unit.
auto celsius_to(const long long& celsius, const string& scale) -> tuple<long long, string>;

}

//* Simple logging implementation
Expand All @@ -349,13 +354,56 @@ namespace Logger {
};
extern std::filesystem::path logfile;

enum Level : size_t {
DISABLED = 0,
ERROR = 1,
WARNING = 2,
INFO = 3,
DEBUG = 4,
};

//* Set log level, valid arguments: "DISABLED", "ERROR", "WARNING", "INFO" and "DEBUG"
void set(const string& level);

void log_write(const size_t level, const string& msg);
inline void error(const string msg) { log_write(1, msg); }
inline void warning(const string msg) { log_write(2, msg); }
inline void info(const string msg) { log_write(3, msg); }
inline void debug(const string msg) { log_write(4, msg); }
void log_write(const Level level, const string& msg);
inline void error(const string msg) { log_write(ERROR, msg); }
inline void warning(const string msg) { log_write(WARNING, msg); }
inline void info(const string msg) { log_write(INFO, msg); }
inline void debug(const string msg) { log_write(DEBUG, msg); }
}

namespace Tools {
//* Creates a named timer that is started on construct (by default) and reports elapsed time in microseconds to Logger::debug() on destruct if running
//* Unless delayed_report is set to false, all reporting is buffered and delayed until DebugTimer is destructed or .force_report() is called
//* Usage example: Tools::DebugTimer timer(name:"myTimer", [start:true], [delayed_report:true]) // Create timer and start
//* timer.stop(); // Stop timer and report elapsed time
//* timer.stop_rename_reset("myTimer2"); // Stop timer, report elapsed time, rename timer, reset and restart
class DebugTimer {
uint64_t start_time{};
uint64_t elapsed_time{};
bool running{};
std::locale custom_locale = std::locale(std::locale::classic(), new Tools::MyNumPunct);
vector<string> report_buffer{};
public:
string name{};
bool delayed_report{};
Logger::Level log_level = Logger::DEBUG;
DebugTimer() = default;
DebugTimer(const string name, bool start = true, bool delayed_report = true);
~DebugTimer();

void start();
void stop(bool report = true);
void reset(bool restart = true);
//* Stops and reports (default), renames timer then resets and restarts (default)
void stop_rename_reset(const string& new_name, bool report = true, bool restart = true);
void report();
void force_report();
uint64_t elapsed();
bool is_running();
};

}



Loading

0 comments on commit 1fee2bc

Please sign in to comment.