libqi-api  2.8.7.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
log.hpp
Go to the documentation of this file.
1 #pragma once
2 /*
3  * Copyright (c) 2012 Aldebaran Robotics. All rights reserved.
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the COPYING file.
6  */
7 
15 #ifndef _QI_LOG_HPP_
16 # define _QI_LOG_HPP_
17 
18 # include <string>
19 # include <sstream>
20 # include <cstdarg>
21 # include <cstdio>
22 
23 # include <boost/format.hpp>
24 # include <boost/function/function_fwd.hpp>
25 
26 # include <qi/os.hpp>
27 
28 // For ExceptionLogError:
29 # include <stdexcept>
30 # include <boost/exception/exception.hpp>
31 # include <boost/exception/diagnostic_information.hpp>
32 # include <ka/macroregular.hpp>
33 # include <ka/typetraits.hpp>
34 # include <ka/utility.hpp>
35 
36 
53 #define qiLogCategory(Cat) \
54  static ::qi::log::CategoryType _QI_LOG_CATEGORY_GET() QI_ATTR_UNUSED = \
55  ::qi::log::addCategory(Cat)
56 
57 
72 #if defined(NO_QI_DEBUG) || defined(NDEBUG)
73 # define qiLogDebug(...) ::qi::log::detail::qiFalse() && false < qi::log::detail::NullStream().self()
74 # define qiLogDebugF(Msg, ...) do {} while(0)
75 #else
76 # define qiLogDebug(...) _QI_LOG_MESSAGE_STREAM(LogLevel_Debug, Debug , __VA_ARGS__)
77 # define qiLogDebugF(Msg, ...) _QI_LOG_MESSAGE(LogLevel_Debug, _QI_LOG_FORMAT(Msg, __VA_ARGS__))
78 #endif
79 
83 #if defined(NO_QI_VERBOSE)
84 # define qiLogVerbose(...) ::qi::log::detail::qiFalse() && false < qi::log::detail::NullStream().self()
85 # define qiLogVerboseF(Msg, ...) do {} while(0)
86 #else
87 # define qiLogVerbose(...) _QI_LOG_MESSAGE_STREAM(LogLevel_Verbose, Verbose, __VA_ARGS__)
88 # define qiLogVerboseF(Msg, ...) _QI_LOG_MESSAGE(LogLevel_Verbose, _QI_LOG_FORMAT(Msg, __VA_ARGS__))
89 #endif
90 
94 #if defined(NO_QI_INFO)
95 # define qiLogInfo(...) ::qi::log::detail::qiFalse() && false < qi::log::detail::NullStream().self()
96 # define qiLogInfoF(Msg, ...) do {} while(0)
97 #else
98 # define qiLogInfo(...) _QI_LOG_MESSAGE_STREAM(LogLevel_Info, Info, __VA_ARGS__)
99 # define qiLogInfoF(Msg, ...) _QI_LOG_MESSAGE(LogLevel_Info, _QI_LOG_FORMAT(Msg, __VA_ARGS__))
100 #endif
101 
105 #if defined(NO_QI_WARNING)
106 # define qiLogWarning(...) ::qi::log::detail::qiFalse() && false < qi::log::detail::NullStream().self()
107 # define qiLogWarningF(Msg, ...) do {} while(0)
108 #else
109 # define qiLogWarning(...) _QI_LOG_MESSAGE_STREAM(LogLevel_Warning, Warning, __VA_ARGS__)
110 # define qiLogWarningF(Msg, ...) _QI_LOG_MESSAGE(LogLevel_Warning, _QI_LOG_FORMAT(Msg, __VA_ARGS__))
111 #endif
112 
116 #if defined(NO_QI_ERROR)
117 # define qiLogError(...) ::qi::log::detail::qiFalse() && false < qi::log::detail::NullStream().self()
118 # define qiLogErrorF(Msg, ...) do {} while(0)
119 #else
120 # define qiLogError(...) _QI_LOG_MESSAGE_STREAM(LogLevel_Error, Error, __VA_ARGS__)
121 # define qiLogErrorF(Msg, ...) _QI_LOG_MESSAGE(LogLevel_Error, _QI_LOG_FORMAT(Msg, __VA_ARGS__))
122 #endif
123 
127 #if defined(NO_QI_FATAL)
128 # define qiLogFatal(...) ::qi::log::detail::qiFalse() && false < qi::log::detail::NullStream().self()
129 # define qiLogFatalF(Msg, ...) do {} while(0)
130 #else
131 # define qiLogFatal(...) _QI_LOG_MESSAGE_STREAM(LogLevel_Fatal, Fatal, __VA_ARGS__)
132 # define qiLogFatalF(Msg, ...) _QI_LOG_MESSAGE(LogLevel_Fatal, _QI_LOG_FORMAT(Msg, __VA_ARGS__))
133 #endif
134 
135 
136 namespace qi {
140  enum LogLevel {
148  };
149 
153  enum LogColor {
157  };
158 
173  };
174 
178  using LogContext = int;
179 
183  namespace log {
184 
186  QI_API_DEPRECATED_MSG(Use 'LogLevel_Silent' instead) static const qi::LogLevel silent = LogLevel_Silent;
188  QI_API_DEPRECATED_MSG(Use 'LogLevel_Fatal' instead) static const qi::LogLevel fatal = LogLevel_Fatal;
190  QI_API_DEPRECATED_MSG(Use 'LogLevel_Error' instead) static const qi::LogLevel error = LogLevel_Error;
192  QI_API_DEPRECATED_MSG(Use 'LogLevel_Warning' instead) static const qi::LogLevel warning = LogLevel_Warning;
194  QI_API_DEPRECATED_MSG(Use 'LogLevel_Info' instead) static const qi::LogLevel info = LogLevel_Info;
196  QI_API_DEPRECATED_MSG(Use 'LogLevel_Verbose' instead) static const qi::LogLevel verbose = LogLevel_Verbose;
198  QI_API_DEPRECATED_MSG(Use 'LogLevel_Debug' instead) static const qi::LogLevel debug = LogLevel_Debug;
199 
201  QI_API_DEPRECATED_MSG('qi::log::LogLevel' is deprecated. Use 'qi::LogLevel' instead) typedef qi::LogLevel LogLevel;
202  }
203 }
204 
205 namespace qi {
206  namespace log {
207  namespace detail {
208  struct Category;
209  }
210 
211  using SubscriberId = unsigned int;
212  using CategoryType = detail::Category*;
213 
215  QI_API_DEPRECATED_MSG(Use 'SubscriberId' instead)
216  typedef unsigned int Subscriber;
217 
223  using logFuncHandler = boost::function7<void,
224  const qi::LogLevel,
225  const qi::os::timeval,
226  const char*,
227  const char*,
228  const char*,
229  const char*,
230  int>;
235  using Handler = boost::function8<void,
236  const qi::LogLevel,
237  const qi::Clock::time_point,
238  const qi::SystemClock::time_point,
239  const char*,
240  const char*,
241  const char*,
242  const char*,
243  int>;
244 
247  namespace env {
248  namespace QI_DEFAULT_LOGHANDLER {
252 
298  QI_API extern char const * const name; // TODO: use constexpr after upgrading to c++17
299  namespace value {
300  QI_API extern char const * const none; // TODO: use constexpr after upgrading to c++17
301  QI_API extern char const * const stdOut; // TODO: use constexpr after upgrading to c++17
302  QI_API extern char const * const logger; // TODO: use constexpr after upgrading to c++17
303  QI_API extern char const * const debugger; // TODO: use constexpr after upgrading to c++17
304  }
305  }
306 
307  // TODO: Publish the names of the other environment variables used by qi::log.
308  }
309 
321  bool synchronous = true);
322 
323 
337  QI_API void destroy();
338 
339 
350  QI_API void log(const qi::LogLevel verb,
351  const char* category,
352  const char* msg,
353  const char* file = "",
354  const char* fct = "",
355  const int line = 0);
356 
360  QI_API void log(const qi::LogLevel verb,
361  CategoryType category,
362  const std::string& msg,
363  const char* file = "",
364  const char* fct = "",
365  const int line = 0);
366 
367 
374  QI_API const char* logLevelToString(const qi::LogLevel verb, bool verbose = true);
375 
381  QI_API qi::LogLevel stringToLogLevel(const char* verb);
382 
404  QI_API void setLogLevel(const qi::LogLevel lv, SubscriberId sub = 0);
405 
412 
417  QI_API std::vector<std::string> categories();
418 
424  QI_API CategoryType addCategory(const std::string& name);
430  QI_API void enableCategory(const std::string& cat, SubscriberId sub = 0);
436  QI_API void disableCategory(const std::string& cat, SubscriberId sub = 0);
437 
444  inline bool isVisible(CategoryType category, qi::LogLevel level);
445 
449  QI_API bool isVisible(const std::string& category, qi::LogLevel level);
450 
465  QI_API void addFilters(const std::string& rules, SubscriberId sub = 0);
466 
484  QI_API void addFilter(const std::string& cat, qi::LogLevel level, SubscriberId sub = 0);
485 
510  QI_API void setContext(int ctx);
511 
516  QI_API int context();
517 
523 
529 
537  QI_API void setSynchronousLog(bool sync);
538 
547  QI_API SubscriberId addHandler(const std::string& name,
548  qi::log::Handler fct,
549  qi::LogLevel defaultLevel = LogLevel_Info);
558  QI_API_DEPRECATED_MSG(Use 'addHandler' instead)
559  QI_API SubscriberId addLogHandler(const std::string& name,
561  qi::LogLevel defaultLevel = LogLevel_Info);
562 
567  QI_API void removeHandler(const std::string& name);
568 
574  QI_API_DEPRECATED_MSG(Use 'removeHandler' instead)
575  QI_API void removeLogHandler(const std::string& name);
576 
580  QI_API void flush();
581 
582 
585  QI_API_DEPRECATED_MSG(Use 'setLogLevel' instead)
586  inline void setVerbosity(SubscriberId sub, const qi::log::LogLevel lv) { setLogLevel(static_cast<qi::LogLevel>(lv), sub); }
588  QI_API_DEPRECATED_MSG(Use 'addFilter' instead)
589  inline void setCategory(SubscriberId sub, const std::string& cat, qi::log::LogLevel level) { addFilter(cat, static_cast<qi::LogLevel>(level), sub); }
591 
596  QI_API QI_API_DEPRECATED_MSG(Use 'logLevel' instead)
597  qi::LogLevel verbosity(SubscriberId sub = 0);
598 
603  QI_API QI_API_DEPRECATED_MSG(Use 'addFilters' instead)
604  void setVerbosity(const std::string& rules, SubscriberId sub = 0);
605 
610  QI_API QI_API_DEPRECATED_MSG(Use 'setLogLevel' instead)
611  void setVerbosity(const qi::LogLevel lv, SubscriberId sub = 0);
612 
617  QI_API QI_API_DEPRECATED_MSG(Use 'addFilter' instead)
618  void setCategory(const std::string& catName, qi::LogLevel level, SubscriberId sub = 0);
619 
620  }
621 
622 }
623 
624 # include <qi/detail/log.hxx>
625 
626 namespace qi
627 {
635  template<typename O, typename S = char const*>
637  {
640  // Regular (if S and O are):
641  KA_GENERATE_FRIEND_REGULAR_OPS_2(ExceptionLogError, category, prefix)
642  // Custom:
643  void operator()(const std::exception& e) const
644  {
645  qiLogError(category) << prefix << ": standard exception: " << e.what();
646  }
647  void operator()(const boost::exception& e) const
648  {
649  qiLogError(category) << prefix <<": boost exception: " << boost::diagnostic_information(e);
650  }
651  void operator()() const
652  {
653  qiLogError(category) << prefix << ": unknown exception";
654  }
655  };
656 
689  template<typename O, typename S>
690  ExceptionLogError<ka::Decay<O>, ka::Decay<S>> exceptionLogError(S&& category, O&& prefix)
691  {
692  return ExceptionLogError<ka::Decay<O>, ka::Decay<S>>{ ka::fwd<S>(category),
693  ka::fwd<O>(prefix) };
694  }
695 
696 } // namespace qi
697 
698 #endif // _QI_LOG_HPP_
error log level
Definition: log.hpp:143
Show logs level.
Definition: log.hpp:164
void destroy()
Stop and flush the logging system.
LogColor
Logs color mode.
Definition: log.hpp:153
Show qi::Clock dates.
Definition: log.hpp:172
Show categories.
Definition: log.hpp:168
std::vector< std::string > categories()
Get the list of all categories.
SubscriberId addHandler(const std::string &name, qi::log::Handler fct, qi::LogLevel defaultLevel=LogLevel_Info)
Add a log handler for this process' logs.
Print an end line between contexts and logs.
Definition: log.hpp:171
Never show color.
Definition: log.hpp:154
void setContext(int ctx)
Set log context verbosity.
void setVerbosity(SubscriberId sub, const qi::log::LogLevel lv)
Definition: log.hpp:586
CategoryType addCategory(const std::string &name)
Add/get a category.
silent log level
Definition: log.hpp:141
#define QI_API
Definition: api.hpp:33
Always show color.
Definition: log.hpp:156
LogLevel
Log level verbosity.
Definition: log.hpp:140
The SystemClock class represents the system-wide real time wall clock. It may not be monotonic: on mo...
Definition: clock.hpp:167
debug log level
Definition: log.hpp:147
qi::LogLevel logLevel(SubscriberId sub=0)
Get log verbosity.
SubscriberId addLogHandler(const std::string &name, qi::log::logFuncHandler fct, qi::LogLevel defaultLevel=LogLevel_Info)
Add a log handler.
unsigned int SubscriberId
Subscriber Identifier.
Definition: log.hpp:211
void disableCategory(const std::string &cat, SubscriberId sub=0)
Set category to silent log level. Globbing is supported.
void setColor(LogColor color)
Set log color.
Show functions name.
Definition: log.hpp:170
void addFilter(const std::string &cat, qi::LogLevel level, SubscriberId sub=0)
Set per-subscriber category to level. Globbing is supported.
const char * logLevelToString(const qi::LogLevel verb, bool verbose=true)
Convert log verbosity to a readable string.
void operator()(const boost::exception &e) const
Definition: log.hpp:647
void addFilters(const std::string &rules, SubscriberId sub=0)
Parse and execute a set of verbosity rules.
void log(const qi::LogLevel verb, const char *category, const char *msg, const char *file="", const char *fct="", const int line=0)
Log function. You should call qiLog* macros instead.
void setSynchronousLog(bool sync)
Enables or disables synchronous logs.
#define qiLogError(...)
Log in error mode.
Definition: log.hpp:120
qi::LogLevel stringToLogLevel(const char *verb)
Convert string to log verbosity.
void log(const qi::LogLevel verb, CategoryType category, const std::string &msg, const char *file="", const char *fct="", const int line=0)
Log function. You should call qiLog* macros instead.
void setLogLevel(const qi::LogLevel lv, SubscriberId sub=0)
Set log Level.
#define QI_API_DEPRECATED_MSG(msg__)
Compiler flags to mark a function as deprecated. It will generate a compiler warning.
Definition: macro.hpp:55
Auto color.
Definition: log.hpp:155
ExceptionLogError< ka::Decay< O >, ka::Decay< S > > exceptionLogError(S &&category, O &&prefix)
Definition: log.hpp:690
No context.
Definition: log.hpp:163
bool isVisible(CategoryType category, qi::LogLevel level)
Check if the given combination of category and level is enable.
Definition: log.hxx:219
Show logs files.
Definition: log.hpp:169
verbose log level
Definition: log.hpp:146
boost::function8< void, const qi::LogLevel, const qi::Clock::time_point, const qi::SystemClock::time_point, const char *, const char *, const char *, const char *, int > Handler
Boost delegate to log function (verbosity lv, dates of log, category, message, file, function, line).
Definition: log.hpp:243
unsigned int Subscriber
Definition: log.hpp:216
warning log level
Definition: log.hpp:144
void removeHandler(const std::string &name)
Remove a log handler.
Show qi::SystemClock dates.
Definition: log.hpp:166
Show short logs level.
Definition: log.hpp:165
info log level
Definition: log.hpp:145
fatal log level
Definition: log.hpp:142
Show threads id.
Definition: log.hpp:167
LogColor color()
Get log color.
int LogContext
Logs context attribute value.
Definition: log.hpp:178
The Clock class represents a system-wide clock, best suitable for timestamping events. Typically monotonic and unaffected by the system clock adjustment, altough this is not guaranteed.
Definition: clock.hpp:85
void enableCategory(const std::string &cat, SubscriberId sub=0)
Set category to current verbosity level. Globbing is supported.
LogContextAttr
Logs context attribute.
Definition: log.hpp:162
void flush()
Flush asynchronous logs.
void init(qi::LogLevel verb=qi::LogLevel_Info, qi::LogContext context=qi::LogContextAttr_ShortVerbosity|qi::LogContextAttr_Tid|qi::LogContextAttr_Category, bool synchronous=true)
Initialization of the logging system Creates and registers the default log handler according to QI_DE...
void setCategory(SubscriberId sub, const std::string &cat, qi::log::LogLevel level)
Definition: log.hpp:589
boost::function7< void, const qi::LogLevel, const qi::os::timeval, const char *, const char *, const char *, const char *, int > logFuncHandler
Boost delegate to log function (verbosity lv, date of log, category, message, file, function, line).
Definition: log.hpp:230
int context()
Get log context.
void operator()() const
Definition: log.hpp:651
void removeLogHandler(const std::string &name)
Remove a log handler.