dodo  0.0.1
A C++ library to create containerized Linux services
logger.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of the dodo library (https://github.com/jmspit/dodo).
3  * Copyright (c) 2019 Jan-Marten Spit.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, version 3.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /**
19  * @file logger.hpp
20  * Defines the dodo::network::Logger class.
21  */
22 
23 #include <threads/mutex.hpp>
24 
25 #include <fstream>
26 #include <map>
27 #include <functional>
28 
29 #ifndef common_logger_hpp
30 #define common_logger_hpp
31 
32 namespace dodo::common {
33 
34  class Config;
35 
36  /**
37  * A Logger interface. Calls to log( LogLevel level, const std::string message ) are serialized internally
38  * and thus thread-safe.
39  */
40  class Logger {
41  public:
42 
43  /**
44  * The level of a log entry.
45  */
46  enum class LogLevel {
47  Fatal, /**< The program could not continue. */
48  Error, /**< The program signaled an error. */
49  Warning, /**< The program signaled a warning. */
50  Info, /**< The program signaled an informational message. */
51  Statistics, /**< The program signaled runtime statistics. */
52  Debug, /**< The program produced debug info. */
53  Trace, /**< The program produced trace info. */
54  };
55 
56  /**
57  * Destination flags.
58  */
59  enum Destination {
60  Console = 1,
61  File = 2,
62  Syslog = 4,
63  };
64 
65  /**
66  * File Logging parameters.
67  */
68  struct FileParams {
69  /** The directory to write the log files in. */
70  std::string directory;
71  /** The maximum size of a logfile. */
72  size_t max_size_mib = 10;
73  /** The maximum number of files to keep besides the active log file. */
74  size_t max_file_trail = 4;
75  /** the filename of the active log */
76  std::string active_log;
77  /** the ofstream of the active log. */
78  std::ofstream file;
79  /** current file size */
80  size_t filesize = 0;
81  };
82 
83  /**
84  * syslog logging parameters.
85  */
86  struct SyslogParams {
87  /** The syslog facility to use. */
88  int facility;
89  };
90 
91  /**
92  * Log a Fatal log entry. These are always logged as Fatal is the lowest LogLevel.
93  * Calling is thread-safe.
94  * @param message The fatal log message.
95  */
96  void fatal( const std::string &message );
97 
98  /**
99  * Log a Error log entry. These are only logged when LogLevel >= Error.
100  * Calling is thread-safe.
101  * @param message The Error log message.
102  */
103  void error( const std::string &message );
104 
105  /**
106  * Log a Warning log entry. These are only logged when LogLevel >= Warning.
107  * Calling is thread-safe.
108  * @param message The Warning log message.
109  */
110  void warning( const std::string &message );
111 
112  /**
113  * Log a Info log entry. These are only logged when LogLevel >= Info.
114  * Calling is thread-safe.
115  * @param message The Info log message.
116  */
117  void info( const std::string &message );
118 
119  /**
120  * Log a Statistics log entry. These are only logged when LogLevel >= Statistics.
121  * Calling is thread-safe.
122  * @param message The Statistics log message.
123  */
124  void statistics( const std::string &message );
125 
126  /**
127  * Log a Debug log entry. These are only logged when LogLevel >= Debug.
128  * Calling is thread-safe.
129  * @param message The Debug log message.
130  */
131  void debug( const std::string &message );
132 
133  /**
134  * Log a Trace log entry. These are only logged when LogLevel >= Trace.
135  * Calling is thread-safe.
136  * @param message The Trace log message.
137  */
138  void trace( const std::string &message );
139 
140  /**
141  * Initialize the Logger singleton.
142  * @param config The Config to use.
143  * @return A pointer to the singleton.
144  */
145  static Logger* initialize( const Config& config );
146 
147 
148  /**
149  * Get the Logger singleton - initialize() must have been called first.
150  * @param config The Config to use.
151  * @return A pointer to the singleton.
152  */
153  static Logger* getLogger();
154 
155  /**
156  * Return the LogLevel as a string (as used in console and file).
157  * @param level The LogLevel.
158  * @param acronym If true, return a uppercase character triplet for use in log files.
159  * @return A string representation of the LogLevel.
160  */
161  static std::string LogLevelAsString( LogLevel level, bool acronym );
162 
163  /**
164  * Return the string as a LogLevel. Note this will default to Info if string is not recognized.
165  * @param slevel The LogLevel as a string.
166  * @return The LogLevel.
167  */
168  static LogLevel StringAsLogLevel( const std::string slevel );
169 
170  protected:
171 
172  /**
173  * Construct against a config.
174  * @param config The configuration to read from.
175  */
176  Logger( const Config& config );
177 
178  /**
179  * Destructor.
180  */
181  virtual ~Logger();
182 
183  /**
184  * Log a log entry. The entry is only written when level <= the loglevel specified in the Config,
185  * and silently ignored otherwise. Calling is thread-safe, but the lock is not acquired at all if
186  * the entry is ignored by level.
187  * @param level The logLevel of the messsage.
188  * @param message The log message.
189  */
190  void log( LogLevel level, const std::string &message );
191 
192  /**
193  * Format a LogLine.
194  * @param level The logLevel of the messsage.
195  * @param message The log message.
196  * @return A formatted log line.
197  */
198  std::string formatMessage( LogLevel level, const std::string &message );
199 
200 
201  /**
202  * Get FileParams from the Config into file_params_.
203  * @param config The Config to get the FileParams from.
204  */
205  void getFileParams( const Config& config );
206 
207  /**
208  * Check and rotate the log file if it exceeds the size limit,
209  * delete older logs if needed.
210  */
211  void checkRotate();
212 
213  /**
214  * Map a LogLevel to a syslog level.
215  * @param level The LogLevel to map.
216  * @return The mapped syslog level.
217  */
218  int mapLeveltoSyslog( LogLevel level );
219 
220  /**
221  * threads::Mutex to serialize log writing.
222  */
224 
225  /**
226  * The singleton.
227  */
228  static Logger* logger_;
229 
230  /**
231  * Destinations as bit flags
232  */
233  uint8_t destinations_;
234 
235  /**
236  * Map Destination to LogLevel.
237  */
238  std::map<uint8_t,LogLevel> levels_;
239 
240  /**
241  * The hostname cached in the constructor.
242  */
243  std::string hostname_;
244 
245  /**
246  * Parameters for the file Destination.
247  */
249 
250  /**
251  * Parameters for the syslog Destination.
252  */
254 
255  /**
256  * Track when rotation was last checked.
257  */
259 
260  /**
261  * Application::~Application() will destruct this singleton
262  */
263  friend class Application;
264 
265  };
266 
267  /**
268  * Macro to log Fatal.
269  * @param what The info to log. As the argument is fed to a dodo::common::Puts() it can be a << pipe-lined expression.
270  */
271  #define log_Fatal( what ) common::Logger::getLogger()->fatal( dodo::common::Puts() << what )
272 
273  /**
274  * Macro to log Error.
275  * @param what The info to log. As the argument is fed to a dodo::common::Puts() it can be a << pipe-lined expression.
276  */
277  #define log_Error( what ) common::Logger::getLogger()->error( dodo::common::Puts() << what )
278 
279  /**
280  * Macro to log Warning.
281  * @param what The info to log. As the argument is fed to a dodo::common::Puts() it can be a << pipe-lined expression.
282  */
283  #define log_Warning( what ) common::Logger::getLogger()->warning( dodo::common::Puts() << what )
284 
285  /**
286  * Macro to log Info.
287  * @param what The info to log. As the argument is fed to a dodo::common::Puts() it can be a << pipe-lined expression.
288  */
289  #define log_Info( what ) common::Logger::getLogger()->info( dodo::common::Puts() << what )
290 
291  /**
292  * Macro to log Statistics.
293  * @param what The info to log. As the argument is fed to a dodo::common::Puts() it can be a << pipe-lined expression.
294  */
295  #define log_Statistics( what ) common::Logger::getLogger()->statistics( dodo::common::Puts() << what )
296 
297  /**
298  * Macro to log Debug.
299  * @param what The info to log. As the argument is fed to a dodo::common::Puts() it can be a << pipe-lined expression.
300  */
301  #ifndef NDEBUG
302  #define log_Debug( what ) common::Logger::getLogger()->debug( dodo::common::Puts() << what )
303  #else
304  #define log_Debug( what )
305  #endif
306 
307  /**
308  * Macro to log Trace.
309  * @param what The info to log. As the argument is fed to a dodo::common::Puts() it can be a << pipe-lined expression.
310  */
311  #ifndef NDEBUG
312  #define log_Trace( what ) common::Logger::getLogger()->trace( dodo::common::Puts() << what )
313  #else
314  #define log_Trace( what )
315  #endif
316 
317 }
318 
319 #endif
dodo::common::Logger::FileParams::max_file_trail
size_t max_file_trail
The maximum number of files to keep besides the active log file.
Definition: logger.hpp:74
dodo::common::Logger::LogLevelAsString
static std::string LogLevelAsString(LogLevel level, bool acronym)
Return the LogLevel as a string (as used in console and file).
Definition: logger.cpp:228
dodo::common::Logger::LogLevel::Error
@ Error
The program signaled an error.
dodo::common::Logger::file_params_
FileParams file_params_
Parameters for the file Destination.
Definition: logger.hpp:248
dodo::common::Logger::error
void error(const std::string &message)
Log a Error log entry.
Definition: logger.cpp:116
dodo::common::Logger
A Logger interface.
Definition: logger.hpp:40
dodo::common::Logger::mutex_
static threads::Mutex mutex_
threads::Mutex to serialize log writing.
Definition: logger.hpp:223
dodo::common::Logger::SyslogParams::facility
int facility
The syslog facility to use.
Definition: logger.hpp:88
dodo::common::Logger::log
void log(LogLevel level, const std::string &message)
Log a log entry.
Definition: logger.cpp:88
dodo::common::Logger::FileParams::active_log
std::string active_log
the filename of the active log
Definition: logger.hpp:76
dodo::common::Logger::getFileParams
void getFileParams(const Config &config)
Get FileParams from the Config into file_params_.
Definition: logger.cpp:180
dodo::common::Logger::Logger
Logger(const Config &config)
Construct against a config.
Definition: logger.cpp:46
dodo::common::Logger::statistics
void statistics(const std::string &message)
Log a Statistics log entry.
Definition: logger.cpp:128
dodo::common::Logger::FileParams
File Logging parameters.
Definition: logger.hpp:68
dodo::common::Logger::LogLevel::Statistics
@ Statistics
The program signaled runtime statistics.
dodo::common::Logger::FileParams::filesize
size_t filesize
current file size
Definition: logger.hpp:80
dodo::common::Logger::~Logger
virtual ~Logger()
Destructor.
Definition: logger.cpp:71
dodo::common::Logger::logger_
static Logger * logger_
The singleton.
Definition: logger.hpp:228
dodo::common::Logger::LogLevel::Fatal
@ Fatal
The program could not continue.
dodo::common::Logger::warning
void warning(const std::string &message)
Log a Warning log entry.
Definition: logger.cpp:120
dodo::common::Logger::debug
void debug(const std::string &message)
Log a Debug log entry.
Definition: logger.cpp:132
dodo::common::Logger::FileParams::file
std::ofstream file
the ofstream of the active log.
Definition: logger.hpp:78
dodo::threads::Mutex
A Mutex to synchronize access to resources between threads.
Definition: mutex.hpp:39
dodo::common::Logger::LogLevel::Warning
@ Warning
The program signaled a warning.
dodo::common::Logger::levels_
std::map< uint8_t, LogLevel > levels_
Map Destination to LogLevel.
Definition: logger.hpp:238
dodo::common::Logger::hostname_
std::string hostname_
The hostname cached in the constructor.
Definition: logger.hpp:243
dodo::common::Logger::formatMessage
std::string formatMessage(LogLevel level, const std::string &message)
Format a LogLine.
Definition: logger.cpp:205
dodo::common::Logger::LogLevel::Trace
@ Trace
The program produced trace info.
dodo::common::Config
Singleton interface to a (read-only) deployment configuration, combining data from the deployment con...
Definition: config.hpp:52
dodo::common::Logger::Destination
Destination
Destination flags.
Definition: logger.hpp:59
dodo::common::Logger::trace
void trace(const std::string &message)
Log a Trace log entry.
Definition: logger.cpp:136
dodo::common::Logger::LogLevel::Info
@ Info
The program signaled an informational message.
dodo::common::Logger::FileParams::max_size_mib
size_t max_size_mib
The maximum size of a logfile.
Definition: logger.hpp:72
dodo::common::Logger::syslog_params_
SyslogParams syslog_params_
Parameters for the syslog Destination.
Definition: logger.hpp:253
dodo::common::Logger::getLogger
static Logger * getLogger()
Get the Logger singleton - initialize() must have been called first.
Definition: logger.cpp:83
dodo::common
Common and utility interfaces.
Definition: application.hpp:29
dodo::common::Logger::initialize
static Logger * initialize(const Config &config)
Initialize the Logger singleton.
Definition: logger.cpp:77
dodo::common::Logger::LogLevel
LogLevel
The level of a log entry.
Definition: logger.hpp:46
dodo::common::Logger::destinations_
uint8_t destinations_
Destinations as bit flags.
Definition: logger.hpp:233
dodo::common::Logger::mapLeveltoSyslog
int mapLeveltoSyslog(LogLevel level)
Map a LogLevel to a syslog level.
Definition: logger.cpp:140
dodo::common::Application
Red tape wrapper class for applications, from command line to services.
Definition: application.hpp:61
dodo::common::Logger::fatal
void fatal(const std::string &message)
Log a Fatal log entry.
Definition: logger.cpp:112
dodo::common::Logger::info
void info(const std::string &message)
Log a Info log entry.
Definition: logger.cpp:124
dodo::common::Logger::rotate_throttle_counter_
size_t rotate_throttle_counter_
Track when rotation was last checked.
Definition: logger.hpp:258
dodo::common::Logger::StringAsLogLevel
static LogLevel StringAsLogLevel(const std::string slevel)
Return the string as a LogLevel.
Definition: logger.cpp:217
dodo::common::Logger::checkRotate
void checkRotate()
Check and rotate the log file if it exceeds the size limit, delete older logs if needed.
Definition: logger.cpp:153
dodo::common::Logger::SyslogParams
syslog logging parameters.
Definition: logger.hpp:86
dodo::common::Logger::LogLevel::Debug
@ Debug
The program produced debug info.
mutex.hpp
dodo::common::Logger::FileParams::directory
std::string directory
The directory to write the log files in.
Definition: logger.hpp:70