MaCh3  2.4.2
Reference Guide
MaCh3Logger.h
Go to the documentation of this file.
1 #pragma once
2 
3 // C++ Includes
4 #include <iostream>
5 #include <sstream>
6 #include <functional>
7 #include <string>
8 #include <exception>
9 
10 // MaCh3 Includes
11 #include "Manager/Core.h"
12 
14 // spdlog Includes
15 #include "spdlog/spdlog.h"
17 
32 
33 #define MACH3LOG_TRACE SPDLOG_TRACE
34 #define MACH3LOG_DEBUG SPDLOG_DEBUG
35 #define MACH3LOG_INFO SPDLOG_INFO
36 #define MACH3LOG_WARN SPDLOG_WARN
37 #define MACH3LOG_ERROR SPDLOG_ERROR
38 #define MACH3LOG_CRITICAL SPDLOG_CRITICAL
39 #define MACH3LOG_OFF SPDLOG_OFF
40 
43 inline spdlog::level::level_enum get_default_log_level() {
44  #ifdef SPDLOG_ACTIVE_LEVEL
45  switch (SPDLOG_ACTIVE_LEVEL) {
46  case SPDLOG_LEVEL_TRACE: return spdlog::level::trace;
47  case SPDLOG_LEVEL_DEBUG: return spdlog::level::debug;
48  case SPDLOG_LEVEL_INFO: return spdlog::level::info;
49  case SPDLOG_LEVEL_WARN: return spdlog::level::warn;
50  case SPDLOG_LEVEL_ERROR: return spdlog::level::err;
51  case SPDLOG_LEVEL_CRITICAL: return spdlog::level::critical;
52  case SPDLOG_LEVEL_OFF: return spdlog::level::off;
53  default: throw std::runtime_error("Unknown SPDLOG_ACTIVE_LEVEL");
54  }
55  #else
56  throw std::runtime_error("SPDLOG_ACTIVE_LEVEL is not defined");
57  #endif
58 }
59 
61 inline void SetMaCh3LoggerFormat()
62 {
63  //KS: %H for hour, %M for minute, %S for second, [%s:%#] for class and line
64  //For documentation see https://github.com/gabime/spdlog/wiki/3.-Custom-formatting
65  #ifdef DEBUG
66  //spdlog::set_pattern("[%H:%M:%S][%s:%#][%^%l%$] %v");
67  spdlog::set_pattern("[%s:%#][%^%l%$] %v");
68  #else
69  //spdlog::set_pattern("[%H:%M:%S][%s][%^%l%$] %v");
70  spdlog::set_pattern("[%s][%^%l%$] %v");
71  #endif
72 
73  spdlog::set_level(get_default_log_level());
74 }
75 
99 template <typename Func, typename LogFunc, typename... Args>
100 void LoggerPrint(const std::string& LibName, LogFunc logFunction, Func&& func, Args&&... args)
101 {
102  // Create a stringstream to capture the output
103  std::stringstream sss_cout;
104  std::stringstream sss_cerr;
105 
106  // Save the original stream buffers
107  std::streambuf* coutBuf = nullptr;
108  std::streambuf* cerrBuf = nullptr;
109 
110  // This should be rare but in case buffers no longer exist ignore
111  if (std::cout.rdbuf() && std::cerr.rdbuf()) {
112  coutBuf = std::cout.rdbuf(); // Save original cout buffer
113  cerrBuf = std::cerr.rdbuf(); // Save original cerr buffer
114 
115  // Redirect std::cout and std::cerr to the stringstream buffer
116  std::cout.rdbuf(sss_cout.rdbuf());
117  std::cerr.rdbuf(sss_cerr.rdbuf());
118  }
119 
120  try {
121  // Call the provided function
122  func(std::forward<Args>(args)...);
123 
124  // Restore the original stream buffers
125  if (coutBuf) std::cout.rdbuf(coutBuf);
126  if (cerrBuf) std::cerr.rdbuf(cerrBuf);
127 
128  std::string line;
129  while (std::getline(sss_cout, line))
130  {
131  auto formatted_message = fmt::format("[{}] {}", LibName, line);
132  logFunction(formatted_message);
133  }
134  while (std::getline(sss_cerr, line))
135  {
136  auto formatted_message = fmt::format("[{}] {}", LibName, line);
137  logFunction(formatted_message);
138  }
139  } catch (std::runtime_error &err) {
140  // Restore the original buffers in case of an exception
141  std::cout.rdbuf(coutBuf);
142  std::cerr.rdbuf(cerrBuf);
143 
144  std::cout << "\nConsole cout output:" << std::endl;
145  std::cout << sss_cout.rdbuf()->str() << std::endl;
146 
147  std::cout << "\nConsole cerr output:" << std::endl;
148  std::cout << sss_cerr.rdbuf()->str() << std::endl;
149  throw;
150  }
151 }
KS: Core MaCh3 definitions and compile-time configuration utilities.
#define _MaCh3_Safe_Include_Start_
KS: Avoiding warning checking for headers.
Definition: Core.h:126
#define _MaCh3_Safe_Include_End_
KS: Restore warning checking after including external headers.
Definition: Core.h:140
spdlog::level::level_enum get_default_log_level()
KS: Map string macro to spdlog::level enum.
Definition: MaCh3Logger.h:43
void SetMaCh3LoggerFormat()
Set messaging format of the logger.
Definition: MaCh3Logger.h:61
void LoggerPrint(const std::string &LibName, LogFunc logFunction, Func &&func, Args &&... args)
KS: This is bit convoluted but this is to allow redirecting cout and errors from external library int...
Definition: MaCh3Logger.h:100