logger.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2020 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License as published by the Free Software
9  * Foundation, either version 3 of the License, or (at your option) any later version.
10  *
11  * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14  *
15  * You should have received copies of the GNU General Public License and GNU Lesser
16  * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17  * <http://www.gnu.org/licenses/>.
18  *
19  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20  */
21 
22 #ifndef NDN_UTIL_LOGGER_HPP
23 #define NDN_UTIL_LOGGER_HPP
24 
26 
27 #ifdef HAVE_NDN_CXX_CUSTOM_LOGGER
28 #include "ndn-cxx/util/custom-logger.hpp"
29 #else
30 
31 #include <boost/log/common.hpp>
32 #include <boost/log/expressions/keyword.hpp>
33 #include <boost/log/sources/severity_logger.hpp>
34 
35 #include <atomic>
36 
37 namespace ndn {
38 namespace util {
39 
42 enum class LogLevel {
43  FATAL = -1,
44  NONE = 0,
45  ERROR = 1,
46  WARN = 2,
47  INFO = 3,
48  DEBUG = 4,
49  TRACE = 5,
50  ALL = 255
51 };
52 
56 std::ostream&
57 operator<<(std::ostream& os, LogLevel level);
58 
63 parseLogLevel(const std::string& s);
64 
65 namespace log {
66 
67 BOOST_LOG_ATTRIBUTE_KEYWORD(module, "Module", std::string)
68 BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", LogLevel)
69 
70 } // namespace log
71 
77 class Logger : public boost::log::sources::severity_logger_mt<LogLevel>
78 {
79 public:
80  explicit
81  Logger(const char* name);
82 
83  static void
84  registerModuleName(const char* name);
85 
86  const std::string&
87  getModuleName() const
88  {
89  return m_moduleName;
90  }
91 
92  bool
93  isLevelEnabled(LogLevel level) const
94  {
95  return m_currentLevel.load(std::memory_order_relaxed) >= level;
96  }
97 
98  void
100  {
101  m_currentLevel.store(level, std::memory_order_relaxed);
102  }
103 
104 private:
105  const std::string m_moduleName;
106  std::atomic<LogLevel> m_currentLevel;
107 };
108 
109 namespace detail {
110 
112 template<class T>
113 struct ExtractArgument;
114 
115 template<class T, class U>
116 struct ExtractArgument<T(U&)>
117 {
118  using type = U;
119 };
120 
121 template<class T, class U>
122 struct ExtractArgument<T(U)&>
123 {
124  using type = U;
125 };
126 
127 template<class T>
128 using ArgumentType = typename ExtractArgument<T>::type;
131 } // namespace detail
132 
134 // implementation detail
135 #define NDN_LOG_REGISTER_NAME(name) \
136  []() -> bool { \
137  ::ndn::util::Logger::registerModuleName(BOOST_STRINGIZE(name)); \
138  return true; \
139  }()
140 
141 // implementation detail
142 #define NDN_LOG_INIT_FUNCTION_BODY(name) \
143  { \
144  static ::ndn::util::Logger logger(BOOST_STRINGIZE(name)); \
145  return logger; \
146  }
147 
163 #define NDN_LOG_INIT(name) \
164  namespace { \
165  const bool ndn_cxx_loggerRegistration __attribute__((used)) = NDN_LOG_REGISTER_NAME(name); \
166  ::ndn::util::Logger& ndn_cxx_getLogger() \
167  NDN_LOG_INIT_FUNCTION_BODY(name) \
168  } \
169  struct ndn_cxx_allow_trailing_semicolon
170 
181 #define NDN_LOG_MEMBER_DECL() \
182  static ::ndn::util::Logger& ndn_cxx_getLogger(); \
183  private: \
184  static const bool ndn_cxx_loggerRegistration
185 
198 #define NDN_LOG_MEMBER_INIT(cls, name) \
199  const bool ::ndn::util::detail::ArgumentType<void(cls&)>::ndn_cxx_loggerRegistration = \
200  NDN_LOG_REGISTER_NAME(name); \
201  ::ndn::util::Logger& ::ndn::util::detail::ArgumentType<void(cls&)>::ndn_cxx_getLogger() \
202  NDN_LOG_INIT_FUNCTION_BODY(name) \
203  struct ndn_cxx_allow_trailing_semicolon
204 
209 #define NDN_LOG_MEMBER_DECL_SPECIALIZED(cls) \
210  template<> \
211  const bool ::ndn::util::detail::ArgumentType<void(cls&)>::ndn_cxx_loggerRegistration; \
212  template<> \
213  ::ndn::util::Logger& ::ndn::util::detail::ArgumentType<void(cls&)>::ndn_cxx_getLogger()
214 
226 #define NDN_LOG_MEMBER_INIT_SPECIALIZED(cls, name) \
227  template<> \
228  const bool ::ndn::util::detail::ArgumentType<void(cls&)>::ndn_cxx_loggerRegistration = \
229  NDN_LOG_REGISTER_NAME(name); \
230  template<> \
231  ::ndn::util::Logger& ::ndn::util::detail::ArgumentType<void(cls&)>::ndn_cxx_getLogger() \
232  NDN_LOG_INIT_FUNCTION_BODY(name) \
233  struct ndn_cxx_allow_trailing_semicolon
234 
236 // implementation detail
237 #define NDN_LOG_INTERNAL(lvl, expression) \
238  do { \
239  if (ndn_cxx_getLogger().isLevelEnabled(::ndn::util::LogLevel::lvl)) { \
240  BOOST_LOG_SEV(ndn_cxx_getLogger(), ::ndn::util::LogLevel::lvl) \
241  << expression; \
242  } \
243  } while (false)
244 
249 #define NDN_LOG_TRACE(expression) NDN_LOG_INTERNAL(TRACE, expression)
250 
254 #define NDN_LOG_DEBUG(expression) NDN_LOG_INTERNAL(DEBUG, expression)
255 
259 #define NDN_LOG_INFO(expression) NDN_LOG_INTERNAL(INFO, expression)
260 
264 #define NDN_LOG_WARN(expression) NDN_LOG_INTERNAL(WARN, expression)
265 
269 #define NDN_LOG_ERROR(expression) NDN_LOG_INTERNAL(ERROR, expression)
270 
274 #define NDN_LOG_FATAL(expression) NDN_LOG_INTERNAL(FATAL, expression)
275 
276 } // namespace util
277 } // namespace ndn
278 
279 #endif // HAVE_NDN_CXX_CUSTOM_LOGGER
280 
281 #endif // NDN_UTIL_LOGGER_HPP
Definition: data.cpp:26
trace messages (most verbose)
serious error messages
std::ostream & operator<<(std::ostream &os, LogLevel level)
Output LogLevel as a string.
Definition: logger.cpp:31
bool isLevelEnabled(LogLevel level) const
Definition: logger.hpp:93
informational messages
LogLevel
Indicates the severity level of a log message.
Definition: logger.hpp:42
Common includes and macros used throughout the library.
LogLevel parseLogLevel(const std::string &s)
Parse LogLevel from a string.
Definition: logger.cpp:56
warning messages
const std::string & getModuleName() const
Definition: logger.hpp:87
Represents a log module in the logging facility.
Definition: logger.hpp:77
fatal (will be logged unconditionally)
void setLevel(LogLevel level)
Definition: logger.hpp:99