Helios++
Helios software for LiDAR simulations
file_logger.hpp
1 #pragma once
2 
3 //TODO: add log rolling
4 //logger that writes to file
8 class file_logger : public logger {
9 protected:
10  // *** ATTRIBUTES *** //
11  // ******************** //
15  std::string file_name;
19  std::ofstream file;
23  std::chrono::seconds reopen_interval;
27  std::chrono::system_clock::time_point last_reopen;
28 
29 public:
30  // *** CONSTRUCTION / DESTRUCTION *** //
31  // ************************************ //
32  file_logger() = delete;
38  file_logger(const logging_config_t& config):logger(config) {
39  //grab the file name
40  auto name = config.find("file_name");
41  if(name == config.end())
42  throw std::runtime_error("No output file provided to file logger");
43  file_name = name->second;
44 
45  //if we specify an interval
46  reopen_interval = std::chrono::seconds(300);
47  auto interval = config.find("reopen_interval");
48  if(interval != config.end()){
49  try {
50  reopen_interval = std::chrono::seconds(
51  std::stoul(interval->second)
52  );
53  }
54  catch(...) {
55  throw std::runtime_error(
56  interval->second + " is not a valid reopen interval"
57  );
58  }
59  }
60 
61  //crack the file open
62  reopen();
63  }
64 
65  // *** M E T H O D S *** //
66  // *********************** //
70  virtual void log(const std::string& message, const log_level level) {
71  if(level < LOG_LEVEL_CUTOFF) return;
72  std::string output;
73  output.reserve(message.length() + 64);
74  //output.append(timestamp());
75  //output.append(uncolored.find(level)->second);
76  output.append(message);
77  output.push_back('\n');
78  log(output);
79  }
80 
84  void log(const std::string& message) override{
85  lock.lock();
86  file << message;
87  file.flush();
88  lock.unlock();
89  reopen();
90  }
91 protected:
95  void reopen() {
96  //TODO: use CLOCK_MONOTONIC_COARSE
97  //check if it should be closed and reopened
98  auto now = std::chrono::system_clock::now();
99  lock.lock();
100  if(now - last_reopen > reopen_interval) {
101  last_reopen = now;
102  try{ file.close(); }catch(...){}
103  try {
104  file.open(file_name, std::ofstream::out | std::ofstream::app);
105  last_reopen = std::chrono::system_clock::now();
106  }
107  catch(std::exception& e) {
108  try{ file.close(); }catch(...){}
109  throw e;
110  }
111  }
112  lock.unlock();
113  }
114 };
Class representing a logger capable of writing to files.
Definition: file_logger.hpp:8
void log(const std::string &message) override
Definition: file_logger.hpp:84
std::chrono::seconds reopen_interval
Reopen interval in seconds.
Definition: file_logger.hpp:23
virtual void log(const std::string &message, const log_level level)
Definition: file_logger.hpp:70
std::chrono::system_clock::time_point last_reopen
Time point when last reopen took place.
Definition: file_logger.hpp:27
std::string file_name
Name of output file.
Definition: file_logger.hpp:15
file_logger(const logging_config_t &config)
File logger constructor.
Definition: file_logger.hpp:38
std::ofstream file
Output file stream.
Definition: file_logger.hpp:19
void reopen()
Reopen the log file in a thread-safe fashion.
Definition: file_logger.hpp:95
Class providing the base for any logger.
Definition: logger.hpp:8
std::mutex lock
Mutex to handle concurrent log writes.
Definition: logger.hpp:15