IBR-DTNSuite  0.10
Logger.h
Go to the documentation of this file.
1 /*
2  * Logger.h
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
22 #ifndef LOGGER_H_
23 #define LOGGER_H_
24 
25 #include <ibrcommon/thread/Queue.h>
27 #include <ibrcommon/data/File.h>
28 #include <fstream>
29 #include <sys/time.h>
30 #include <iostream>
31 #include <sstream>
32 #include <list>
33 
64 #define IBRCOMMON_LOGGER_LEVEL \
65  ibrcommon::Logger::getVerbosity()
66 
67 #define IBRCOMMON_LOGGER(level) \
68  if (ibrcommon::LogLevel::level & ibrcommon::Logger::getLogMask()) { \
69  ibrcommon::Logger __macro_ibrcommon_logger = ibrcommon::Logger::level(""); \
70  std::stringstream __macro_ibrcommon_stream; __macro_ibrcommon_stream
71 
72 #define IBRCOMMON_LOGGER_TAG(tag, level) \
73  if (ibrcommon::LogLevel::level & ibrcommon::Logger::getLogMask()) { \
74  ibrcommon::Logger __macro_ibrcommon_logger = ibrcommon::Logger::level(tag); \
75  std::stringstream __macro_ibrcommon_stream; __macro_ibrcommon_stream
76 
77 #define IBRCOMMON_LOGGER_DEBUG(verbosity) \
78  if (ibrcommon::Logger::getVerbosity() >= verbosity) \
79  { \
80  ibrcommon::Logger __macro_ibrcommon_logger = ibrcommon::Logger::debug("", verbosity); \
81  std::stringstream __macro_ibrcommon_stream; __macro_ibrcommon_stream
82 
83 #define IBRCOMMON_LOGGER_DEBUG_TAG(tag, verbosity) \
84  if (ibrcommon::Logger::getVerbosity() >= verbosity) \
85  { \
86  ibrcommon::Logger __macro_ibrcommon_logger = ibrcommon::Logger::debug(tag, verbosity); \
87  std::stringstream __macro_ibrcommon_stream; __macro_ibrcommon_stream
88 
89 #define IBRCOMMON_LOGGER_ENDL \
90  std::flush; \
91  __macro_ibrcommon_logger.setMessage(__macro_ibrcommon_stream.str()); \
92  __macro_ibrcommon_logger.print(); \
93  }
94 
95 #define IBRCOMMON_LOGGER_ex(level) \
96  IBRCOMMON_LOGGER(level) << __PRETTY_FUNCTION__ << ": "
97 
98 #define IBRCOMMON_LOGGER_DEBUG_ex(verbosity) \
99  IBRCOMMON_LOGGER_DEBUG(verbosity) << __FILE__ << ":" << __LINE__ << " in " << __PRETTY_FUNCTION__ << ": "
100 
101 namespace ibrcommon
102 {
103  namespace LogLevel {
104  enum LogLevel
105  {
106  emergency = 1 << 0, /* system is unusable */
107  alert = 1 << 1, /* action must be taken immediately */
108  critical = 1 << 2, /* critical conditions */
109  error = 1 << 3, /* error conditions */
110  warning = 1 << 4, /* warning conditions */
111  notice = 1 << 5, /* normal but significant condition */
112  info = 1 << 6, /* informational */
113  debug = 1 << 7 /* debug-level messages */
114  };
115  }
116 
122  class Logger
123  {
124  public:
126  {
127  LOG_NONE = 0,
128  LOG_DATETIME = 1 << 0, /* print date/time on log messages */
129  LOG_HOSTNAME = 1 << 1, /* print hostname on log messages */
130  LOG_LEVEL = 1 << 2, /* print the log level on log messages */
131  LOG_TIMESTAMP = 1 << 3, /* print timestamp on log messages */
132  LOG_TAG = 1 << 4 /* print tag on log messages */
133  };
134 
135  enum LogLevel
136  {
137  LOGGER_EMERG = 1 << 0, /* system is unusable */
138  LOGGER_ALERT = 1 << 1, /* action must be taken immediately */
139  LOGGER_CRIT = 1 << 2, /* critical conditions */
140  LOGGER_ERR = 1 << 3, /* error conditions */
141  LOGGER_WARNING = 1 << 4, /* warning conditions */
142  LOGGER_NOTICE = 1 << 5, /* normal but significant condition */
143  LOGGER_INFO = 1 << 6, /* informational */
144  LOGGER_DEBUG = 1 << 7, /* debug-level messages */
145  LOGGER_ALL = 0xff
146  };
147 
148  Logger(const Logger&);
149  virtual ~Logger();
150 
154  void setMessage(const std::string &data);
155 
159  const std::string& str() const;
160 
161  static Logger emergency(const std::string &tag);
162  static Logger alert(const std::string &tag);
163  static Logger critical(const std::string &tag);
164  static Logger error(const std::string &tag);
165  static Logger warning(const std::string &tag);
166  static Logger notice(const std::string &tag);
167  static Logger info(const std::string &tag);
168  static Logger debug(const std::string &tag, int verbosity);
169 
174  static void setVerbosity(const int verbosity);
175 
179  static unsigned char getLogMask();
180 
185  static int getVerbosity();
186 
193  static void addStream(std::ostream &stream, const unsigned char logmask = LOGGER_INFO, const unsigned char options = LOG_NONE);
194 
201  static void setLogfile(const ibrcommon::File &logfile, const unsigned char logmask = LOGGER_INFO, const unsigned char options = LOG_NONE);
202 
210  static void enableSyslog(const char *name, int option, int facility, const unsigned char logmask = LOGGER_INFO);
211 
219  static void enableAsync();
220 
225  static void enableBuffer(size_t size);
226 
231  static void writeBuffer(std::ostream&);
232 
238  static void stop();
239 
243  static void setDefaultTag(const std::string &tag);
244 
248  void print();
249 
253  static void reload();
254 
255  private:
256  Logger(LogLevel level, const std::string &tag, int debug_verbosity = 0);
257 
258  class LoggerOutput
259  {
260  public:
261  LoggerOutput(std::ostream &stream, const unsigned char logmask, const unsigned char options);
262  virtual ~LoggerOutput();
263 
264  void log(const Logger &log);
265 
266  std::ostream &_stream;
267  unsigned char _level;
268  unsigned char _options;
269  };
270 
271  class LogWriter : public ibrcommon::JoinableThread
272  {
273  public:
274  LogWriter();
275  virtual ~LogWriter();
276 
277  void log(Logger &logger);
278 
283  void setVerbosity(const int verbosity);
284 
289  int getVerbosity() const;
290 
291 
292  unsigned char getLogMask() const;
293 
300  void addStream(std::ostream &stream, const unsigned char logmask = LOGGER_INFO, const unsigned char options = LOG_NONE);
301 
308  void setLogfile(const ibrcommon::File &logfile, const unsigned char logmask = LOGGER_INFO, const unsigned char options = LOG_NONE);
309 
317  void enableSyslog(const char *name, int option, int facility, const unsigned char logmask = LOGGER_INFO);
318 
326  void enableAsync();
327 
332  void enableBuffer(size_t size);
333 
337  void reload();
338 
343  void writeBuffer(std::ostream&, const unsigned char logmask, const unsigned char options);
344 
345  protected:
346  void flush();
347  void run() throw ();
348  void __cancellation() throw ();
349 
350  private:
354  void flush(const Logger &logger);
355 
356  unsigned char _global_logmask;
357  int _verbosity;
358  bool _syslog;
359  unsigned char _syslog_mask;
360 
361  ibrcommon::Queue<Logger> _queue;
362  bool _use_queue;
363  std::list<LoggerOutput> _logger;
364 
365  ibrcommon::Mutex _buffer_mutex;
366  size_t _buffer_size;
367  std::list<Logger> *_buffer;
368 
369  ibrcommon::Mutex _logfile_mutex;
370  ibrcommon::File _logfile;
371  std::ofstream _logfile_stream;
372  LoggerOutput *_logfile_output;
373  unsigned char _logfile_logmask;
374  unsigned char _logfile_options;
375  };
376 
377  LogLevel _level;
378  const std::string _tag;
379  int _debug_verbosity;
380  struct timeval _logtime;
381 
382  std::string _data;
383 
384  static std::string _default_tag;
385  static std::string _android_tag_prefix;
386  static LogWriter _logwriter;
387  };
388 }
389 
390 #endif /* LOGGER_H_ */