MIRA
LoggingCore.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
47 #ifndef _MIRA_LOGGINGCORE_H_
48 #define _MIRA_LOGGINGCORE_H_
49 
50 #include <map>
51 
52 #ifndef Q_MOC_RUN
53 #include <boost/thread/mutex.hpp>
54 #include <boost/function.hpp>
55 #endif
56 
57 #include <platform/Types.h>
58 #include <thread/ThreadID.h>
59 #include <utils/Singleton.h>
60 #include <utils/Time.h>
61 #include <utils/Foreach.h>
62 
63 namespace mira {
64 
66 
72 {
73  CRITICAL = 0,
74  ERROR = 1,
75  WARNING = 2,
76  NOTICE = 3,
77  DEBUG = 4,
78  TRACE = 5,
79 };
80 
84 const std::string severityLevelStr[]= {
85  "CRITICAL",
86  "ERROR ",
87  "WARNING ",
88  "NOTICE ",
89  "DEBUG ",
90  "TRACE "
91 };
92 
98 MIRA_BASE_EXPORT SeverityLevel stringToSeverityLevel(const std::string& levelString);
99 
101 
106 struct LogRecord
107 {
111  std::string message;
112  std::string details;
113  int line;
114  std::string file;
115  std::string function;
117 };
118 
125 {
126  std::string nameSpace;
127  std::string className;
128  std::string functionName;
129 };
130 
135 template<typename Reflector>
136 void reflect(Reflector& r, LogRecord& record)
137 {
138  r.member("level", record.level, "Log level");
139  r.member("time", record.time, "Log time");
140  r.member("uptime", record.uptime, "Log uptime");
141  r.member("message", record.message, "Log message");
142  r.member("line", record.line, "Line in file where log call occurred");
143  r.member("file", record.file, "File where log call occurred");
144  r.member("function", record.function, "Function where log call occurred");
145  r.member("threadID", record.threadID, "ID of thread where log call occurred");
146 }
147 
149 
155 {
156 public:
157 
159  virtual ~LogFormatterBase() {}
160 
166  virtual std::string format(const LogRecord& record) = 0;
167 };
168 
170 typedef boost::shared_ptr<LogFormatterBase> LogFormatterPtr;
171 
173 
183 {
184 public:
185 
187  virtual ~LogFilterBase() {}
188 
194  virtual bool filter(const LogRecord& record) = 0;
195 };
196 
198 typedef boost::shared_ptr<LogFilterBase> LogFilterPtr;
199 
201 
208 {
209 public:
210 
212  virtual ~LogSink() {}
213 
218  void aboutToConsume(const LogRecord& record);
219 
225  virtual void consume(const LogRecord& record) = 0;
226 
231  void resetFilter()
232  {
233  mFilter.reset();
234  }
235 
241  template <typename T>
242  LogFilterPtr setFilter(const T& filter)
243  {
244  mFilter.reset(new T(filter));
245  return mFilter;
246  }
247 
253  {
254  mFormatter.reset();
255  }
256 
262  template <typename T>
263  LogFormatterPtr setFormatter(const T& formatter)
264  {
265  mFormatter.reset(new T(formatter));
266  return mFormatter;
267  }
268 
269 protected:
272 };
273 
275 typedef boost::shared_ptr<LogSink> LogSinkPtr;
276 
278 
285 class MIRA_BASE_EXPORT LogCore : public LazySingleton<LogCore>
286 {
287 public:
288 
290  typedef boost::function<void(SeverityLevel)> SeverityLevelChangedCallback;
291 
295  LogCore();
296 
302  LogRecordFunctionInfo parseFunction(const LogRecord& record);
303 
309  {
310  boost::mutex::scoped_lock lock(mCallbackMutex);
311  mSeverityLevel = level;
312  foreach(auto i, mSeverityChangedCallbacks)
313  i.second(level);
314  }
315 
321  {
322  return mSeverityLevel;
323  }
324 
331  {
332  boost::mutex::scoped_lock lock(mCallbackMutex);
333  mSeverityChangedCallbacks[mCallbackCounter] = callback;
334  return mCallbackCounter++;
335  }
336 
340  void unregisterCallback(uint32 id)
341  {
342  boost::mutex::scoped_lock lock(mCallbackMutex);
343  mSeverityChangedCallbacks.erase(id);
344  }
345 
351  {
352  return Time::now()-mStartTime;
353  }
354 
361  template <typename T>
362  LogSinkPtr registerSink(const T& sink)
363  {
364  boost::mutex::scoped_lock lock(mSinkMutex);
365  LogSinkPtr ptr(new T(sink));
366  mSinks.push_back(ptr);
367  return ptr;
368  }
369 
375  {
376  boost::mutex::scoped_lock lock(mSinkMutex);
377  auto i = mSinks.begin();
378  for (; i!= mSinks.end(); ++i)
379  if ((*i) == sink)
380  break;
381  if (i != mSinks.end())
382  mSinks.erase(i);
383  }
384 
391  void log(LogRecord& record)
392  {
393  boost::mutex::scoped_lock lock(mSinkMutex);
394  record.uptime = getUptime();
395  for(size_t i=0; i<mSinks.size(); ++i)
396  mSinks[i]->aboutToConsume(record);
397  }
398 
399 private:
400  boost::mutex mSinkMutex;
401  boost::mutex mCallbackMutex;
402  Time mStartTime;
403  SeverityLevel mSeverityLevel;
404  std::vector<LogSinkPtr> mSinks;
405  uint32 mCallbackCounter;
406  std::map<uint32, SeverityLevelChangedCallback> mSeverityChangedCallbacks;
407 };
408 
410 
416 #define MIRA_LOGGER (mira::LogCore::instance())
417 
426 class Logger : boost::noncopyable
427 {
428 public:
433  const Time& time,
434  const std::string& file, int line,
435  const std::string& function, ThreadID threadID)
436  {
437  mRecord.level = level;
438  mRecord.time = time;
439  mRecord.file = file;
440  mRecord.line = line;
441  mRecord.function = function;
442  mRecord.threadID = threadID;
443  }
444 
447  {
448  mStream.flush();
449  mRecord.message = mStream.str();
450  MIRA_LOGGER.log(mRecord);
451  }
456  std::ostringstream& stream()
457  {
458  return mStream;
459  }
460 
461 protected:
462 
464  std::ostringstream mStream;
465 };
466 
468 
479 #ifndef MIRA_SEVERITY_MAX_LEVEL
480 # ifdef NDEBUG
481 # define MIRA_SEVERITY_MAX_LEVEL mira::NOTICE
482 # else
483 # define MIRA_SEVERITY_MAX_LEVEL mira::TRACE
484 # endif
485 #endif
486 
528 #define MIRA_LOG(level) \
529 if (level > MIRA_SEVERITY_MAX_LEVEL) {} \
530 else if (level > MIRA_LOGGER.getSeverityLevel()) {} \
531  else mira::Logger(level, mira::Time::now(), __FILE__, __LINE__, MIRA_FUNCTION, mira::getCurrentThreadID()).stream()
532 
541 #define MIRA_LOG_ALWAYS(level) \
542  mira::Logger(level, mira::Time::now(), __FILE__, __LINE__, MIRA_FUNCTION, mira::getCurrentThreadID()).stream()
543 
548 #define MIRA_LOG_ATTR(level, time, file, line, function, threadID) \
549 if (level > MIRA_SEVERITY_MAX_LEVEL) {} \
550 else if (level > MIRA_LOGGER.getSeverityLevel()) {} \
551  else mira::Logger(level, time, file, line, function, threadID).stream()
552 
553 #define MIRA_TRACE MIRA_LOG(mira::TRACE) << "in : " << __FILE__ << "(" << __LINE__ << ") in " << MIRA_FUNCTION << " "
554 
556 
557 }
558 
559 #endif
Macro for iterating over all elements in a container.
SeverityLevel level
Definition: LoggingCore.h:108
LogFilterPtr mFilter
Definition: LoggingCore.h:271
Typedefs for OS independent basic data types.
boost::function< void(SeverityLevel)> SeverityLevelChangedCallback
Signature of a callback function for log severity level changes.
Definition: LoggingCore.h:290
Single instance of the core logging class.
Definition: LoggingCore.h:285
virtual ~LogFormatterBase()
Destructor.
Definition: LoggingCore.h:159
Holds all the information about a log entry.
Definition: LoggingCore.h:106
Duration uptime
Definition: LoggingCore.h:110
virtual std::string format(const LogRecord &record)=0
Creates a formatted string out of a log entry.
void unregisterSink(LogSinkPtr sink)
Unregisters a sink.
Definition: LoggingCore.h:374
LogSinkPtr registerSink(const T &sink)
Register a new sink.
Definition: LoggingCore.h:362
std::string function
Definition: LoggingCore.h:115
~Logger()
Destructor.
Definition: LoggingCore.h:446
PropertyHint file(const std::string &filters=std::string(), bool save=false)
Tells the property editor that the path is for a file, and that it should show a "File Open"/"File Sa...
Definition: Path.h:247
Duration getUptime() const
Get the up-time of the core.
Definition: LoggingCore.h:350
Abstract base class for log filters.
Definition: LoggingCore.h:182
boost::shared_ptr< LogSink > LogSinkPtr
A shared pointer for a log sink.
Definition: LoggingCore.h:275
Holds information about a log entry function.
Definition: LoggingCore.h:124
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
void resetFilter()
Resets the log filter.
Definition: LoggingCore.h:231
std::string nameSpace
Definition: LoggingCore.h:126
Time and Duration wrapper class.
Helper class that is created to make one logging process atomic and thread safe.
Definition: LoggingCore.h:426
uint32 ThreadID
Platform independent thread ID.
Definition: ThreadID.h:68
Definition: LoggingCore.h:78
Provided for convenience.
Definition: Singleton.h:564
SeverityLevel
Severity levels to graduate between different log outputs.
Definition: LoggingCore.h:71
Logger(SeverityLevel level, const Time &time, const std::string &file, int line, const std::string &function, ThreadID threadID)
The constructor taking the details of a log entry.
Definition: LoggingCore.h:432
LogFormatterPtr setFormatter(const T &formatter)
Set the formatter.
Definition: LoggingCore.h:263
std::ostringstream mStream
Definition: LoggingCore.h:464
void unregisterCallback(uint32 id)
Unregister a callback function.
Definition: LoggingCore.h:340
Wrapper class for boost::posix_time::ptime for adding more functionality to it.
Definition: Time.h:421
OS independent thread id.
int line
Definition: LoggingCore.h:113
std::string file
Definition: LoggingCore.h:114
LogFilterPtr setFilter(const T &filter)
Set the filter.
Definition: LoggingCore.h:242
boost::shared_ptr< LogFormatterBase > LogFormatterPtr
A shared pointer for a log formatter.
Definition: LoggingCore.h:170
A singleton class that can be freely configured using policies that control the creation, instantiation, lifetime and thread-safety.
Use this class to represent time durations.
Definition: Time.h:104
uint32 registerCallback(SeverityLevelChangedCallback callback)
Register a callback function.
Definition: LoggingCore.h:330
void resetFormatter()
Resets the formatter.
Definition: LoggingCore.h:252
std::string message
Definition: LoggingCore.h:111
void reflect(Reflector &r, LogRecord &record)
Non-intrusive reflector for LogRecord.
Definition: LoggingCore.h:136
void setSeverityLevel(SeverityLevel level)
Sets the application wide severity level.
Definition: LoggingCore.h:308
void log(LogRecord &record)
Writes a log record and distribute it between all the registered sinks.
Definition: LoggingCore.h:391
std::string className
Definition: LoggingCore.h:127
virtual ~LogFilterBase()
Destructor.
Definition: LoggingCore.h:187
boost::shared_ptr< LogFilterBase > LogFilterPtr
A shared pointer for a log filter.
Definition: LoggingCore.h:198
Abstract base class for sink formatters.
Definition: LoggingCore.h:154
ThreadID threadID
Definition: LoggingCore.h:116
const std::string severityLevelStr[]
String conversion for the enum severity types.
Definition: LoggingCore.h:84
Time time
Definition: LoggingCore.h:109
Abstract base class for all log sinks.
Definition: LoggingCore.h:207
Definition: LoggingCore.h:75
static Time now() static Time eternity()
Returns the current utc based time.
Definition: Time.h:484
MIRA_BASE_EXPORT SeverityLevel stringToSeverityLevel(const std::string &levelString)
Converts the specified string into a numeric severity level.
Definition: LoggingCore.h:73
virtual bool filter(const LogRecord &record)=0
Filters a log entry.
Definition: LoggingCore.h:77
#define MIRA_BASE_EXPORT
This is required because on windows there is a macro defined called ERROR.
Definition: Platform.h:153
std::string functionName
Definition: LoggingCore.h:128
Definition: LoggingCore.h:74
SeverityLevel getSeverityLevel() const
Get the application wide severity level.
Definition: LoggingCore.h:320
LogRecord mRecord
Definition: LoggingCore.h:463
virtual ~LogSink()
Destructor.
Definition: LoggingCore.h:212
std::string details
Definition: LoggingCore.h:112
LogFormatterPtr mFormatter
Definition: LoggingCore.h:270
Definition: LoggingCore.h:76
#define MIRA_LOGGER
Macro for easier access to the logging core instance.
Definition: LoggingCore.h:416
std::ostringstream & stream()
Get the underlying stream.
Definition: LoggingCore.h:456