TTTT Analysis  0.1
log.hpp
Go to the documentation of this file.
1 
33 #ifndef log_hpp
34 #define log_hpp
35 
36 #include <iostream>
37 #include <fstream>
38 #include <cstring>
39 #include <map>
40 
41 namespace fv::util{
42 enum LogPriority {
43  kLogEmergency = 7, // system is unusable
44  kLogAlert = 6, // action must be taken immediately
45  kLogCritical = 5, // critical conditions
46  kLogError = 4, // error conditions
47  kLogWarning = 3, // warning conditions
48  kLogNotice = 2, // normal, but significant, condition
49  kLogInfo = 1, // informational message
50  kLogDebug = 0 // debug-level message
51 };
52 
53 #define CRITICAL(x,y) std::clog << fv::util::LogPriority::kLogCritical << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush; std::cout << "Errors encountered! See log file for details."<<std::endl;exit(y)
54 #define ERROR(x) std::clog << fv::util::LogPriority::kLogError << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush
55 #define WARNING(x) std::clog << fv::util::LogPriority::kLogWarning << x << std::flush
56 #define INFO(x) std::clog << fv::util::LogPriority::kLogInfo << x << std::flush
57 #define DEBUG(x) std::clog << fv::util::LogPriority::kLogDebug << __FILE__ << "@L" << __LINE__ << " :: " << x << std::flush
58 
62 std::ostream& operator<< (std::ostream& os, const LogPriority& log_priority);
63 
64 class Log : public std::basic_streambuf<char, std::char_traits<char> > {
65 private:
66  std::string buffer_;
67  std::ofstream logfile;
68  LogPriority priority_curr;
69  LogPriority priority_set;
70  inline static Log* singleton = nullptr;
71  const std::map<LogPriority,std::string> name_map = {{kLogEmergency, "EMERGENCY"},
72  {kLogAlert, "ALERT"},
73  {kLogCritical, "CRITICAL"},
74  {kLogError, "ERROR"},
75  {kLogWarning, "WARNING"},
76  {kLogNotice, "NOTICE"},
77  {kLogInfo, "INFO"},
78  {kLogDebug, "DEBUG"}};
79 
80  friend std::ostream& operator<< (std::ostream& os, const LogPriority& log_priority){
81  static_cast<Log *>(os.rdbuf())->priority_curr = log_priority;
82  return os;
83  }
84 protected:
85  int sync(){
86  if (buffer_.length()) {
87  if (priority_curr >= priority_set){
88  logfile << name_map.at(priority_curr) << ": " << buffer_ << std::endl << std::flush;
89  }
90  buffer_.erase();
91  /* priority_curr = kLogDebug; // default to debug for each message */
92  }
93  return 0;
94  }
95  int overflow(int c){
96  if (c != EOF) {
97  buffer_ += static_cast<char>(c);
98  } else {
99  sync();
100  }
101  return c;
102  }
103 public:
104  explicit Log(std::string filename, LogPriority priority)
105  :logfile(filename, std::ofstream::out){
106  priority_set = priority;
107  priority_curr = kLogDebug;
108  }
109 
110  static Log& init_logger(std::string filename, LogPriority priority){
111  if (singleton == nullptr){
112  singleton = new Log(filename, priority);
113  std::cout << "Writing log data to " << filename << std::endl;
114  std::clog.rdbuf(singleton);
115  }
116  return *singleton;
117  }
118 };
119 }
120 #endif // log_hpp