Libftpp
A modern C++ library
logger.cpp
Go to the documentation of this file.
1 #include "logger.hpp"
2 
4 {
5  setOutputFile("");
6 }
7 
8 Logger::Logger(const std::string& outputfile, LogLevel level) : _currentLevel(level)
9 {
10  setOutputFile(outputfile);
11 }
12 
13 const std::string Logger::getOutputPathFile() const
14 {
15  return _outputFilePath + _logFilename + ".log";
16 }
17 
19 {
20  if (_logFile.is_open())
21  _logFile.close();
22  _writer << std::flush;
23 }
24 
26 {
27  static Logger instance;
28  return instance;
29 }
30 
32 {
33  _currentLevel = level;
34 }
35 
36 void Logger::setOutputFile(const std::string& filename)
37 {
38  char buffer[1024];
39  if (!getcwd(buffer, 1024))
40  throw std::runtime_error("Current path for Output file could not be determined try to "
41  "increase filename buffer size" +
42  std::to_string(errno));
43  if (filename.empty())
44  _logFilename = getCurrentTime();
45  else
46  _logFilename = filename;
47 
48  if (_outputFilePath.empty())
49  _outputFilePath = std::string(buffer) + "/logs/";
50 
51  std::string dirPath = _outputFilePath;
52  if (!dirPath.empty() && dirPath.back() == '/')
53  dirPath.pop_back();
54 
55  struct stat st;
56  if (stat(dirPath.c_str(), &st) != 0)
57  {
58  if (mkdir(dirPath.c_str(), 0755) != 0 && errno != EEXIST)
59  {
60  throw std::runtime_error(std::string("Could not create log directory: ") +
61  std::to_string(errno));
62  }
63  }
64  else if (!S_ISDIR(st.st_mode))
65  {
66  throw std::runtime_error("Log path exists but is not a directory");
67  }
68 
69  if (_logFile.is_open())
70  _logFile.close();
71 
72  // std::ios::out -> cree si il existe pas + ecriture
73  // std::ios::app -> O_APPEND se place et ecris a la fin du fichier de destination
74  _logFile.open(_outputFilePath + _logFilename + ".log", std::ios::out | std::ios::app);
75  if (!_logFile.is_open())
76  throw std::runtime_error("Could not open log file: " + _logFilename + ".log");
77 }
78 
79 std::string Logger::getCurrentTime() const
80 {
81  auto now = std::chrono::system_clock::now();
82  std::time_t clock = std::chrono::system_clock::to_time_t(now);
83  std::tm localTime;
84 
85  localtime_r(&clock, &localTime); // Linux / Mac
86  std::ostringstream oss;
87  oss << std::put_time(&localTime, "%Y-%m-%d | %H:%M:%S");
88  return oss.str();
89 }
90 
91 std::string Logger::logLevelToString(LogLevel level) const
92 {
93  switch (level)
94  {
95  case LogLevel::DEBUG:
96  return "DEBUG";
97  case LogLevel::INFO:
98  return "INFO";
99  case LogLevel::WARNING:
100  return "WARNING";
101  case LogLevel::ERROR:
102  return "ERROR";
103  default:
104  return "UNKNOWN";
105  }
106 }
107 
113 void Logger::log(LogLevel level, const std::string& message)
114 {
115  if (level < _currentLevel)
116  return;
117  std::lock_guard<std::mutex> lock(_fileMutex);
118  _logFile << "[" << logLevelToString(level) << "]" << "[" << getCurrentTime() << "] " << message
119  << std::endl;
120 }
121 
127 void Logger::logConsole(LogLevel level, const std::string& message)
128 {
129  if (level < _currentLevel)
130  return;
131  _writer << "[" << logLevelToString(level) << "]" << "[" << getCurrentTime() << "] " << message
132  << std::endl;
133 }
Logger class for logging messages to console and file with different log levels. This class is implem...
Definition: logger.hpp:47
void setLogLevel(LogLevel level)
Definition: logger.cpp:31
void logConsole(LogLevel level, const std::string &message)
Log a message to the console if the log level is sufficient.
Definition: logger.cpp:127
void log(LogLevel level, const std::string &message)
Log a message to the log file if the log level is sufficient.
Definition: logger.cpp:113
static Logger & instance()
Definition: logger.cpp:25
const std::string getOutputPathFile() const
Definition: logger.cpp:13
Logger()
Definition: logger.cpp:3
~Logger()
Definition: logger.cpp:18
void setOutputFile(const std::string &filename)
Definition: logger.cpp:36
LogLevel
Definition: logger.hpp:19