ModErn Text Analysis
META Enumerates Textual Applications
logger.h
Go to the documentation of this file.
1 
11 #ifndef META_LOGGER_H_
12 #define META_LOGGER_H_
13 
14 #include <chrono>
15 #include <functional>
16 #include <iostream>
17 #include <iomanip>
18 #include <sstream>
19 #include <vector>
20 
21 namespace meta
22 {
23 
27 namespace logging
28 {
29 
34 class logger
35 {
36  public:
42  enum class severity_level
43  {
44  progress,
45  trace,
46  debug,
47  info,
48  warning,
49  error,
50  fatal
51  };
52 
58  static std::string severity_string(severity_level sev)
59  {
60  switch (sev)
61  {
62  case severity_level::progress:
63  return "progress";
64  case severity_level::trace:
65  return "trace";
66  case severity_level::debug:
67  return "debug";
68  case severity_level::info:
69  return "info";
70  case severity_level::warning:
71  return "warning";
72  case severity_level::error:
73  return "error";
74  case severity_level::fatal:
75  return "fatal";
76  default:
77  return "unknown";
78  }
79  }
80 
85  class log_line
86  {
87  public:
96  log_line(logger& log, severity_level sev, size_t line,
97  const std::string& file)
98  : log_(log), sev_(sev), line_(line), file_(file)
99  {
100  /* nothing */
101  }
102 
111  static log_line& endlg(log_line& logline)
112  {
113  logline.stream_.flush();
114  logline.write_to_sinks();
115  return logline;
116  }
117 
126  {
127  return (*fn)(*this);
128  }
129 
137  template <class T>
138  log_line& operator<<(const T& to_write)
139  {
140  stream_ << to_write;
141  return *this;
142  }
143 
149  {
150  log_.write_to_sinks(*this);
151  }
152 
157  std::string str() const
158  {
159  return stream_.str();
160  }
161 
166  {
167  return sev_;
168  }
169 
173  const std::string& file() const
174  {
175  return file_;
176  }
177 
181  size_t line() const
182  {
183  return line_;
184  }
185 
186  private:
190  std::stringstream stream_;
191 
196 
201 
205  size_t line_;
206 
210  std::string file_;
211  };
212 
216  class sink
217  {
218  public:
222  using formatter_func = std::function<std::string(const log_line&)>;
223 
227  using filter_func = std::function<bool(const log_line&)>;
228 
242  sink(std::ostream& stream, const filter_func& filter =
243  [](const log_line&) { return true; },
244  const formatter_func& formatter = &default_formatter)
245  : stream_(stream), formatter_(formatter), filter_(filter)
246  {
247  /* nothing */
248  }
249 
261  sink(std::ostream& stream, logger::severity_level sev,
262  const formatter_func& formatter = &default_formatter)
263  : stream_(stream),
264  formatter_(formatter),
265  filter_([sev](const log_line& ll)
266  { return ll.severity() >= sev; })
267  {
268  // nothing
269  }
270 
277  void write(const log_line& line)
278  {
279  if (filter_)
280  if (!filter_(line))
281  return;
282  if (formatter_)
283  stream_ << formatter_(line);
284  else
285  stream_ << line.str();
286  stream_ << std::flush;
287  }
288 
296  static std::string default_formatter(const log_line& line)
297  {
298  namespace sc = std::chrono;
299 
300  auto time = sc::system_clock::now();
301  auto since_epoch = time.time_since_epoch();
302  auto unix_time = sc::duration_cast<sc::seconds>(since_epoch);
303 
304  std::stringstream ss;
305  ss << unix_time.count();
306  ss << ": ";
307 
308  std::stringstream sev;
309  sev << "[" << severity_string(line.severity()) << "]";
310  ss << std::setw(10) << std::left << sev.str();
311 
312  ss << " ";
313  ss << line.str();
314  ss << " ";
315 
316  ss << "(" << line.file() << ":" << line.line() << ")";
317  ss << std::endl;
318  return ss.str();
319  }
320 
321  private:
325  std::ostream& stream_;
326 
331 
336  };
337 
343  void add_sink(const sink& s)
344  {
345  sinks_.push_back(s);
346  }
347 
353  void add_sink(sink&& s)
354  {
355  sinks_.emplace_back(std::move(s));
356  }
357 
363  void write_to_sinks(const log_line& line)
364  {
365  for (sink& s : sinks_)
366  s.write(line);
367  }
368 
369  private:
373  std::vector<sink> sinks_;
374 };
375 
380 {
381  static logger log;
382  return log;
383 }
384 
389 inline void add_sink(const logger::sink& s)
390 {
391  get_logger().add_sink(s);
392 }
393 
398 inline void add_sink(logger::sink&& s)
399 {
400  get_logger().add_sink(std::move(s));
401 }
402 
411  = logging::logger::severity_level::trace)
412 {
413  // separate logging for progress output
414  add_sink({std::cerr, [](const logger::log_line& ll) {
415  return ll.severity() == logger::severity_level::progress;
416  }, [](const logger::log_line& ll) {
417  return " " + ll.str();
418  }});
419 
420  add_sink({std::cerr, sev});
421 }
422 }
423 }
424 
425 #define LOG(sev) \
426  logging::logger::log_line(logging::get_logger(), \
427  logging::logger::severity_level::sev, __LINE__, \
428  __FILE__)
429 #define ENDLG logging::logger::log_line::endlg
430 #define LOG_FUNCTION_START() \
431  LOG(trace) << "entering " << __func__ << "()" << ENDLG
432 #endif
filter_func filter_
The filtering functor.
Definition: logger.h:335
log_line(logger &log, severity_level sev, size_t line, const std::string &file)
Constructs a new log line for the given logger.
Definition: logger.h:96
static std::string default_formatter(const log_line &line)
The default formatting function.
Definition: logger.h:296
logger & log_
The logger this log_line is to be written on.
Definition: logger.h:195
logger & get_logger()
Definition: logger.h:379
size_t line_
The line number for this message.
Definition: logger.h:205
size_t line() const
Definition: logger.h:181
std::string str() const
Converts the internal stream to a string.
Definition: logger.h:157
log_line & operator<<(log_line &(*fn)(log_line &))
Overloaded operator<<(), used to determine when a manipulator is sent to the log_line stream...
Definition: logger.h:125
sink(std::ostream &stream, const filter_func &filter=[](const log_line &){return true;}, const formatter_func &formatter=&default_formatter)
Creates a new sink with the given formatting function and filtering function.
Definition: logger.h:242
void add_sink(const logger::sink &s)
Adds a sink to a static instance of a logger.
Definition: logger.h:389
void set_cerr_logging(logging::logger::severity_level sev=logging::logger::severity_level::trace)
Sets up default logging to cerr.
Definition: logger.h:410
std::function< bool(const log_line &)> filter_func
Convenience typedef for functions that filter log lines.
Definition: logger.h:227
static std::string severity_string(severity_level sev)
Determines the string form of a given severity_level.
Definition: logger.h:58
severity_level
severity_level: A demarcation of how severe a given message is.
Definition: logger.h:42
std::string file_
The file for this message.
Definition: logger.h:210
void write_to_sinks()
Writes the current log line to all sinks of the logger it was created with.
Definition: logger.h:148
void add_sink(const sink &s)
Adds a sink to the given logger.
Definition: logger.h:343
static log_line & endlg(log_line &logline)
Simulates a std::endl, but for log entries.
Definition: logger.h:111
The ModErn Text Analysis toolkit is a suite of natural language processing, classification, information retreival, data mining, and other applications of text processing.
Definition: analyzer.h:24
log_line: Represents a single message to be written to all sinks.
Definition: logger.h:85
sink: A wrapper for a stream that a logger should write to.
Definition: logger.h:216
std::ostream & stream_
Internal stream.
Definition: logger.h:325
std::function< std::string(const log_line &)> formatter_func
Convenience typedef for functions that format log lines.
Definition: logger.h:222
severity_level severity() const
Definition: logger.h:165
severity_level sev_
The severity of this message.
Definition: logger.h:200
formatter_func formatter_
The formatting functor.
Definition: logger.h:330
void write(const log_line &line)
Writes the given log_line to the stream, formatting and filtering it as necessary.
Definition: logger.h:277
sink(std::ostream &stream, logger::severity_level sev, const formatter_func &formatter=&default_formatter)
Creates a new sink on the given stream, filtering out all results that are greater than or equal to t...
Definition: logger.h:261
std::stringstream stream_
Internal stream.
Definition: logger.h:190
log_line & operator<<(const T &to_write)
Generic operator<<().
Definition: logger.h:138
const std::string & file() const
Definition: logger.h:173
logger: Main logging class.
Definition: logger.h:34
std::vector< sink > sinks_
The list of sinks to write to.
Definition: logger.h:373
void add_sink(sink &&s)
Adds a sink to the given logger.
Definition: logger.h:353
void write_to_sinks(const log_line &line)
Writes the given log_line to all sinks.
Definition: logger.h:363