util: fix Logging::getLoggerNames()
Change-Id: Ia243b7eeb7aae69427526e23e7eff4896506871a
diff --git a/src/util/logger.hpp b/src/util/logger.hpp
index 87e317b..75d86b4 100644
--- a/src/util/logger.hpp
+++ b/src/util/logger.hpp
@@ -61,13 +61,18 @@
parseLogLevel(const std::string& s);
/** \brief Represents a log module in the logging facility.
- * \note New loggers should be defined using #NDN_LOG_INIT or #NDN_LOG_MEMBER_INIT.
+ *
+ * \note Normally, loggers should be defined using #NDN_LOG_INIT, #NDN_LOG_MEMBER_INIT,
+ * or #NDN_LOG_MEMBER_INIT_SPECIALIZED.
*/
class Logger : public boost::log::sources::logger_mt
{
public:
explicit
- Logger(const std::string& name);
+ Logger(const char* name);
+
+ static void
+ registerModuleName(const char* name);
const std::string&
getModuleName() const
@@ -126,6 +131,14 @@
} // namespace detail
/** \cond */
+// implementation detail
+#define NDN_LOG_REGISTER_NAME(name) \
+ []() -> bool { \
+ ::ndn::util::Logger::registerModuleName(BOOST_STRINGIZE(name)); \
+ return true; \
+ }()
+
+// implementation detail
#define NDN_LOG_INIT_FUNCTION_BODY(name) \
{ \
static ::ndn::util::Logger logger(BOOST_STRINGIZE(name)); \
@@ -149,47 +162,61 @@
*/
#define NDN_LOG_INIT(name) \
namespace { \
+ const bool ndn_cxx_loggerRegistration __attribute__((used)) = NDN_LOG_REGISTER_NAME(name); \
::ndn::util::Logger& ndn_cxx_getLogger() \
NDN_LOG_INIT_FUNCTION_BODY(name) \
} \
struct ndn_cxx_allow_trailing_semicolon
-/** \brief Define a member log module.
+/** \brief Declare a member log module, without initializing it.
*
- * This macro should only be used to define a log module as a class or struct member.
+ * This macro should only be used to declare a log module as a class or struct member.
* It is recommended to place this macro in the private or protected section of the
- * class or struct definition. Use #NDN_LOG_INIT to define a non-member log module.
+ * class or struct definition. Use #NDN_LOG_INIT to declare a non-member log module.
*
+ * If the enclosing class is a template, this macro can be used in conjunction with
+ * #NDN_LOG_MEMBER_DECL_SPECIALIZED and #NDN_LOG_MEMBER_INIT_SPECIALIZED to provide
+ * different loggers for different template specializations.
+ */
+#define NDN_LOG_MEMBER_DECL() \
+ static ::ndn::util::Logger& ndn_cxx_getLogger(); \
+ private: \
+ static const bool ndn_cxx_loggerRegistration
+
+/** \brief Initialize a member log module.
+ *
+ * This macro should only be used to initialize a previously declared member log module.
+ * It must be placed in a .cpp file (NOT in a header file), in the same namespace as
+ * the class or struct that contains the log module.
+ *
+ * \param cls class name; wrap in parentheses if it contains commas
* \param name the logger name
* \note The logger name is restricted to alphanumeric characters and a select set of
* symbols: `~`, `#`, `%`, `_`, `<`, `>`, `.`, `-`. It must not start or end with
* a dot (`.`), or contain multiple consecutive dots.
*/
-#define NDN_LOG_MEMBER_INIT(name) \
- static ::ndn::util::Logger& ndn_cxx_getLogger() \
+#define NDN_LOG_MEMBER_INIT(cls, name) \
+ const bool ::ndn::util::detail::ArgumentType<void(cls)>::ndn_cxx_loggerRegistration = \
+ NDN_LOG_REGISTER_NAME(name); \
+ ::ndn::util::Logger& ::ndn::util::detail::ArgumentType<void(cls)>::ndn_cxx_getLogger() \
NDN_LOG_INIT_FUNCTION_BODY(name) \
struct ndn_cxx_allow_trailing_semicolon
-/** \brief Forward-declare a member log module, without fully defining it.
- *
- * This macro can be used to declare a log module as a member of a class template.
- * Use this macro in conjunction with #NDN_LOG_MEMBER_DECL_SPECIALIZED and
- * #NDN_LOG_MEMBER_INIT_SPECIALIZED to provide different loggers for different
- * template specializations.
- */
-#define NDN_LOG_MEMBER_DECL() \
- static ::ndn::util::Logger& ndn_cxx_getLogger()
-
/** \brief Declare an explicit specialization of a member log module of a class template.
*
* \param cls fully specialized class name; wrap in parentheses if it contains commas
*/
#define NDN_LOG_MEMBER_DECL_SPECIALIZED(cls) \
template<> \
+ const bool ::ndn::util::detail::ArgumentType<void(cls)>::ndn_cxx_loggerRegistration; \
+ template<> \
::ndn::util::Logger& ::ndn::util::detail::ArgumentType<void(cls)>::ndn_cxx_getLogger()
/** \brief Define an explicit specialization of a member log module of a class template.
*
+ * This macro must be placed in a .cpp file (NOT in a header file), in the same namespace
+ * as the class template that contains the log module.
+ *
* \param cls fully specialized class name; wrap in parentheses if it contains commas
* \param name the logger name
* \note The logger name is restricted to alphanumeric characters and a select set of
@@ -197,7 +224,10 @@
* a dot (`.`), or contain multiple consecutive dots.
*/
#define NDN_LOG_MEMBER_INIT_SPECIALIZED(cls, name) \
- template<> inline \
+ template<> \
+ const bool ::ndn::util::detail::ArgumentType<void(cls)>::ndn_cxx_loggerRegistration = \
+ NDN_LOG_REGISTER_NAME(name); \
+ template<> \
::ndn::util::Logger& ::ndn::util::detail::ArgumentType<void(cls)>::ndn_cxx_getLogger() \
NDN_LOG_INIT_FUNCTION_BODY(name) \
struct ndn_cxx_allow_trailing_semicolon
@@ -210,6 +240,7 @@
#define NDN_BOOST_LOG(x) BOOST_LOG(x)
#endif
+// implementation detail
#define NDN_LOG_INTERNAL(lvl, lvlstr, expression) \
do { \
if (ndn_cxx_getLogger().isLevelEnabled(::ndn::util::LogLevel::lvl)) { \