SOPT
Sparse OPTimisation
logging.h
Go to the documentation of this file.
1 #ifndef SOPT_LOGGING_H
2 #define SOPT_LOGGING_H
3 
4 #include "sopt/config.h"
5 #include "sopt/exception.h"
6 
7 #include <map>
8 #include <memory>
9 #include <cstring>
10 
11 namespace sopt::logging {
12 
14 class Log {
15 public:
16 
18  enum Level {
19  trace = 0,
20  debug = 10,
21  info = 20,
22  warn = 30, warning = 30,
23  error = 40,
24  critical = 50, always = 50
25  };
26  static const int end_color{-10};
27 
28 
30  using LogMap = std::map<std::string, Log>;
31 
33  using LevelMap = std::map<std::string, int>;
34 
36  using ColorCodes = std::map<int, std::string>;
37 
38 
39 private:
40 
42  thread_local static LogMap existingLogs;
43 
45  thread_local static LevelMap defaultLevels;
46 
48  static bool showTimestamp;
49 
51  static bool showLogLevel;
52 
54  static bool showLoggerName;
55 
57  static bool useShellColors;
58 
59 
60 public:
61 
63  static void setLevel(const std::string& name, int level);
64  static void setLevels(const LevelMap& logLevels);
65 
66 protected:
67 
70 
72  Log(const std::string& name);
73 
75  Log(const std::string& name, int level);
76 
78 
80  static std::string getColorCode(int level);
81 
82 
83 public:
84 
87  static Log& getLog(const std::string& name);
88 
90  int getLevel() const {
91  return _level;
92  }
93 
95  Log& setLevel(int level) {
96  _level = level;
97  return *this;
98  }
99 
101  static Level getLevelFromName(const std::string& level);
102 
104  static std::string getLevelName(int level);
105 
107  std::string getName() const {
108  return _name;
109  }
110 
112  Log& setName(const std::string& name) {
113  _name = name;
114  return *this;
115  }
116 
118  bool isActive(int level) const {
119  return (level >= _level);
120  }
121 
122 
123 private:
124 
126  std::string _name;
127 
129  int _level;
130 
131 protected:
132 
134  void log(int level, const std::string& message);
135 
137  std::string formatMessage(int level, const std::string& message);
138 
139 public:
140 
142  friend std::ostream& operator<<(Log& log, int level);
143 
144 };
145 
146 
148 std::ostream& operator<<(Log& log, int level);
149 
151 inline Log& getLog() { return Log::getLog("sopt::"); }
152 
154 inline void set_level(const std::string &level) {
156 }
157 
158 
161 template <typename Arg>
162 void applyFormat(std::stringstream& ss, char*& pos, Arg&& arg) {
163  char* delim = strstr(pos, "{}");
164  if (delim != NULL) {
165  ss << std::string(pos, delim-pos) << std::forward<Arg>(arg);
166  pos = delim + 2;
167  }
168  else {
169  SOPT_THROW("Insufficient placeholders for number of arguments!");
170  }
171 }
172 
174 template <typename... Args>
175 inline std::string mkFormattedString(const char* txt, Args&& ... args) {
176  std::string mys = txt;
177  std::stringstream rtn;
178  char* pos = (char*)txt;
179  ((void)applyFormat(rtn, pos, std::forward<Args>(args)), ...);
180  rtn << std::string(pos);
181  return rtn.str();
182 }
183 
184 inline const std::string& mkFormattedString(const std::string& txt) { return txt; }
185 
188 
192 #define SOPT_MSG_LVL(lvl, ...) \
193  do { \
194  if (sopt::logging::getLog().isActive(lvl)) { \
195  sopt::logging::getLog() << lvl << sopt::logging::mkFormattedString(__VA_ARGS__) << '\n'; \
196  } \
197  } while (0)
198 
200 #define SOPT_LOG_(TYPE, ...) \
201  SOPT_MSG_LVL(sopt::logging::Log::TYPE, __VA_ARGS__)
202 
203 
205 
206 }
207 
209 #define SOPT_NOTICE(...) SOPT_LOG_(critical, __VA_ARGS__)
211 #define SOPT_ERROR(...) SOPT_LOG_(error, __VA_ARGS__)
213 #define SOPT_WARN(...) SOPT_LOG_(warn, __VA_ARGS__)
215 #define SOPT_INFO(...) SOPT_LOG_(info, __VA_ARGS__)
217 #define SOPT_DEBUG(...) SOPT_LOG_(debug, __VA_ARGS__)
220 #define SOPT_TRACE(...) SOPT_LOG_(trace, __VA_ARGS__)
221 
223 #define SOPT_HIGH_LOG(...) SOPT_LOG_(critical, __VA_ARGS__)
225 #define SOPT_MEDIUM_LOG(...) SOPT_LOG_(info, __VA_ARGS__)
227 #define SOPT_LOW_LOG(...) SOPT_LOG_(debug, __VA_ARGS__)
228 
229 #endif
Logging system for controlled & formatted writing to stdout.
Definition: logging.h:14
std::map< std::string, int > LevelMap
Typedef for a collection of named log levels.
Definition: logging.h:33
static Log & getLog(const std::string &name)
Definition: logging.cc:57
static Level getLevelFromName(const std::string &level)
Get a log level enum from a string.
Definition: logging.cc:138
static std::string getLevelName(int level)
Get the std::string representation of a log level.
Definition: logging.cc:95
static const int end_color
Special "level-like" code to end coloring.
Definition: logging.h:26
friend std::ostream & operator<<(Log &log, int level)
The streaming operator can use Log's internals.
Definition: logging.cc:190
bool isActive(int level) const
Will this log level produce output on this logger at the moment?
Definition: logging.h:118
std::map< std::string, Log > LogMap
Typedef for a collection of named logs.
Definition: logging.h:30
int getLevel() const
Get the priority level of this logger.
Definition: logging.h:90
std::map< int, std::string > ColorCodes
Typedef for a collection of shell color codes, accessed by log level.
Definition: logging.h:36
Level
Log priority levels.
Definition: logging.h:18
static void setLevel(const std::string &name, int level)
Set the log levels.
std::string getName() const
Get the name of this logger.
Definition: logging.h:107
Log & setLevel(int level)
Set the priority level of this logger.
Definition: logging.h:95
Log & setName(const std::string &name)
Set the name of this logger.
Definition: logging.h:112
static void setLevels(const LevelMap &logLevels)
Definition: logging.cc:49
#define SOPT_THROW(MSG)
Definition: exception.h:46
void set_level(const std::string &level)
Method to set the logging level of the default Log object.
Definition: logging.h:154
Log & getLog()
Access method to default Log object.
Definition: logging.h:151
std::string mkFormattedString(const char *txt, Args &&... args)
Helper method to construct formatted string.
Definition: logging.h:175
ostream & operator<<(Log &log, int level)
Streaming output to a logger must have a Log::Level/int as its first argument.
Definition: logging.cc:190
void applyFormat(std::stringstream &ss, char *&pos, Arg &&arg)
Definition: logging.h:162