RNA Folding simulation
herrlog.hh
Go to the documentation of this file.
1 
32 #pragma once
33 
34 #include <chrono>
35 #include <fstream>
36 #include <mutex>
37 #include <ostream>
38 #include <sstream>
39 #include <string_view>
40 
41 static_assert(__cplusplus >= 202002L,
42  "This library requires at least C++20 to compile");
43 
49 namespace ascii_colors {
50 inline constexpr std::string_view reset_color{"\033[0m"};
51 inline constexpr std::string_view bold_red_color{"\033[1;31m"};
52 inline constexpr std::string_view bold_green_color{"\033[1;32m"};
53 inline constexpr std::string_view bold_yellow_color{"\033[1;33m"};
54 inline constexpr std::string_view bold_blue_color{"\033[1;34m"};
55 inline constexpr std::string_view background_red_color{"\033[41m"};
56 inline constexpr std::string_view bold_white_color{"\033[1;37m"};
57 } // namespace ascii_colors
58 
65 class LogType {
66  private:
67  std::uint8_t bitflag;
68 
69  public:
74  enum : std::uint8_t {
75  Trace = 0b000001, // For specific details
76  Debug = 0b000010, // Temporary debug printing
77  Info = 0b000100, // General purpose details, e.g. "Program has started"
78  Error = 0b001000, // For errors, exits the program
79  Warn = 0b010000, // For reporting warning, the program keeps working
80  Fatal = 0b100000, // Program exits and produces core dump
81 
82  All = 0b111111,
83  None = 0b000000,
84  };
85 
93  LogType(std::uint8_t initial_flag) : bitflag(initial_flag) {}
94 
100  LogType operator|(const LogType other) const {
101  return LogType((static_cast<std::uint8_t>(bitflag) |
102  static_cast<std::uint8_t>(other.bitflag)));
103  }
104 
112  bool operator&(const LogType other) const {
113  return static_cast<bool>(static_cast<std::uint8_t>(bitflag) &
114  static_cast<std::uint8_t>(other.bitflag));
115  }
116 };
117 
122 class Logger {
123  private:
124  static LogType log_type;
125  static std::string output_file_name;
126  static std::ostream* output_buffer;
127  static bool is_color_output;
128  static const char* datetime_format;
129  static std::mutex log_mutex;
130  static std::ofstream output_file;
131 
142  template <typename T, typename... Rest>
143  static void print_to_stream(std::ostream& stream, const char* format, T arg,
144  Rest... rest) {
145  for (size_t index = 0; format[index] != '\0'; index++) {
146  if (format[index] == '{' && format[index + 1] == '}') {
147  stream << arg;
148  return print_to_stream(stream, format + index + 2, rest...);
149  }
150  stream << format[index];
151  }
152  }
153 
160  static void print_to_stream(std::ostream& stream, const char* format) {
161  for (size_t index = 0; format[index] != '\0'; index++) {
162  stream << format[index];
163  }
164  }
165 
175  template <typename... Args>
176  static void log(const char* name, const std::string_view& color,
177  const char* format, Args... args) {
178  std::time_t current_time = std::chrono::system_clock::to_time_t(
179  std::chrono::system_clock::now());
180  char time_string[100];
181  std::strftime(time_string, sizeof(time_string), datetime_format,
182  std::localtime(&current_time));
183 
184  std::stringstream ss;
185  ss << (is_color_output ? color : std::string_view()) << "[" << name
186  << " " << time_string << "]"
187  << (is_color_output ? ascii_colors::reset_color : std::string_view())
188  << " ";
189 
190  print_to_stream(ss, format, args...);
191 
192  std::lock_guard<std::mutex> lock(Logger::log_mutex);
193  *output_buffer << ss.str() << '\n';
200  output_buffer->flush();
201  }
202 
207  Logger() = delete;
208 
209  public:
215  static void set_type(LogType log_type) { Logger::log_type = log_type; }
216 
222  static void set_output_file_name(std::string output_file_name) {
223  Logger::output_file_name = output_file_name;
224  Logger::output_file = std::ofstream(Logger::output_file_name);
225  if (Logger::output_file.is_open()) {
226  Logger::output_file.close();
227  }
228  Logger::output_file.open(Logger::output_file_name);
229  if (!Logger::output_file.is_open()) {
231  "Failed to open {}",
232  Logger::output_file_name); // Peak efficiency ᕦ(ò_óˇ)ᕤ
233  return;
234  }
235 
236  output_buffer = &Logger::output_file;
237  is_color_output = false;
238  }
239 
245  static void set_datetime_format(const char* datetime_format) {
246  Logger::datetime_format = datetime_format;
247  }
248 
254  static void set_output_buffer(std::ostream& output_buffer) {
255  Logger::output_buffer = &output_buffer;
256  }
257 
263  static void set_is_color_output(bool is_color_output) {
264  Logger::is_color_output = is_color_output;
265  }
266 
276  template <typename... Args>
277  static void trace(const char* format, Args... args) {
278  if (log_type & LogType::Trace) {
279  log("TRACE", ascii_colors::bold_white_color, format, args...);
280  }
281  }
282 
292  template <typename... Args>
293  static void debug(const char* format, Args... args) {
294  if (log_type & LogType::Debug) {
295  log("DEBUG", ascii_colors::bold_blue_color, format, args...);
296  }
297  }
298 
308  template <typename... Args>
309  static void info(const char* format, Args... args) {
310  if (log_type & LogType::Info) {
311  log(" INFO", ascii_colors::bold_green_color, format, args...);
312  }
313  }
314 
325  template <typename... Args>
326  static void error(const char* format, Args... args) {
327  if (log_type & LogType::Error) {
328  log("ERROR", ascii_colors::bold_red_color, format, args...);
329  exit(EXIT_FAILURE);
330  }
331  }
332 
341  template <typename... Args>
342  static void warn(const char* format, Args... args) {
343  if (log_type & LogType::Warn) {
344  log(" WARN", ascii_colors::bold_yellow_color, format, args...);
345  }
346  }
347 
356  template <typename... Args>
357  static void fatal(const char* format, Args... args) {
358  if (log_type & LogType::Fatal) {
359  log("FATAL", ascii_colors::background_red_color, format, args...);
360  abort();
361  }
362  }
363 };
364 
365 LogType Logger::log_type = LogType::All;
366 std::string Logger::output_file_name = std::string();
367 std::ostream* Logger::output_buffer = &std::cout;
368 bool Logger::is_color_output = true;
369 const char* Logger::datetime_format = "%Y-%m-%d %H:%M:%S";
370 std::mutex Logger::log_mutex;
371 std::ofstream Logger::output_file = std::ofstream();
372 
The LogType class is used to define different types of logs using bit flags. Each log type is represe...
Definition: herrlog.hh:65
LogType operator|(const LogType other) const
Overloading the | operator for combining log types.
Definition: herrlog.hh:100
bool operator&(const LogType other) const
Overloading the & operator for checking if a log type is set.
Definition: herrlog.hh:112
LogType(std::uint8_t initial_flag)
Construct a new Log Type object. Allows implicit conversion from uint8_t. Thus allows assignments lik...
Definition: herrlog.hh:93
Logger implementation providing flexible logging capabilities.
Definition: herrlog.hh:122
static void set_is_color_output(bool is_color_output)
Set the is color output object.
Definition: herrlog.hh:263
static void info(const char *format, Args... args)
Logs messages of type info.
Definition: herrlog.hh:309
static void trace(const char *format, Args... args)
Logs messages of type trace.
Definition: herrlog.hh:277
static void error(const char *format, Args... args)
Logs messages of type error. Furthermore closes the output file and exits the program.
Definition: herrlog.hh:326
static void set_type(LogType log_type)
Sets the log type, default is LogType::All.
Definition: herrlog.hh:215
static void fatal(const char *format, Args... args)
Logs messages of type fatal. Exits the program and creates a core dump.
Definition: herrlog.hh:357
static void set_datetime_format(const char *datetime_format)
Set the datetime format object, default is "%Y-%m-%d %H:%M:%S".
Definition: herrlog.hh:245
static void set_output_buffer(std::ostream &output_buffer)
Set the output buffer object.
Definition: herrlog.hh:254
static void debug(const char *format, Args... args)
Logs messages of type debug.
Definition: herrlog.hh:293
static void warn(const char *format, Args... args)
Logs messages of type warning. Doesn't exit the program, just notifies the issue.
Definition: herrlog.hh:342
static void set_output_file_name(std::string output_file_name)
Set the output file name object.
Definition: herrlog.hh:222
Set of ANSI colors, more can be found here: https://gist.github.com/JBlond/2fea43a3049b38287e5e9cefc8...
Definition: herrlog.hh:49