Program Listing for File logger.cc¶
↰ Return to documentation for file (core/logger.cc)
#include "lupnt/core/logger.h"
#include <sstream>
#include "lupnt/core/data_logger.h"
namespace lupnt {
// Static member initialization
std::chrono::steady_clock::time_point Logger::start_time_ = std::chrono::steady_clock::now();
Logger::LogLevel Logger::log_level_ = Logger::INFO;
std::string Logger::FormatTime(double seconds, bool short_format) {
int hours = static_cast<int>(seconds / 3600);
int minutes = static_cast<int>((static_cast<int>(seconds) % 3600) / 60);
double secs = seconds - hours * 3600 - minutes * 60;
if (!short_format) return fmt::format("{:02}:{:02}:{:05.2f}", hours, minutes, secs);
if (hours > 0) return fmt::format("{:02}:{:02}:{:05.2f}", hours, minutes, secs);
if (minutes > 0) return fmt::format("{:02}:{:05.2f}", minutes, secs);
return fmt::format("{:05.2f}", secs);
}
std::string Logger::GetPrefix(const std::string& name, double time_sim) {
auto now = std::chrono::steady_clock::now();
auto elapsed = std::chrono::duration<double>(now - start_time_).count();
std::string elapsed_str = FormatTime(elapsed, true);
std::stringstream ss;
ss << "[" << Colors::CYAN << elapsed_str << Colors::RESET << "]";
if (time_sim >= 0.0) {
std::string sim_str = FormatTime(time_sim, true);
ss << "[" << Colors::CYAN << sim_str << Colors::RESET << "]";
}
if (!name.empty()) {
ss << "[" << Colors::GREEN << name << Colors::RESET << "]";
}
return ss.str();
}
void Logger::Log(const std::string& message, const std::string& name, double time_sim,
const std::string& color, LogLevel level) {
// Prefix
std::string prefix = GetPrefix(name, time_sim);
// Console
if (level >= log_level_) {
auto progress_bars = ProgressBar::GetProgressBars();
int n_bars = static_cast<int>(progress_bars.size());
if (n_bars > 0) {
std::cout << "\033[" << n_bars << "A" << std::flush; // Move up
std::cout << "\r\033[2K" << std::flush; // Clear line
}
std::cout << prefix << " " << color << message << Colors::RESET << std::endl;
if (n_bars > 0) std::cout << std::string(n_bars, '\n') << std::flush;
if (level != LogLevel::ERROR) {
for (auto bar : progress_bars) bar->Redraw();
}
}
// Remove colors from message
auto colors = {Colors::CYAN, Colors::GREEN, Colors::YELLOW, Colors::RED,
Colors::BLUE, Colors::WHITE, Colors::RESET};
std::string clean_message = prefix + " " + message;
for (auto color_code : colors) {
// Prevent infinite loop if an empty string (like Colors::RESET on some systems) is searched.
if (color_code.empty()) {
continue;
}
size_t pos = 0;
while ((pos = clean_message.find(color_code, pos)) != std::string::npos) {
clean_message.erase(pos, color_code.length());
// Do not advance pos, next iteration correctly resumes search at the current index.
}
}
}
// Static methods
void Logger::Debug(const std::string& message, const std::string& name, double time_sim) {
Log(message, name, time_sim, Colors::BLUE, LogLevel::DEBUG);
}
void Logger::Info(const std::string& message, const std::string& name, double time_sim) {
Log(message, name, time_sim, Colors::WHITE, LogLevel::INFO);
}
void Logger::Warn(const std::string& message, const std::string& name, double time_sim) {
Log(message, name, time_sim, Colors::YELLOW, LogLevel::WARNING);
}
void Logger::Error(const std::string& message, const std::string& name, double time_sim) {
Log(message, name, time_sim, Colors::RED, LogLevel::ERROR);
}
Ptr<ProgressBar> Logger::GetProgressBar(int total, const std::string& message,
const std::string& name, double time_sim) {
Ptr<ProgressBar> bar;
bar = MakePtr<ProgressBar>(total);
std::stringstream ss;
ss << GetPrefix(name, time_sim);
if (!message.empty()) ss << " " << message;
bar->SetDescription(ss.str());
return bar;
} // namespace lupnt
void Logger::PlaySound() { std::cout << '\a' << std::flush; }
} // namespace lupnt