core: reimplement logging using ndn-cxx's facility

Change-Id: Ifc7c5d70a61ad405dc1f1adfa522a2c0ad1586ab
Refs: #4580
diff --git a/core/log-config-section.cpp b/core/log-config-section.cpp
new file mode 100644
index 0000000..6f6f0ab
--- /dev/null
+++ b/core/log-config-section.cpp
@@ -0,0 +1,96 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "log-config-section.hpp"
+
+#include <ndn-cxx/util/logger.hpp>
+#include <ndn-cxx/util/logging.hpp>
+
+namespace nfd {
+namespace log {
+
+static ndn::util::LogLevel
+parseLogLevel(const ConfigSection& item, const std::string& key)
+{
+  try {
+    return ndn::util::parseLogLevel(item.get_value<std::string>());
+  }
+  catch (const std::invalid_argument& e) {
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid setting for log." + key + ": " + e.what()));
+  }
+}
+
+static void
+onConfig(const ConfigSection& section, bool isDryRun, const std::string&)
+{
+  // log
+  // {
+  //   ; default_level specifies the logging level for modules
+  //   ; that are not explicitly named. All debugging levels
+  //   ; listed above the selected value are enabled.
+  //
+  //   default_level INFO
+  //
+  //   ; You may also override the default for specific modules:
+  //
+  //   FibManager DEBUG
+  //   Forwarder WARN
+  // }
+
+  auto defaultLevel = ndn::util::LogLevel::INFO;
+  auto item = section.get_child_optional("default_level");
+  if (item) {
+    defaultLevel = parseLogLevel(*item, "default_level");
+  }
+  if (!isDryRun) {
+    // default_level applies only to NFD loggers
+    ndn::util::Logging::setLevel("nfd.*", defaultLevel);
+  }
+
+  for (const auto& i : section) {
+    if (i.first == "default_level") {
+      // do nothing
+    }
+    else {
+      auto level = parseLogLevel(i.second, i.first);
+      if (!isDryRun) {
+        if (i.first.find('.') == std::string::npos)
+          // backward compat: assume unqualified logger names refer to NFD loggers
+          ndn::util::Logging::setLevel("nfd." + i.first, level);
+        else
+          ndn::util::Logging::setLevel(i.first, level);
+      }
+    }
+  }
+}
+
+void
+setConfigFile(ConfigFile& config)
+{
+  config.addSectionHandler("log", &onConfig);
+}
+
+} // namespace log
+} // namespace nfd
diff --git a/core/log-config-section.hpp b/core/log-config-section.hpp
new file mode 100644
index 0000000..fbe35f9
--- /dev/null
+++ b/core/log-config-section.hpp
@@ -0,0 +1,40 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_CORE_LOG_CONFIG_SECTION_HPP
+#define NFD_CORE_LOG_CONFIG_SECTION_HPP
+
+#include "config-file.hpp"
+
+namespace nfd {
+namespace log {
+
+void
+setConfigFile(ConfigFile& config);
+
+} // namespace log
+} // namespace nfd
+
+#endif // NFD_CORE_LOG_CONFIG_SECTION_HPP
diff --git a/core/logger-factory.cpp b/core/logger-factory.cpp
deleted file mode 100644
index 215b087..0000000
--- a/core/logger-factory.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2017,  Regents of the University of California,
- *                           Arizona Board of Regents,
- *                           Colorado State University,
- *                           University Pierre & Marie Curie, Sorbonne University,
- *                           Washington University in St. Louis,
- *                           Beijing Institute of Technology,
- *                           The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "logger-factory.hpp"
-
-#include <ndn-cxx/util/logging.hpp>
-
-#include <boost/algorithm/string/case_conv.hpp>
-#include <boost/range/adaptor/map.hpp>
-
-#include <iostream>
-
-#ifdef HAVE_CUSTOM_LOGGER
-#error "This file should not be compiled when custom logger is used"
-#endif
-
-namespace nfd {
-
-NFD_LOG_INIT("LoggerFactory");
-
-LoggerFactory&
-LoggerFactory::getInstance()
-{
-  static LoggerFactory globalLoggerFactory;
-
-  return globalLoggerFactory;
-}
-
-LoggerFactory::LoggerFactory()
-  : m_defaultLevel(LOG_INFO)
-{
-  m_levelNames["NONE"] = LOG_NONE;
-  m_levelNames["ERROR"] = LOG_ERROR;
-  m_levelNames["WARN"] = LOG_WARN;
-  m_levelNames["INFO"] = LOG_INFO;
-  m_levelNames["DEBUG"] = LOG_DEBUG;
-  m_levelNames["TRACE"] = LOG_TRACE;
-  m_levelNames["ALL"] = LOG_ALL;
-
-  // Let ndn-cxx logging facility initialize Boost.Log backend,
-  // so that only one sink is attached to Boost.Log core.
-  ndn::util::Logging::setDestination(std::clog);
-}
-
-LoggerFactory::~LoggerFactory()
-{
-  ndn::util::Logging::flush();
-}
-
-void
-LoggerFactory::setConfigFile(ConfigFile& config)
-{
-  config.addSectionHandler("log", bind(&LoggerFactory::onConfig, this, _1, _2, _3));
-}
-
-LogLevel
-LoggerFactory::parseLevel(const std::string& level)
-{
-  std::string upperLevel = boost::to_upper_copy(level);
-
-  // std::cerr << "parsing level: " << upperLevel << std::endl;;
-  // std::cerr << "# levels: " << m_levelNames.size() << std::endl;
-  // std::cerr << m_levelNames.begin()->first << std::endl;
-
-  LevelMap::const_iterator levelIt = m_levelNames.find(upperLevel);
-  if (levelIt != m_levelNames.end()) {
-    return levelIt->second;
-  }
-  try {
-    uint32_t levelNo = boost::lexical_cast<uint32_t>(level);
-
-    if ((boost::lexical_cast<uint32_t>(LOG_NONE) <= levelNo &&
-         levelNo <= boost::lexical_cast<uint32_t>(LOG_TRACE)) ||
-        levelNo == LOG_ALL) {
-      return static_cast<LogLevel>(levelNo);
-    }
-  }
-  catch (const boost::bad_lexical_cast& error) {
-  }
-
-  BOOST_THROW_EXCEPTION(LoggerFactory::Error("Unsupported logging level \"" + level + "\""));
-}
-
-LogLevel
-LoggerFactory::extractLevel(const ConfigSection& item, const std::string& key)
-{
-  std::string levelString;
-  try {
-    levelString = item.get_value<std::string>();
-  }
-  catch (const boost::property_tree::ptree_error& error) {
-  }
-
-  if (levelString.empty()) {
-    BOOST_THROW_EXCEPTION(LoggerFactory::Error("No logging level found for option \"" + key + "\""));
-  }
-
-  return parseLevel(levelString);
-}
-
-void
-LoggerFactory::onConfig(const ConfigSection& section,
-                        bool isDryRun,
-                        const std::string& filename)
-{
-  // log
-  // {
-  //   ; default_level specifies the logging level for modules
-  //   ; that are not explicitly named. All debugging levels
-  //   ; listed above the selected value are enabled.
-  //
-  //   default_level INFO
-  //
-  //   ; You may also override the default for specific modules:
-  //
-  //   FibManager DEBUG
-  //   Forwarder WARN
-  // }
-
-  if (!isDryRun) {
-    ConfigSection::const_assoc_iterator item = section.find("default_level");
-    if (item != section.not_found()) {
-      LogLevel level = extractLevel(item->second, "default_level");
-      setDefaultLevel(level);
-    }
-    else {
-      setDefaultLevel(LOG_INFO);
-    }
-  }
-
-  for (const auto& i : section) {
-    LogLevel level = extractLevel(i.second, i.first);
-
-    if (i.first == "default_level") {
-      // do nothing
-    }
-    else {
-      std::unique_lock<std::mutex> lock(m_loggersGuard);
-      LoggerMap::iterator loggerIt = m_loggers.find(i.first);
-      if (loggerIt == m_loggers.end()) {
-        lock.unlock();
-        NFD_LOG_DEBUG("Failed to configure logging level for module \"" <<
-                      i.first << "\" (module not found)");
-      }
-      else if (!isDryRun) {
-        loggerIt->second.setLogLevel(level);
-        lock.unlock();
-        NFD_LOG_DEBUG("Changing level for module " << i.first << " to " << level);
-      }
-    }
-  }
-}
-
-void
-LoggerFactory::setDefaultLevel(LogLevel level)
-{
-  // std::cerr << "changing to default_level " << level << std::endl;
-  std::lock_guard<std::mutex> lock(m_loggersGuard);
-
-  m_defaultLevel = level;
-  for (auto&& logger : m_loggers) {
-    // std::cerr << "changing " << i->first << " to default " << m_defaultLevel << std::endl;
-    logger.second.setLogLevel(m_defaultLevel);
-  }
-}
-
-void
-LoggerFactory::flushBackend()
-{
-  ndn::util::Logging::flush();
-}
-
-Logger&
-LoggerFactory::create(const std::string& moduleName)
-{
-  return LoggerFactory::getInstance().createLogger(moduleName);
-}
-
-Logger&
-LoggerFactory::createLogger(const std::string& moduleName)
-{
-  // std::cerr << "creating logger for " << moduleName
-  //           << " with level " << m_defaultLevel << std::endl;
-
-  std::lock_guard<std::mutex> lock(m_loggersGuard);
-
-  std::pair<LoggerMap::iterator, bool> loggerIt =
-    m_loggers.insert(NameAndLogger(moduleName, Logger(moduleName, m_defaultLevel)));
-
-  return loggerIt.first->second;
-}
-
-std::list<std::string>
-LoggerFactory::getModules() const
-{
-  std::lock_guard<std::mutex> lock(m_loggersGuard);
-
-  std::list<std::string> modules;
-  for (const auto& loggerName : m_loggers | boost::adaptors::map_keys) {
-    modules.push_back(loggerName);
-  }
-
-  return modules;
-}
-
-} // namespace nfd
diff --git a/core/logger-factory.hpp b/core/logger-factory.hpp
deleted file mode 100644
index 5cafc64..0000000
--- a/core/logger-factory.hpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
- *                           Arizona Board of Regents,
- *                           Colorado State University,
- *                           University Pierre & Marie Curie, Sorbonne University,
- *                           Washington University in St. Louis,
- *                           Beijing Institute of Technology,
- *                           The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_CORE_LOGGER_FACTORY_HPP
-#define NFD_CORE_LOGGER_FACTORY_HPP
-
-#include "common.hpp"
-
-#ifdef HAVE_CUSTOM_LOGGER
-#include "custom-logger-factory.hpp"
-#else
-
-#include "config-file.hpp"
-#include "logger.hpp"
-
-#include <mutex>
-
-namespace nfd {
-
-class LoggerFactory : noncopyable
-{
-public:
-
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& error)
-      : std::runtime_error(error)
-    {
-    }
-  };
-
-  static LoggerFactory&
-  getInstance();
-
-  void
-  setConfigFile(ConfigFile& config);
-
-  void
-  onConfig(const ConfigSection& section, bool isDryRun, const std::string& filename);
-
-  std::list<std::string>
-  getModules() const;
-
-  static Logger&
-  create(const std::string& moduleName);
-
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-
-  // these methods are used during unit-testing
-
-  LogLevel
-  getDefaultLevel() const;
-
-  void
-  setDefaultLevel(LogLevel level);
-
-  void
-  flushBackend();
-
-private:
-
-  LoggerFactory();
-
-  ~LoggerFactory();
-
-  Logger&
-  createLogger(const std::string& moduleName);
-
-  LogLevel
-  parseLevel(const std::string& level);
-
-  LogLevel
-  extractLevel(const ConfigSection& item, const std::string& key);
-
-private:
-
-  typedef std::map<std::string, LogLevel> LevelMap;
-  typedef std::pair<std::string, LogLevel> NameAndLevel;
-
-  LevelMap m_levelNames;
-
-  typedef std::map<std::string, Logger> LoggerMap;
-  typedef std::pair<std::string, Logger> NameAndLogger;
-
-  LoggerMap m_loggers;
-  mutable std::mutex m_loggersGuard;
-
-  LogLevel m_defaultLevel;
-};
-
-inline LogLevel
-LoggerFactory::getDefaultLevel() const
-{
-  return m_defaultLevel;
-}
-
-} // namespace nfd
-
-#endif // HAVE_CUSTOM_LOGGER
-
-#endif // NFD_CORE_LOGGER_FACTORY_HPP
diff --git a/core/logger.cpp b/core/logger.cpp
deleted file mode 100644
index d1f4e45..0000000
--- a/core/logger.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2018,  Regents of the University of California,
- *                           Arizona Board of Regents,
- *                           Colorado State University,
- *                           University Pierre & Marie Curie, Sorbonne University,
- *                           Washington University in St. Louis,
- *                           Beijing Institute of Technology,
- *                           The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "logger.hpp"
-
-#ifdef HAVE_CUSTOM_LOGGER
-#error "This file should not be compiled when custom logger is used"
-#endif
-
-#include <cinttypes>
-#include <cstdlib>
-#include <stdio.h>
-#include <type_traits>
-
-#include <ndn-cxx/util/time.hpp>
-
-namespace nfd {
-
-Logger::Logger(const std::string& name, LogLevel level)
-  : m_moduleName(name)
-  , m_enabledLogLevel(level)
-{
-}
-
-std::ostream&
-operator<<(std::ostream& os, const LoggerTimestamp&)
-{
-  using namespace ndn::time;
-
-  const auto sinceEpoch = system_clock::now().time_since_epoch();
-  BOOST_ASSERT(sinceEpoch.count() >= 0);
-  // use abs() to silence truncation warning in snprintf(), see #4365
-  const auto usecs = std::abs(duration_cast<microseconds>(sinceEpoch).count());
-  const auto usecsPerSec = microseconds::period::den;
-
-  // 10 (whole seconds) + '.' + 6 (fraction) + '\0'
-  char buffer[10 + 1 + 6 + 1];
-  BOOST_ASSERT_MSG(usecs / usecsPerSec <= 9999999999, "whole seconds cannot fit in 10 characters");
-
-  static_assert(std::is_same<microseconds::rep, int_least64_t>::value,
-                "PRIdLEAST64 is incompatible with microseconds::rep");
-  // std::snprintf unavailable on some platforms, see #2299
-  ::snprintf(buffer, sizeof(buffer), "%" PRIdLEAST64 ".%06" PRIdLEAST64,
-             usecs / usecsPerSec, usecs % usecsPerSec);
-
-  return os << buffer;
-}
-
-} // namespace nfd
diff --git a/core/logger.hpp b/core/logger.hpp
index 24ec63c..b98ff61 100644
--- a/core/logger.hpp
+++ b/core/logger.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -26,146 +26,19 @@
 #ifndef NFD_CORE_LOGGER_HPP
 #define NFD_CORE_LOGGER_HPP
 
-#include "common.hpp"
+#include <ndn-cxx/util/logger.hpp>
 
-#ifdef HAVE_CUSTOM_LOGGER
-#include "custom-logger.hpp"
-#else
-#include <boost/log/common.hpp>
-#include <boost/log/sources/logger.hpp>
+#define NFD_LOG_INIT(name)                         NDN_LOG_INIT(nfd.name)
+#define NFD_LOG_MEMBER_DECL()                      NDN_LOG_MEMBER_DECL()
+#define NFD_LOG_MEMBER_DECL_SPECIALIZED(cls)       NDN_LOG_MEMBER_DECL_SPECIALIZED(cls)
+#define NFD_LOG_MEMBER_INIT(cls, name)             NDN_LOG_MEMBER_INIT(cls, nfd.name)
+#define NFD_LOG_MEMBER_INIT_SPECIALIZED(cls, name) NDN_LOG_MEMBER_INIT_SPECIALIZED(cls, nfd.name)
 
-namespace nfd {
-
-/** \brief indicates a log level
- *  \note This type is internal. Logger should be accessed through NFD_LOG_* macros.
- */
-enum LogLevel {
-  LOG_FATAL          = -1, // fatal (will be logged unconditionally)
-  LOG_NONE           = 0, // no messages
-  LOG_ERROR          = 1, // serious error messages
-  LOG_WARN           = 2, // warning messages
-  LOG_INFO           = 3, // informational messages
-  LOG_DEBUG          = 4, // debug messages
-  LOG_TRACE          = 5, // trace messages (most verbose)
-  LOG_ALL            = 255 // all messages
-};
-
-/** \brief provides logging for a module
- *  \note This type is internal. Logger should be accessed through NFD_LOG_* macros.
- *  \note This type is copyable because logger can be declared as a field of
- *        (usually template) classes, and shouldn't prevent those classes to be copyable.
- */
-class Logger
-{
-public:
-  Logger(const std::string& name, LogLevel level);
-
-  bool
-  isEnabled(LogLevel level) const
-  {
-    return m_enabledLogLevel >= level;
-  }
-
-  void
-  setLogLevel(LogLevel level)
-  {
-    m_enabledLogLevel = level;
-  }
-
-  const std::string&
-  getName() const
-  {
-    return m_moduleName;
-  }
-
-  void
-  setName(const std::string& name)
-  {
-    m_moduleName = name;
-  }
-
-public:
-  boost::log::sources::logger boostLogger;
-
-private:
-  std::string m_moduleName;
-  LogLevel    m_enabledLogLevel;
-};
-
-inline std::ostream&
-operator<<(std::ostream& output, const Logger& logger)
-{
-  output << logger.getName();
-  return output;
-}
-
-/**
- * \brief a tag that writes a timestamp upon stream output
- */
-struct LoggerTimestamp
-{
-};
-
-/**
- * \brief write a timestamp to \p os
- * \note This function is thread-safe.
- */
-std::ostream&
-operator<<(std::ostream& os, const LoggerTimestamp&);
-
-} // namespace nfd
-
-#include "core/logger-factory.hpp"
-
-namespace nfd {
-
-#define NFD_LOG_INIT(name) \
-static ::nfd::Logger& g_logger = ::nfd::LoggerFactory::create(name)
-
-#define NFD_LOG_INCLASS_DECLARE() \
-static ::nfd::Logger& g_logger
-
-#define NFD_LOG_INCLASS_DEFINE(cls, name) \
-::nfd::Logger& cls::g_logger = ::nfd::LoggerFactory::create(name)
-
-#define NFD_LOG_INCLASS_TEMPLATE_DEFINE(cls, name) \
-template<class T>                                  \
-::nfd::Logger& cls<T>::g_logger = ::nfd::LoggerFactory::create(name)
-
-#define NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(cls, specialization, name) \
-template<>                                                                        \
-::nfd::Logger& cls<specialization>::g_logger = ::nfd::LoggerFactory::create(name)
-
-#define NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(cls, s1, s2, name) \
-template<>                                                                 \
-::nfd::Logger& cls<s1, s2>::g_logger = ::nfd::LoggerFactory::create(name)
-
-#if (BOOST_VERSION >= 105900) && (BOOST_VERSION < 106000)
-// workaround Boost bug 11549
-#define NFD_BOOST_LOG(x) BOOST_LOG(x) << ""
-#else
-#define NFD_BOOST_LOG(x) BOOST_LOG(x)
-#endif
-
-#define NFD_LOG_LINE(msg, expression) \
-::nfd::LoggerTimestamp{} << " "#msg": " << "[" << g_logger  << "] " << expression
-
-#define NFD_LOG(level, msg, expression)                                 \
-  do {                                                                  \
-    if (g_logger.isEnabled(::nfd::LOG_##level)) {                       \
-      NFD_BOOST_LOG(g_logger.boostLogger) << NFD_LOG_LINE(msg, expression); \
-    }                                                                   \
-  } while (false)
-
-#define NFD_LOG_TRACE(expression) NFD_LOG(TRACE, TRACE,   expression)
-#define NFD_LOG_DEBUG(expression) NFD_LOG(DEBUG, DEBUG,   expression)
-#define NFD_LOG_INFO(expression)  NFD_LOG(INFO,  INFO,    expression)
-#define NFD_LOG_WARN(expression)  NFD_LOG(WARN,  WARNING, expression)
-#define NFD_LOG_ERROR(expression) NFD_LOG(ERROR, ERROR,   expression)
-#define NFD_LOG_FATAL(expression) NFD_LOG(FATAL, FATAL,   expression)
-
-} // namespace nfd
-
-#endif // HAVE_CUSTOM_LOGGER
+#define NFD_LOG_TRACE NDN_LOG_TRACE
+#define NFD_LOG_DEBUG NDN_LOG_DEBUG
+#define NFD_LOG_INFO  NDN_LOG_INFO
+#define NFD_LOG_WARN  NDN_LOG_WARN
+#define NFD_LOG_ERROR NDN_LOG_ERROR
+#define NFD_LOG_FATAL NDN_LOG_FATAL
 
 #endif // NFD_CORE_LOGGER_HPP
diff --git a/core/privilege-helper.cpp b/core/privilege-helper.cpp
index edc8336..923efa4 100644
--- a/core/privilege-helper.cpp
+++ b/core/privilege-helper.cpp
@@ -31,7 +31,7 @@
 
 namespace nfd {
 
-NFD_LOG_INIT("PrivilegeHelper");
+NFD_LOG_INIT(PrivilegeHelper);
 
 #ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
 uid_t PrivilegeHelper::s_normalUid = ::geteuid();
@@ -123,6 +123,9 @@
 void
 PrivilegeHelper::drop()
 {
+  if (::geteuid() == s_normalUid && ::getegid() == s_normalGid)
+    return;
+
 #ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
   NFD_LOG_TRACE("dropping to effective gid=" << s_normalGid);
   if (::setegid(s_normalGid) != 0)
@@ -141,6 +144,9 @@
 void
 PrivilegeHelper::raise()
 {
+  if (::geteuid() == s_privilegedUid && ::getegid() == s_privilegedGid)
+    return;
+
 #ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
   NFD_LOG_TRACE("elevating to effective uid=" << s_privilegedUid);
   if (::seteuid(s_privilegedUid) != 0)
diff --git a/daemon/face/datagram-transport.hpp b/daemon/face/datagram-transport.hpp
index 2b2cc29..0b375ad 100644
--- a/daemon/face/datagram-transport.hpp
+++ b/daemon/face/datagram-transport.hpp
@@ -95,7 +95,7 @@
   typename protocol::socket m_socket;
   typename protocol::endpoint m_sender;
 
-  NFD_LOG_INCLASS_DECLARE();
+  NFD_LOG_MEMBER_DECL();
 
 private:
   std::array<uint8_t, ndn::MAX_NDN_PACKET_SIZE> m_receiveBuffer;
diff --git a/daemon/face/ethernet-channel.cpp b/daemon/face/ethernet-channel.cpp
index cf60527..3791d44 100644
--- a/daemon/face/ethernet-channel.cpp
+++ b/daemon/face/ethernet-channel.cpp
@@ -35,7 +35,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("EthernetChannel");
+NFD_LOG_INIT(EthernetChannel);
 
 EthernetChannel::EthernetChannel(shared_ptr<const ndn::net::NetworkInterface> localEndpoint,
                                  time::nanoseconds idleTimeout)
diff --git a/daemon/face/ethernet-factory.cpp b/daemon/face/ethernet-factory.cpp
index 2c6c39c..d921855 100644
--- a/daemon/face/ethernet-factory.cpp
+++ b/daemon/face/ethernet-factory.cpp
@@ -33,7 +33,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("EthernetFactory");
+NFD_LOG_INIT(EthernetFactory);
 NFD_REGISTER_PROTOCOL_FACTORY(EthernetFactory);
 
 const std::string&
diff --git a/daemon/face/ethernet-transport.cpp b/daemon/face/ethernet-transport.cpp
index 5a8f91a..a7e8907 100644
--- a/daemon/face/ethernet-transport.cpp
+++ b/daemon/face/ethernet-transport.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -35,7 +35,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("EthernetTransport");
+NFD_LOG_INIT(EthernetTransport);
 
 EthernetTransport::EthernetTransport(const ndn::net::NetworkInterface& localEndpoint,
                                      const ethernet::Address& remoteEndpoint)
diff --git a/daemon/face/face-system.cpp b/daemon/face/face-system.cpp
index ebdce9c..1d2db37 100644
--- a/daemon/face/face-system.cpp
+++ b/daemon/face/face-system.cpp
@@ -31,7 +31,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("FaceSystem");
+NFD_LOG_INIT(FaceSystem);
 
 FaceSystem::FaceSystem(FaceTable& faceTable, shared_ptr<ndn::net::NetworkMonitor> netmon)
   : m_faceTable(faceTable)
diff --git a/daemon/face/generic-link-service.cpp b/daemon/face/generic-link-service.cpp
index d7ebc7c..5122755 100644
--- a/daemon/face/generic-link-service.cpp
+++ b/daemon/face/generic-link-service.cpp
@@ -32,7 +32,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("GenericLinkService");
+NFD_LOG_INIT(GenericLinkService);
 
 constexpr uint32_t DEFAULT_CONGESTION_THRESHOLD_DIVISOR = 2;
 
diff --git a/daemon/face/internal-transport.cpp b/daemon/face/internal-transport.cpp
index 5b82c20..7e7ac3e 100644
--- a/daemon/face/internal-transport.cpp
+++ b/daemon/face/internal-transport.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -29,11 +29,11 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INCLASS_DEFINE(InternalForwarderTransport, "InternalForwarderTransport");
+NFD_LOG_MEMBER_INIT(InternalForwarderTransport, InternalForwarderTransport);
+NFD_LOG_MEMBER_INIT(InternalClientTransport, InternalClientTransport);
 
-InternalForwarderTransport::InternalForwarderTransport(
-    const FaceUri& localUri, const FaceUri& remoteUri,
-    ndn::nfd::FaceScope scope, ndn::nfd::LinkType linkType)
+InternalForwarderTransport::InternalForwarderTransport(const FaceUri& localUri, const FaceUri& remoteUri,
+                                                       ndn::nfd::FaceScope scope, ndn::nfd::LinkType linkType)
 {
   this->setLocalUri(localUri);
   this->setRemoteUri(remoteUri);
@@ -71,8 +71,6 @@
   this->setState(TransportState::CLOSED);
 }
 
-NFD_LOG_INCLASS_DEFINE(InternalClientTransport, "InternalClientTransport");
-
 static void
 asyncReceive(InternalTransportBase* recipient, const Block& packet)
 {
diff --git a/daemon/face/internal-transport.hpp b/daemon/face/internal-transport.hpp
index 67a53b3..9f834d7 100644
--- a/daemon/face/internal-transport.hpp
+++ b/daemon/face/internal-transport.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -27,6 +27,7 @@
 #define NFD_DAEMON_FACE_INTERNAL_TRANSPORT_HPP
 
 #include "transport.hpp"
+
 #include <ndn-cxx/transport/transport.hpp>
 
 namespace nfd {
@@ -73,7 +74,7 @@
   doSend(Packet&& packet) override;
 
 private:
-  NFD_LOG_INCLASS_DECLARE();
+  NFD_LOG_MEMBER_DECL();
 };
 
 /** \brief implements a client-side transport that can be paired with another
@@ -117,7 +118,7 @@
   send(const Block& header, const Block& payload) override;
 
 private:
-  NFD_LOG_INCLASS_DECLARE();
+  NFD_LOG_MEMBER_DECL();
 
   signal::ScopedConnection m_fwToClientTransmitConn;
   signal::ScopedConnection m_clientToFwTransmitConn;
diff --git a/daemon/face/link-service.cpp b/daemon/face/link-service.cpp
index 9b05c2a..c5dcdfc 100644
--- a/daemon/face/link-service.cpp
+++ b/daemon/face/link-service.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -29,7 +29,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("LinkService");
+NFD_LOG_INIT(LinkService);
 
 LinkService::LinkService()
   : m_face(nullptr)
diff --git a/daemon/face/lp-fragmenter.cpp b/daemon/face/lp-fragmenter.cpp
index b54f7d5..1928bf5 100644
--- a/daemon/face/lp-fragmenter.cpp
+++ b/daemon/face/lp-fragmenter.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -25,12 +25,13 @@
 
 #include "lp-fragmenter.hpp"
 #include "link-service.hpp"
+
 #include <ndn-cxx/encoding/tlv.hpp>
 
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("LpFragmenter");
+NFD_LOG_INIT(LpFragmenter);
 
 static_assert(lp::tlv::LpPacket < 253, "LpPacket TLV-TYPE must fit in 1 octet");
 static_assert(lp::tlv::Sequence < 253, "Sequence TLV-TYPE must fit in 1 octet");
diff --git a/daemon/face/lp-fragmenter.hpp b/daemon/face/lp-fragmenter.hpp
index 8275d0f..40d32cb 100644
--- a/daemon/face/lp-fragmenter.hpp
+++ b/daemon/face/lp-fragmenter.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -26,6 +26,7 @@
 #ifndef NFD_DAEMON_FACE_LP_FRAGMENTER_HPP
 #define NFD_DAEMON_FACE_LP_FRAGMENTER_HPP
 
+#include "core/common.hpp"
 #include "face-log.hpp"
 
 #include <ndn-cxx/lp/packet.hpp>
@@ -36,7 +37,7 @@
 class LinkService;
 
 /** \brief fragments network-layer packets into NDNLPv2 link-layer packets
- *  \sa http://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
+ *  \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
  */
 class LpFragmenter
 {
diff --git a/daemon/face/lp-reassembler.cpp b/daemon/face/lp-reassembler.cpp
index 88ef1c1..a6d1c60 100644
--- a/daemon/face/lp-reassembler.cpp
+++ b/daemon/face/lp-reassembler.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -25,12 +25,13 @@
 
 #include "lp-reassembler.hpp"
 #include "link-service.hpp"
+
 #include <numeric>
 
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("LpReassembler");
+NFD_LOG_INIT(LpReassembler);
 
 LpReassembler::Options::Options()
   : nMaxFragments(400)
diff --git a/daemon/face/multicast-ethernet-transport.cpp b/daemon/face/multicast-ethernet-transport.cpp
index b7bbdc2..91c25d4 100644
--- a/daemon/face/multicast-ethernet-transport.cpp
+++ b/daemon/face/multicast-ethernet-transport.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -46,7 +46,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("MulticastEthernetTransport");
+NFD_LOG_INIT(MulticastEthernetTransport);
 
 MulticastEthernetTransport::MulticastEthernetTransport(const ndn::net::NetworkInterface& localEndpoint,
                                                        const ethernet::Address& mcastAddress,
diff --git a/daemon/face/multicast-udp-transport.cpp b/daemon/face/multicast-udp-transport.cpp
index 80f86ae..3574158 100644
--- a/daemon/face/multicast-udp-transport.cpp
+++ b/daemon/face/multicast-udp-transport.cpp
@@ -40,8 +40,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(DatagramTransport, MulticastUdpTransport::protocol,
-                                                Multicast, "MulticastUdpTransport");
+NFD_LOG_MEMBER_INIT_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Multicast>), MulticastUdpTransport);
 
 MulticastUdpTransport::MulticastUdpTransport(const protocol::endpoint& multicastGroup,
                                              protocol::socket&& recvSocket,
diff --git a/daemon/face/multicast-udp-transport.hpp b/daemon/face/multicast-udp-transport.hpp
index ba7bcbe..72498d0 100644
--- a/daemon/face/multicast-udp-transport.hpp
+++ b/daemon/face/multicast-udp-transport.hpp
@@ -33,6 +33,8 @@
 namespace nfd {
 namespace face {
 
+NFD_LOG_MEMBER_DECL_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Multicast>));
+
 // Explicit specialization of makeEndpointId for the UDP multicast case.
 // Note that this "shall be declared before the first use of the specialization
 // that would cause an implicit instantiation to take place, in every translation
diff --git a/daemon/face/stream-transport.hpp b/daemon/face/stream-transport.hpp
index 0adbf26..d70e4f6 100644
--- a/daemon/face/stream-transport.hpp
+++ b/daemon/face/stream-transport.hpp
@@ -97,7 +97,7 @@
 protected:
   typename protocol::socket m_socket;
 
-  NFD_LOG_INCLASS_DECLARE();
+  NFD_LOG_MEMBER_DECL();
 
 private:
   uint8_t m_receiveBuffer[ndn::MAX_NDN_PACKET_SIZE];
diff --git a/daemon/face/tcp-channel.cpp b/daemon/face/tcp-channel.cpp
index 058bbe5..968c6a7 100644
--- a/daemon/face/tcp-channel.cpp
+++ b/daemon/face/tcp-channel.cpp
@@ -31,7 +31,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("TcpChannel");
+NFD_LOG_INIT(TcpChannel);
 
 namespace ip = boost::asio::ip;
 
diff --git a/daemon/face/tcp-factory.cpp b/daemon/face/tcp-factory.cpp
index 1831467..02d5f33 100644
--- a/daemon/face/tcp-factory.cpp
+++ b/daemon/face/tcp-factory.cpp
@@ -32,7 +32,7 @@
 
 namespace ip = boost::asio::ip;
 
-NFD_LOG_INIT("TcpFactory");
+NFD_LOG_INIT(TcpFactory);
 NFD_REGISTER_PROTOCOL_FACTORY(TcpFactory);
 
 const std::string&
diff --git a/daemon/face/tcp-transport.cpp b/daemon/face/tcp-transport.cpp
index eef8570..ad1be5d 100644
--- a/daemon/face/tcp-transport.cpp
+++ b/daemon/face/tcp-transport.cpp
@@ -33,7 +33,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(StreamTransport, TcpTransport::protocol, "TcpTransport");
+NFD_LOG_MEMBER_INIT_SPECIALIZED(StreamTransport<boost::asio::ip::tcp>, TcpTransport);
 
 time::milliseconds TcpTransport::s_initialReconnectWait = time::seconds(1);
 time::milliseconds TcpTransport::s_maxReconnectWait = time::minutes(5);
diff --git a/daemon/face/tcp-transport.hpp b/daemon/face/tcp-transport.hpp
index 9367ffe..adf5085 100644
--- a/daemon/face/tcp-transport.hpp
+++ b/daemon/face/tcp-transport.hpp
@@ -32,6 +32,8 @@
 namespace nfd {
 namespace face {
 
+NFD_LOG_MEMBER_DECL_SPECIALIZED(StreamTransport<boost::asio::ip::tcp>);
+
 /**
  * \brief A Transport that communicates on a connected TCP socket
  *
diff --git a/daemon/face/transport.cpp b/daemon/face/transport.cpp
index 863b2b3..f615a10 100644
--- a/daemon/face/transport.cpp
+++ b/daemon/face/transport.cpp
@@ -29,7 +29,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("Transport");
+NFD_LOG_INIT(Transport);
 
 std::ostream&
 operator<<(std::ostream& os, TransportState state)
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index 209aa70..3d6e6b8 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -31,7 +31,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("UdpChannel");
+NFD_LOG_INIT(UdpChannel);
 
 namespace ip = boost::asio::ip;
 
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index 377d3b1..2b7b3c8 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -38,7 +38,7 @@
 namespace ip = boost::asio::ip;
 namespace net = ndn::net;
 
-NFD_LOG_INIT("UdpFactory");
+NFD_LOG_INIT(UdpFactory);
 NFD_REGISTER_PROTOCOL_FACTORY(UdpFactory);
 
 const std::string&
diff --git a/daemon/face/unicast-ethernet-transport.cpp b/daemon/face/unicast-ethernet-transport.cpp
index e2e56d0..e28fa93 100644
--- a/daemon/face/unicast-ethernet-transport.cpp
+++ b/daemon/face/unicast-ethernet-transport.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -30,7 +30,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("UnicastEthernetTransport");
+NFD_LOG_INIT(UnicastEthernetTransport);
 
 UnicastEthernetTransport::UnicastEthernetTransport(const ndn::net::NetworkInterface& localEndpoint,
                                                    const ethernet::Address& remoteEndpoint,
diff --git a/daemon/face/unicast-udp-transport.cpp b/daemon/face/unicast-udp-transport.cpp
index 4f8a8f7..8e3d7d8 100644
--- a/daemon/face/unicast-udp-transport.cpp
+++ b/daemon/face/unicast-udp-transport.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -36,8 +36,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(DatagramTransport, UnicastUdpTransport::protocol,
-                                               "UnicastUdpTransport");
+NFD_LOG_MEMBER_INIT_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Unicast>), UnicastUdpTransport);
 
 UnicastUdpTransport::UnicastUdpTransport(protocol::socket&& socket,
                                          ndn::nfd::FacePersistency persistency,
diff --git a/daemon/face/unicast-udp-transport.hpp b/daemon/face/unicast-udp-transport.hpp
index 6136746..b1eb672 100644
--- a/daemon/face/unicast-udp-transport.hpp
+++ b/daemon/face/unicast-udp-transport.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -32,6 +32,8 @@
 namespace nfd {
 namespace face {
 
+NFD_LOG_MEMBER_DECL_SPECIALIZED((DatagramTransport<boost::asio::ip::udp, Unicast>));
+
 /**
  * \brief A Transport that communicates on a unicast UDP socket
  */
diff --git a/daemon/face/unix-stream-channel.cpp b/daemon/face/unix-stream-channel.cpp
index fcc8fe7..a127c84 100644
--- a/daemon/face/unix-stream-channel.cpp
+++ b/daemon/face/unix-stream-channel.cpp
@@ -34,7 +34,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("UnixStreamChannel");
+NFD_LOG_INIT(UnixStreamChannel);
 
 UnixStreamChannel::UnixStreamChannel(const unix_stream::Endpoint& endpoint,
                                      bool wantCongestionMarking)
diff --git a/daemon/face/unix-stream-factory.cpp b/daemon/face/unix-stream-factory.cpp
index 439eff4..2d8567a 100644
--- a/daemon/face/unix-stream-factory.cpp
+++ b/daemon/face/unix-stream-factory.cpp
@@ -30,7 +30,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("UnixStreamFactory");
+NFD_LOG_INIT(UnixStreamFactory);
 NFD_REGISTER_PROTOCOL_FACTORY(UnixStreamFactory);
 
 const std::string&
diff --git a/daemon/face/unix-stream-transport.cpp b/daemon/face/unix-stream-transport.cpp
index cbbda54..b1987a5 100644
--- a/daemon/face/unix-stream-transport.cpp
+++ b/daemon/face/unix-stream-transport.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -28,8 +28,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(StreamTransport, UnixStreamTransport::protocol,
-                                               "UnixStreamTransport");
+NFD_LOG_MEMBER_INIT_SPECIALIZED(StreamTransport<boost::asio::local::stream_protocol>, UnixStreamTransport);
 
 UnixStreamTransport::UnixStreamTransport(protocol::socket&& socket)
   : StreamTransport(std::move(socket))
diff --git a/daemon/face/unix-stream-transport.hpp b/daemon/face/unix-stream-transport.hpp
index 510350e..a52567a 100644
--- a/daemon/face/unix-stream-transport.hpp
+++ b/daemon/face/unix-stream-transport.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -35,6 +35,8 @@
 namespace nfd {
 namespace face {
 
+NFD_LOG_MEMBER_DECL_SPECIALIZED(StreamTransport<boost::asio::local::stream_protocol>);
+
 /**
  * \brief A Transport that communicates on a stream-oriented Unix domain socket
  */
diff --git a/daemon/face/websocket-channel.cpp b/daemon/face/websocket-channel.cpp
index d26a0b5..2ac9384 100644
--- a/daemon/face/websocket-channel.cpp
+++ b/daemon/face/websocket-channel.cpp
@@ -31,7 +31,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("WebSocketChannel");
+NFD_LOG_INIT(WebSocketChannel);
 
 WebSocketChannel::WebSocketChannel(const websocket::Endpoint& localEndpoint)
   : m_localEndpoint(localEndpoint)
diff --git a/daemon/face/websocket-factory.cpp b/daemon/face/websocket-factory.cpp
index c61d900..11921cc 100644
--- a/daemon/face/websocket-factory.cpp
+++ b/daemon/face/websocket-factory.cpp
@@ -30,7 +30,7 @@
 
 namespace ip = boost::asio::ip;
 
-NFD_LOG_INIT("WebSocketFactory");
+NFD_LOG_INIT(WebSocketFactory);
 NFD_REGISTER_PROTOCOL_FACTORY(WebSocketFactory);
 
 const std::string&
diff --git a/daemon/face/websocket-transport.cpp b/daemon/face/websocket-transport.cpp
index d4bbbac..97af039 100644
--- a/daemon/face/websocket-transport.cpp
+++ b/daemon/face/websocket-transport.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -28,7 +28,7 @@
 namespace nfd {
 namespace face {
 
-NFD_LOG_INIT("WebSocketTransport");
+NFD_LOG_INIT(WebSocketTransport);
 
 static bool
 isLoopback(const boost::asio::ip::address& addr)
diff --git a/daemon/fw/access-strategy.cpp b/daemon/fw/access-strategy.cpp
index 377ef80..a766424 100644
--- a/daemon/fw/access-strategy.cpp
+++ b/daemon/fw/access-strategy.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -30,7 +30,7 @@
 namespace nfd {
 namespace fw {
 
-NFD_LOG_INIT("AccessStrategy");
+NFD_LOG_INIT(AccessStrategy);
 NFD_REGISTER_STRATEGY(AccessStrategy);
 
 AccessStrategy::AccessStrategy(Forwarder& forwarder, const Name& name)
diff --git a/daemon/fw/asf-measurements.cpp b/daemon/fw/asf-measurements.cpp
index e85ec3f..0d772ac 100644
--- a/daemon/fw/asf-measurements.cpp
+++ b/daemon/fw/asf-measurements.cpp
@@ -29,7 +29,7 @@
 namespace fw {
 namespace asf {
 
-NFD_LOG_INIT("AsfMeasurements");
+NFD_LOG_INIT(AsfMeasurements);
 
 const RttStats::Rtt RttStats::RTT_TIMEOUT(-1.0);
 const RttStats::Rtt RttStats::RTT_NO_MEASUREMENT(0.0);
diff --git a/daemon/fw/asf-strategy.cpp b/daemon/fw/asf-strategy.cpp
index ab629f9..d47649d 100644
--- a/daemon/fw/asf-strategy.cpp
+++ b/daemon/fw/asf-strategy.cpp
@@ -25,14 +25,13 @@
 
 #include "asf-strategy.hpp"
 #include "algorithm.hpp"
-
 #include "core/logger.hpp"
 
 namespace nfd {
 namespace fw {
 namespace asf {
 
-NFD_LOG_INIT("AsfStrategy");
+NFD_LOG_INIT(AsfStrategy);
 NFD_REGISTER_STRATEGY(AsfStrategy);
 
 const time::milliseconds AsfStrategy::RETX_SUPPRESSION_INITIAL(10);
diff --git a/daemon/fw/best-route-strategy2.cpp b/daemon/fw/best-route-strategy2.cpp
index 61dc07a..2956ed7 100644
--- a/daemon/fw/best-route-strategy2.cpp
+++ b/daemon/fw/best-route-strategy2.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -30,7 +30,7 @@
 namespace nfd {
 namespace fw {
 
-NFD_LOG_INIT("BestRouteStrategy2");
+NFD_LOG_INIT(BestRouteStrategy2);
 NFD_REGISTER_STRATEGY(BestRouteStrategy2);
 
 const time::milliseconds BestRouteStrategy2::RETX_SUPPRESSION_INITIAL(10);
diff --git a/daemon/fw/client-control-strategy.cpp b/daemon/fw/client-control-strategy.cpp
index 1de5a58..f381c04 100644
--- a/daemon/fw/client-control-strategy.cpp
+++ b/daemon/fw/client-control-strategy.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -29,7 +29,7 @@
 namespace nfd {
 namespace fw {
 
-NFD_LOG_INIT("ClientControlStrategy");
+NFD_LOG_INIT(ClientControlStrategy);
 NFD_REGISTER_STRATEGY(ClientControlStrategy);
 
 ClientControlStrategy::ClientControlStrategy(Forwarder& forwarder, const Name& name)
diff --git a/daemon/fw/face-table.cpp b/daemon/fw/face-table.cpp
index fbd90f0..3e19dd1 100644
--- a/daemon/fw/face-table.cpp
+++ b/daemon/fw/face-table.cpp
@@ -34,7 +34,7 @@
 
 NDN_CXX_ASSERT_FORWARD_ITERATOR(FaceTable::const_iterator);
 
-NFD_LOG_INIT("FaceTable");
+NFD_LOG_INIT(FaceTable);
 
 FaceTable::FaceTable()
   : m_lastFaceId(face::FACEID_RESERVED_MAX)
diff --git a/daemon/fw/forwarder.cpp b/daemon/fw/forwarder.cpp
index f967e0b..accfb38 100644
--- a/daemon/fw/forwarder.cpp
+++ b/daemon/fw/forwarder.cpp
@@ -24,16 +24,18 @@
  */
 
 #include "forwarder.hpp"
+
 #include "algorithm.hpp"
 #include "best-route-strategy2.hpp"
 #include "strategy.hpp"
 #include "core/logger.hpp"
 #include "table/cleanup.hpp"
+
 #include <ndn-cxx/lp/tags.hpp>
 
 namespace nfd {
 
-NFD_LOG_INIT("Forwarder");
+NFD_LOG_INIT(Forwarder);
 
 static Name
 getDefaultStrategyName()
diff --git a/daemon/fw/multicast-strategy.cpp b/daemon/fw/multicast-strategy.cpp
index 297f481..6a05356 100644
--- a/daemon/fw/multicast-strategy.cpp
+++ b/daemon/fw/multicast-strategy.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -32,7 +32,7 @@
 
 NFD_REGISTER_STRATEGY(MulticastStrategy);
 
-NFD_LOG_INIT("MulticastStrategy");
+NFD_LOG_INIT(MulticastStrategy);
 
 const time::milliseconds MulticastStrategy::RETX_SUPPRESSION_INITIAL(10);
 const time::milliseconds MulticastStrategy::RETX_SUPPRESSION_MAX(250);
diff --git a/daemon/fw/process-nack-traits.cpp b/daemon/fw/process-nack-traits.cpp
index cd1f00e..584bf70 100644
--- a/daemon/fw/process-nack-traits.cpp
+++ b/daemon/fw/process-nack-traits.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -29,7 +29,7 @@
 namespace nfd {
 namespace fw {
 
-NFD_LOG_INIT("ProcessNackTraits");
+NFD_LOG_INIT(ProcessNackTraits);
 
 void
 ProcessNackTraitsBase::processNack(const Face& inFace, const lp::Nack& nack,
diff --git a/daemon/fw/strategy.cpp b/daemon/fw/strategy.cpp
index 278e016..4dfe32e 100644
--- a/daemon/fw/strategy.cpp
+++ b/daemon/fw/strategy.cpp
@@ -27,13 +27,14 @@
 #include "forwarder.hpp"
 #include "core/logger.hpp"
 #include "core/random.hpp"
+
 #include <boost/range/adaptor/map.hpp>
 #include <boost/range/algorithm/copy.hpp>
 
 namespace nfd {
 namespace fw {
 
-NFD_LOG_INIT("Strategy");
+NFD_LOG_INIT(Strategy);
 
 Strategy::Registry&
 Strategy::getRegistry()
diff --git a/daemon/main.cpp b/daemon/main.cpp
index c549ac9..0de725e 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -29,11 +29,10 @@
 #include "core/extended-error-message.hpp"
 #include "core/global-io.hpp"
 #include "core/logger.hpp"
-#include "core/logger-factory.hpp"
 #include "core/privilege-helper.hpp"
 #include "core/version.hpp"
 
-#include <string.h>
+#include <string.h> // for strsignal()
 
 #include <boost/config.hpp>
 #include <boost/filesystem.hpp>
@@ -49,7 +48,9 @@
 #include <condition_variable>
 #include <iostream>
 
+#include <ndn-cxx/util/logging.hpp>
 #include <ndn-cxx/version.hpp>
+
 #ifdef HAVE_LIBPCAP
 #include <pcap/pcap.h>
 #endif
@@ -59,7 +60,7 @@
 
 namespace po = boost::program_options;
 
-NFD_LOG_INIT("Main");
+NFD_LOG_INIT(Main);
 
 namespace nfd {
 
@@ -205,10 +206,10 @@
 };
 
 static void
-printUsage(std::ostream& os, const char* programName,
-           const po::options_description& opts)
+printUsage(std::ostream& os, const char* programName, const po::options_description& opts)
 {
   os << "Usage: " << programName << " [options]\n"
+     << "\n"
      << "Run the NDN Forwarding Daemon (NFD)\n"
      << "\n"
      << opts;
@@ -217,10 +218,9 @@
 static void
 printLogModules(std::ostream& os)
 {
-  const auto& factory = LoggerFactory::getInstance();
-  for (const auto& module : factory.getModules()) {
-    os << module << "\n";
-  }
+  const auto& modules = ndn::util::Logging::getLoggerNames();
+  std::copy(modules.begin(), modules.end(), ndn::make_ostream_joiner(os, "\n"));
+  os << std::endl;
 }
 
 } // namespace nfd
@@ -247,8 +247,9 @@
     po::notify(vm);
   }
   catch (const std::exception& e) {
-    // avoid NFD_LOG_FATAL to ensure that errors related to command-line parsing always appear on the
-    // terminal and are not littered with timestamps and other things added by the logging subsystem
+    // Cannot use NFD_LOG_* macros here, because the logging subsystem is not initialized yet
+    // at this point. Moreover, we don't want to clutter error messages related to command-line
+    // parsing with timestamps and other useless text added by the macros.
     std::cerr << "ERROR: " << e.what() << "\n\n";
     printUsage(std::cerr, argv[0], description);
     return 2;
@@ -288,13 +289,13 @@
       "without WebSocket++";
 #endif
 
-  NFD_LOG_INFO("NFD version " NFD_VERSION_BUILD_STRING " starting");
-  NFD_LOG_INFO("Built with " BOOST_COMPILER
-               ", with " BOOST_STDLIB
+  std::clog << "NFD version " NFD_VERSION_BUILD_STRING " starting\n"
+            << "Built with " BOOST_COMPILER ", with " BOOST_STDLIB
                ", " << boostBuildInfo <<
                ", " << pcapBuildInfo <<
                ", " << wsBuildInfo <<
-               ", with ndn-cxx version " NDN_CXX_VERSION_BUILD_STRING);
+               ", with ndn-cxx version " NDN_CXX_VERSION_BUILD_STRING
+            << std::endl;
 
   NfdRunner runner(configFile);
   try {
diff --git a/daemon/mgmt/command-authenticator.cpp b/daemon/mgmt/command-authenticator.cpp
index 04f2476..0b6346b 100644
--- a/daemon/mgmt/command-authenticator.cpp
+++ b/daemon/mgmt/command-authenticator.cpp
@@ -41,7 +41,7 @@
 
 namespace nfd {
 
-NFD_LOG_INIT("CommandAuthenticator");
+NFD_LOG_INIT(CommandAuthenticator);
 // INFO: configuration change, etc
 // DEBUG: per authentication request result
 
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index 76fac1c..1d53eab 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -24,6 +24,8 @@
  */
 
 #include "face-manager.hpp"
+
+#include "core/logger.hpp"
 #include "face/generic-link-service.hpp"
 #include "face/protocol-factory.hpp"
 #include "fw/face-table.hpp"
@@ -35,7 +37,7 @@
 
 namespace nfd {
 
-NFD_LOG_INIT("FaceManager");
+NFD_LOG_INIT(FaceManager);
 
 FaceManager::FaceManager(FaceSystem& faceSystem,
                          Dispatcher& dispatcher,
diff --git a/daemon/mgmt/fib-manager.cpp b/daemon/mgmt/fib-manager.cpp
index 06e660a..5c04977 100644
--- a/daemon/mgmt/fib-manager.cpp
+++ b/daemon/mgmt/fib-manager.cpp
@@ -24,6 +24,8 @@
  */
 
 #include "fib-manager.hpp"
+
+#include "core/logger.hpp"
 #include "fw/face-table.hpp"
 
 #include <ndn-cxx/lp/tags.hpp>
@@ -33,7 +35,7 @@
 
 namespace nfd {
 
-NFD_LOG_INIT("FibManager");
+NFD_LOG_INIT(FibManager);
 
 FibManager::FibManager(Fib& fib,
                        const FaceTable& faceTable,
diff --git a/daemon/mgmt/fib-manager.hpp b/daemon/mgmt/fib-manager.hpp
index b5c6984..c5455e9 100644
--- a/daemon/mgmt/fib-manager.hpp
+++ b/daemon/mgmt/fib-manager.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -27,9 +27,8 @@
 #define NFD_DAEMON_MGMT_FIB_MANAGER_HPP
 
 #include "nfd-manager-base.hpp"
-#include "core/logger.hpp"
-#include "table/fib.hpp"
 #include "fw/forwarder.hpp"
+#include "table/fib.hpp"
 
 namespace nfd {
 
@@ -37,7 +36,7 @@
 
 /**
  * @brief implement the FIB Management of NFD Management Protocol.
- * @sa http://redmine.named-data.net/projects/nfd/wiki/FibMgmt
+ * @sa https://redmine.named-data.net/projects/nfd/wiki/FibMgmt
  */
 class FibManager : public NfdManagerBase
 {
diff --git a/daemon/mgmt/general-config-section.cpp b/daemon/mgmt/general-config-section.cpp
index 2b573b3..6ed3af1 100644
--- a/daemon/mgmt/general-config-section.cpp
+++ b/daemon/mgmt/general-config-section.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,83 +24,58 @@
  */
 
 #include "general-config-section.hpp"
-
-#include "core/logger.hpp"
 #include "core/privilege-helper.hpp"
-#include "core/config-file.hpp"
 
 namespace nfd {
-
 namespace general {
 
-NFD_LOG_INIT("GeneralConfigSection");
-
 static void
-onConfig(const ConfigSection& configSection,
-         bool isDryRun,
-         const std::string& filename)
+onConfig(const ConfigSection& section, bool isDryRun, const std::string&)
 {
   // general
   // {
-  //    ; user "ndn-user"
-  //    ; group "ndn-user"
+  //   user "ndn-user"
+  //   group "ndn-user"
   // }
 
   std::string user;
   std::string group;
 
-  for (ConfigSection::const_iterator i = configSection.begin();
-       i != configSection.end();
-       ++i)
-    {
-      if (i->first == "user")
-        {
-          try
-            {
-              user = i->second.get_value<std::string>("user");
+  for (const auto& i : section) {
+    if (i.first == "user") {
+      try {
+        user = i.second.get_value<std::string>("user");
 
-              if (user.empty())
-                {
-                  BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"user\""
-                                                          " in \"general\" section"));
-                }
-            }
-          catch (const boost::property_tree::ptree_error& error)
-            {
-              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"user\""
-                                                      " in \"general\" section"));
-            }
+        if (user.empty()) {
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"user\" in \"general\" section"));
         }
-      else if (i->first == "group")
-        {
-          try
-            {
-              group = i->second.get_value<std::string>("group");
-
-              if (group.empty())
-                {
-                  BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"group\""
-                                                          " in \"general\" section"));
-                }
-            }
-          catch (const boost::property_tree::ptree_error& error)
-            {
-              BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"group\""
-                                                      " in \"general\" section"));
-            }
-        }
+      }
+      catch (const boost::property_tree::ptree_error&) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"user\" in \"general\" section"));
+      }
     }
-  NFD_LOG_TRACE("using user \"" << user << "\" group \"" << group << "\"");
+    else if (i.first == "group") {
+      try {
+        group = i.second.get_value<std::string>("group");
+
+        if (group.empty()) {
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"group\" in \"general\" section"));
+        }
+      }
+      catch (const boost::property_tree::ptree_error&) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for \"group\" in \"general\" section"));
+      }
+    }
+  }
 
   PrivilegeHelper::initialize(user, group);
 }
 
 void
-setConfigFile(ConfigFile& configFile)
+setConfigFile(ConfigFile& config)
 {
-  configFile.addSectionHandler("general", &onConfig);
+  config.addSectionHandler("general", &onConfig);
 }
 
 } // namespace general
-
 } // namespace nfd
diff --git a/daemon/mgmt/general-config-section.hpp b/daemon/mgmt/general-config-section.hpp
index 6ce5473..a70bc48 100644
--- a/daemon/mgmt/general-config-section.hpp
+++ b/daemon/mgmt/general-config-section.hpp
@@ -1,11 +1,12 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014  Regents of the University of California,
- *                     Arizona Board of Regents,
- *                     Colorado State University,
- *                     University Pierre & Marie Curie, Sorbonne University,
- *                     Washington University in St. Louis,
- *                     Beijing Institute of Technology
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,22 +21,20 @@
  *
  * You should have received a copy of the GNU General Public License along with
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
 
 #ifndef NFD_MGMT_GENERAL_CONFIG_SECTION_HPP
 #define NFD_MGMT_GENERAL_CONFIG_SECTION_HPP
 
+#include "core/config-file.hpp"
+
 namespace nfd {
-
-class ConfigFile;
-
 namespace general {
 
 void
-setConfigFile(ConfigFile& configFile);
+setConfigFile(ConfigFile& config);
 
 } // namespace general
-
 } // namespace nfd
 
 #endif // NFD_MGMT_GENERAL_CONFIG_SECTION_HPP
diff --git a/daemon/mgmt/strategy-choice-manager.cpp b/daemon/mgmt/strategy-choice-manager.cpp
index 6cb5d57..8f7cef0 100644
--- a/daemon/mgmt/strategy-choice-manager.cpp
+++ b/daemon/mgmt/strategy-choice-manager.cpp
@@ -24,13 +24,15 @@
  */
 
 #include "strategy-choice-manager.hpp"
+
+#include "core/logger.hpp"
 #include "table/strategy-choice.hpp"
+
 #include <ndn-cxx/mgmt/nfd/strategy-choice.hpp>
-#include <boost/lexical_cast.hpp>
 
 namespace nfd {
 
-NFD_LOG_INIT("StrategyChoiceManager");
+NFD_LOG_INIT(StrategyChoiceManager);
 
 StrategyChoiceManager::StrategyChoiceManager(StrategyChoice& strategyChoice,
                                              Dispatcher& dispatcher,
diff --git a/daemon/nfd.cpp b/daemon/nfd.cpp
index 6d5a6c4..f96720f 100644
--- a/daemon/nfd.cpp
+++ b/daemon/nfd.cpp
@@ -27,7 +27,7 @@
 
 #include "core/config-file.hpp"
 #include "core/global-io.hpp"
-#include "core/logger-factory.hpp"
+#include "core/log-config-section.hpp"
 #include "core/privilege-helper.hpp"
 #include "face/face-system.hpp"
 #include "face/internal-face.hpp"
@@ -43,7 +43,7 @@
 
 namespace nfd {
 
-NFD_LOG_INIT("Nfd");
+NFD_LOG_INIT(Nfd);
 
 static const std::string INTERNAL_CONFIG = "internal://nfd.conf";
 
@@ -73,7 +73,7 @@
 void
 Nfd::initialize()
 {
-  initializeLogging();
+  configureLogging();
 
   m_forwarder = make_unique<Forwarder>();
 
@@ -98,10 +98,10 @@
 }
 
 void
-Nfd::initializeLogging()
+Nfd::configureLogging()
 {
   ConfigFile config(&ConfigFile::ignoreUnknownSection);
-  LoggerFactory::getInstance().setConfigFile(config);
+  log::setConfigFile(config);
 
   if (!m_configFile.empty()) {
     config.parse(m_configFile, true);
@@ -176,12 +176,9 @@
 void
 Nfd::reloadConfigFile()
 {
-  // Logging
-  initializeLogging();
+  configureLogging();
 
-  // Other stuff
   ConfigFile config(&ignoreRibAndLogSections);
-
   general::setConfigFile(config);
 
   TablesConfigSection tablesConfig(*m_forwarder);
diff --git a/daemon/nfd.hpp b/daemon/nfd.hpp
index f9f43c4..4aadc18 100644
--- a/daemon/nfd.hpp
+++ b/daemon/nfd.hpp
@@ -100,7 +100,7 @@
   Nfd(ndn::KeyChain& keyChain);
 
   void
-  initializeLogging();
+  configureLogging();
 
   void
   initializeManagement();
diff --git a/daemon/table/cs-policy.cpp b/daemon/table/cs-policy.cpp
index 4aab572..a982590 100644
--- a/daemon/table/cs-policy.cpp
+++ b/daemon/table/cs-policy.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -26,10 +26,11 @@
 #include "cs-policy.hpp"
 #include "cs.hpp"
 #include "core/logger.hpp"
+
 #include <boost/range/adaptor/map.hpp>
 #include <boost/range/algorithm/copy.hpp>
 
-NFD_LOG_INIT("CsPolicy");
+NFD_LOG_INIT(CsPolicy);
 
 namespace nfd {
 namespace cs {
diff --git a/daemon/table/cs.cpp b/daemon/table/cs.cpp
index c789567..00dc9ee 100644
--- a/daemon/table/cs.cpp
+++ b/daemon/table/cs.cpp
@@ -35,7 +35,7 @@
 
 NDN_CXX_ASSERT_FORWARD_ITERATOR(Cs::const_iterator);
 
-NFD_LOG_INIT("ContentStore");
+NFD_LOG_INIT(ContentStore);
 
 unique_ptr<Policy>
 makeDefaultPolicy()
diff --git a/daemon/table/dead-nonce-list.cpp b/daemon/table/dead-nonce-list.cpp
index 5df2482..d732a90 100644
--- a/daemon/table/dead-nonce-list.cpp
+++ b/daemon/table/dead-nonce-list.cpp
@@ -1,12 +1,12 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014,  Regents of the University of California,
- *                      Arizona Board of Regents,
- *                      Colorado State University,
- *                      University Pierre & Marie Curie, Sorbonne University,
- *                      Washington University in St. Louis,
- *                      Beijing Institute of Technology,
- *                      The University of Memphis
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -27,10 +27,10 @@
 #include "core/city-hash.hpp"
 #include "core/logger.hpp"
 
-NFD_LOG_INIT("DeadNonceList");
-
 namespace nfd {
 
+NFD_LOG_INIT(DeadNonceList);
+
 const time::nanoseconds DeadNonceList::DEFAULT_LIFETIME = time::seconds(6);
 const time::nanoseconds DeadNonceList::MIN_LIFETIME = time::milliseconds(1);
 const size_t DeadNonceList::INITIAL_CAPACITY = (1 << 7);
diff --git a/daemon/table/name-tree-hashtable.cpp b/daemon/table/name-tree-hashtable.cpp
index e6b3c33..2e25223 100644
--- a/daemon/table/name-tree-hashtable.cpp
+++ b/daemon/table/name-tree-hashtable.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,13 +24,13 @@
  */
 
 #include "name-tree-hashtable.hpp"
-#include "core/logger.hpp"
 #include "core/city-hash.hpp"
+#include "core/logger.hpp"
 
 namespace nfd {
 namespace name_tree {
 
-NFD_LOG_INIT("NameTreeHashtable");
+NFD_LOG_INIT(NameTreeHashtable);
 
 class Hash32
 {
diff --git a/daemon/table/name-tree-iterator.cpp b/daemon/table/name-tree-iterator.cpp
index 9752ac7..56c0360 100644
--- a/daemon/table/name-tree-iterator.cpp
+++ b/daemon/table/name-tree-iterator.cpp
@@ -36,7 +36,7 @@
 NDN_CXX_ASSERT_FORWARD_ITERATOR(Iterator);
 BOOST_CONCEPT_ASSERT((boost::ForwardRangeConcept<Range>));
 
-NFD_LOG_INIT("NameTreeIterator");
+NFD_LOG_INIT(NameTreeIterator);
 
 Iterator::Iterator()
   : m_entry(nullptr)
diff --git a/daemon/table/name-tree.cpp b/daemon/table/name-tree.cpp
index 02553cb..93bed3a 100644
--- a/daemon/table/name-tree.cpp
+++ b/daemon/table/name-tree.cpp
@@ -33,7 +33,7 @@
 namespace nfd {
 namespace name_tree {
 
-NFD_LOG_INIT("NameTree");
+NFD_LOG_INIT(NameTree);
 
 NameTree::NameTree(size_t nBuckets)
   : m_ht(HashtableOptions(nBuckets))
diff --git a/daemon/table/strategy-choice-entry.cpp b/daemon/table/strategy-choice-entry.cpp
index 8a73c5d..77302f7 100644
--- a/daemon/table/strategy-choice-entry.cpp
+++ b/daemon/table/strategy-choice-entry.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,7 +24,6 @@
  */
 
 #include "strategy-choice-entry.hpp"
-#include "core/logger.hpp"
 #include "fw/strategy.hpp"
 
 namespace nfd {
diff --git a/daemon/table/strategy-choice.cpp b/daemon/table/strategy-choice.cpp
index 8e026dc..233f367 100644
--- a/daemon/table/strategy-choice.cpp
+++ b/daemon/table/strategy-choice.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "strategy-choice.hpp"
+
 #include "measurements-entry.hpp"
 #include "pit-entry.hpp"
 #include "core/logger.hpp"
@@ -36,7 +37,7 @@
 
 NDN_CXX_ASSERT_FORWARD_ITERATOR(StrategyChoice::const_iterator);
 
-NFD_LOG_INIT("StrategyChoice");
+NFD_LOG_INIT(StrategyChoice);
 
 using fw::Strategy;
 
diff --git a/docs/doxygen.conf.in b/docs/doxygen.conf.in
index 2087935..902c297 100644
--- a/docs/doxygen.conf.in
+++ b/docs/doxygen.conf.in
@@ -2050,12 +2050,13 @@
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
 PREDEFINED             = DOXYGEN \
-                         NFD_LOG_INIT(x)= \
-                         NFD_LOG_INCLASS_DEFINE(a,b)= \
-                         NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(a,b,c)= \
-                         NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(a,b,c,d)= \
                          BOOST_CONCEPT_ASSERT(x)= \
                          BOOST_CONCEPT_REQUIRES(x)= \
+                         NFD_LOG_INIT(x)= \
+                         NFD_LOG_MEMBER_DECL()= \
+                         NFD_LOG_MEMBER_DECL_SPECIALIZED(x)= \
+                         NFD_LOG_MEMBER_INIT(x,y)= \
+                         NFD_LOG_MEMBER_INIT_SPECIALIZED(x,y)= \
                          VIRTUAL_WITH_TESTS= \
                          PUBLIC_WITH_TESTS_ELSE_PROTECTED=protected \
                          PUBLIC_WITH_TESTS_ELSE_PRIVATE=private \
diff --git a/nfd.conf.sample.in b/nfd.conf.sample.in
index c5bf79f..8efc2ab 100644
--- a/nfd.conf.sample.in
+++ b/nfd.conf.sample.in
@@ -33,7 +33,8 @@
   ; Run:
   ;   nfd --modules
   ;
-  ; Or look for NFD_LOG_INIT(<module name>) statements in .cpp files
+  ; Or look for NFD_LOG_INIT(<module name>) statements in source files.
+  ; Note that the "nfd." prefix can be omitted.
   ;
   ; Example module-level settings:
   ;
diff --git a/rib/auto-prefix-propagator.cpp b/rib/auto-prefix-propagator.cpp
index d3e9e86..13124d2 100644
--- a/rib/auto-prefix-propagator.cpp
+++ b/rib/auto-prefix-propagator.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -26,16 +26,16 @@
 #include "auto-prefix-propagator.hpp"
 #include "core/logger.hpp"
 #include "core/scheduler.hpp"
+
 #include <ndn-cxx/security/pib/identity.hpp>
 #include <ndn-cxx/security/pib/identity-container.hpp>
 #include <ndn-cxx/security/pib/pib.hpp>
 #include <ndn-cxx/security/signing-helpers.hpp>
-#include <vector>
 
 namespace nfd {
 namespace rib {
 
-NFD_LOG_INIT("AutoPrefixPropagator");
+NFD_LOG_INIT(AutoPrefixPropagator);
 
 using ndn::nfd::ControlParameters;
 using ndn::nfd::CommandOptions;
diff --git a/rib/fib-updater.cpp b/rib/fib-updater.cpp
index bce3a5d..76a33c7 100644
--- a/rib/fib-updater.cpp
+++ b/rib/fib-updater.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,7 +24,6 @@
  */
 
 #include "fib-updater.hpp"
-
 #include "core/logger.hpp"
 
 #include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
@@ -32,9 +31,9 @@
 namespace nfd {
 namespace rib {
 
-using ndn::nfd::ControlParameters;
+NFD_LOG_INIT(FibUpdater);
 
-NFD_LOG_INIT("FibUpdater");
+using ndn::nfd::ControlParameters;
 
 const unsigned int FibUpdater::MAX_NUM_TIMEOUTS = 10;
 const uint32_t FibUpdater::ERROR_FACE_NOT_FOUND = 410;
diff --git a/rib/propagated-entry.cpp b/rib/propagated-entry.cpp
index 8dff54a..dae3934 100644
--- a/rib/propagated-entry.cpp
+++ b/rib/propagated-entry.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -23,7 +23,6 @@
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "core/logger.hpp"
 #include "propagated-entry.hpp"
 
 namespace nfd {
diff --git a/rib/readvertise/nfd-rib-readvertise-destination.cpp b/rib/readvertise/nfd-rib-readvertise-destination.cpp
index 3d19004..530a9d4 100644
--- a/rib/readvertise/nfd-rib-readvertise-destination.cpp
+++ b/rib/readvertise/nfd-rib-readvertise-destination.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -34,7 +34,7 @@
 namespace nfd {
 namespace rib {
 
-NFD_LOG_INIT("NfdRibReadvertiseDestination");
+NFD_LOG_INIT(NfdRibReadvertiseDestination);
 
 using ndn::nfd::CommandOptions;
 using ndn::nfd::ControlParameters;
diff --git a/rib/readvertise/readvertise-destination.cpp b/rib/readvertise/readvertise-destination.cpp
index 3c577c7..a687a8a 100644
--- a/rib/readvertise/readvertise-destination.cpp
+++ b/rib/readvertise/readvertise-destination.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -29,7 +29,7 @@
 namespace nfd {
 namespace rib {
 
-NFD_LOG_INIT("ReadvertiseDestination");
+NFD_LOG_INIT(ReadvertiseDestination);
 
 void
 ReadvertiseDestination::setAvailability(bool isAvailable)
diff --git a/rib/readvertise/readvertise.cpp b/rib/readvertise/readvertise.cpp
index 344bc7e..53074f8 100644
--- a/rib/readvertise/readvertise.cpp
+++ b/rib/readvertise/readvertise.cpp
@@ -30,7 +30,7 @@
 namespace nfd {
 namespace rib {
 
-NFD_LOG_INIT("Readvertise");
+NFD_LOG_INIT(Readvertise);
 
 const time::milliseconds Readvertise::RETRY_DELAY_MIN = time::seconds(50);
 const time::milliseconds Readvertise::RETRY_DELAY_MAX = time::seconds(3600);
diff --git a/rib/rib-entry.cpp b/rib/rib-entry.cpp
index e26e6d6..7fd0ed7 100644
--- a/rib/rib-entry.cpp
+++ b/rib/rib-entry.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,16 +24,15 @@
  */
 
 #include "rib-entry.hpp"
-
 #include "core/logger.hpp"
 
 #include <ndn-cxx/mgmt/nfd/control-command.hpp>
 
-NFD_LOG_INIT("RibEntry");
-
 namespace nfd {
 namespace rib {
 
+NFD_LOG_INIT(RibEntry);
+
 RibEntry::RouteList::iterator
 RibEntry::findRoute(const Route& route)
 {
diff --git a/rib/rib-manager.cpp b/rib/rib-manager.cpp
index c955a0d..ecf20d9 100644
--- a/rib/rib-manager.cpp
+++ b/rib/rib-manager.cpp
@@ -42,7 +42,7 @@
 namespace nfd {
 namespace rib {
 
-NFD_LOG_INIT("RibManager");
+NFD_LOG_INIT(RibManager);
 
 const Name RibManager::LOCAL_HOST_TOP_PREFIX = "/localhost/nfd";
 const Name RibManager::LOCAL_HOP_TOP_PREFIX = "/localhop/nfd";
diff --git a/rib/rib.cpp b/rib/rib.cpp
index a2a27fb..d6b125b 100644
--- a/rib/rib.cpp
+++ b/rib/rib.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,15 +24,14 @@
  */
 
 #include "rib.hpp"
-
 #include "fib-updater.hpp"
 #include "core/logger.hpp"
 
-NFD_LOG_INIT("Rib");
-
 namespace nfd {
 namespace rib {
 
+NFD_LOG_INIT(Rib);
+
 bool
 operator<(const RibRouteRef& lhs, const RibRouteRef& rhs)
 {
@@ -52,9 +51,7 @@
 {
 }
 
-Rib::~Rib()
-{
-}
+Rib::~Rib() = default;
 
 void
 Rib::setFibUpdater(FibUpdater* updater)
diff --git a/rib/service.cpp b/rib/service.cpp
index 51ba11c..dce806f 100644
--- a/rib/service.cpp
+++ b/rib/service.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,10 +24,7 @@
  */
 
 #include "service.hpp"
-
 #include "rib-manager.hpp"
-#include "core/config-file.hpp"
-#include "core/logger-factory.hpp"
 #include "core/global-io.hpp"
 
 #include <boost/property_tree/info_parser.hpp>
@@ -52,32 +49,23 @@
 {
 }
 
-Service::~Service()
-{
-  // It is necessary to explicitly define the destructor, because some member variables
-  // (e.g., unique_ptr<RibManager>) are forward-declared, but implicitly declared destructor
-  // requires complete types for all members when instantiated.
-}
+// It is necessary to explicitly define the destructor, because some member variables
+// (e.g., unique_ptr<RibManager>) are forward-declared, but implicitly declared destructor
+// requires complete types for all members when instantiated.
+Service::~Service() = default;
 
 void
 Service::initialize()
 {
-  m_face.reset(new ndn::Face(getLocalNfdTransport(), getGlobalIoService(), m_keyChain));
-  m_dispatcher.reset(new ndn::mgmt::Dispatcher(*m_face, m_keyChain));
-
-  initializeLogging();
-
-  m_ribManager.reset(new RibManager(*m_dispatcher, *m_face, m_keyChain));
+  m_face = make_unique<ndn::Face>(getLocalNfdTransport(), getGlobalIoService(), m_keyChain);
+  m_dispatcher = make_unique<ndn::mgmt::Dispatcher>(*m_face, m_keyChain);
+  m_ribManager = make_unique<RibManager>(*m_dispatcher, *m_face, m_keyChain);
 
   ConfigFile config([] (const std::string& filename, const std::string& sectionName,
                         const ConfigSection& section, bool isDryRun) {
-      // Ignore "log" and sections belonging to NFD,
-      // but raise an error if we're missing a handler for a "rib" section.
-      if (sectionName != "rib" || sectionName == "log") {
-        // do nothing
-      }
-      else {
-        // missing "rib" section handler
+      // Ignore sections belonging to NFD, but raise an error
+      // if we're missing a handler for a "rib" section.
+      if (sectionName == "rib") {
         ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun);
       }
     });
@@ -97,22 +85,6 @@
   m_ribManager->enableLocalFields();
 }
 
-void
-Service::initializeLogging()
-{
-  ConfigFile config(&ConfigFile::ignoreUnknownSection);
-  LoggerFactory::getInstance().setConfigFile(config);
-
-  if (!m_configFile.empty()) {
-    config.parse(m_configFile, true);
-    config.parse(m_configFile, false);
-  }
-  else {
-    config.parse(m_configSection, true, INTERNAL_CONFIG);
-    config.parse(m_configSection, false, INTERNAL_CONFIG);
-  }
-}
-
 shared_ptr<ndn::Transport>
 Service::getLocalNfdTransport()
 {
@@ -123,13 +95,14 @@
     // If error is thrown at this point, it is development error
     boost::property_tree::read_info(m_configFile, config);
   }
-  else
+  else {
     config = m_configSection;
+  }
 
   if (config.get_child_optional("face_system.unix")) {
     // unix socket enabled
 
-    auto&& socketPath = config.get<std::string>("face_system.unix.path", "/var/run/nfd.sock");
+    auto socketPath = config.get<std::string>("face_system.unix.path", "/var/run/nfd.sock");
     // default socketPath should be the same as in FaceManager::processSectionUnix
 
     return make_shared<ndn::UnixTransport>(socketPath);
@@ -138,7 +111,7 @@
            config.get<std::string>("face_system.tcp.listen", "yes") == "yes") {
     // tcp is enabled
 
-    auto&& port = config.get<std::string>("face_system.tcp.port", "6363");
+    auto port = config.get<std::string>("face_system.tcp.port", "6363");
     // default port should be the same as in FaceManager::processSectionTcp
 
     return make_shared<ndn::TcpTransport>("localhost", port);
diff --git a/rib/service.hpp b/rib/service.hpp
index ae7b23f..35223dc 100644
--- a/rib/service.hpp
+++ b/rib/service.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -26,13 +26,12 @@
 #ifndef NFD_RIB_SERVICE_HPP
 #define NFD_RIB_SERVICE_HPP
 
-#include "core/common.hpp"
 #include "core/config-file.hpp"
 
 #include <ndn-cxx/face.hpp>
+#include <ndn-cxx/mgmt/dispatcher.hpp>
 #include <ndn-cxx/security/key-chain.hpp>
 #include <ndn-cxx/transport/transport.hpp>
-#include <ndn-cxx/mgmt/dispatcher.hpp>
 
 namespace nfd {
 namespace rib {
@@ -86,9 +85,6 @@
   initialize();
 
 private:
-  void
-  initializeLogging();
-
   /**
    * \brief Look into the config file and construct appropriate transport to communicate with NFD
    * If NFD-RIB instance was initialized with config file, INFO format is assumed
diff --git a/tests/core/logger.t.cpp b/tests/core/logger.t.cpp
deleted file mode 100644
index b2fb4c7..0000000
--- a/tests/core/logger.t.cpp
+++ /dev/null
@@ -1,992 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2017,  Regents of the University of California,
- *                           Arizona Board of Regents,
- *                           Colorado State University,
- *                           University Pierre & Marie Curie, Sorbonne University,
- *                           Washington University in St. Louis,
- *                           Beijing Institute of Technology,
- *                           The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "core/logger.hpp"
-
-#include "tests/test-common.hpp"
-
-#include <boost/algorithm/string/classification.hpp>
-#include <boost/algorithm/string/split.hpp>
-
-#include <iostream>
-
-namespace nfd {
-namespace tests {
-
-BOOST_FIXTURE_TEST_SUITE(TestLogger, BaseFixture)
-
-class LoggerFixture : protected BaseFixture
-{
-public:
-  LoggerFixture()
-    : m_savedBuf(std::clog.rdbuf())
-    , m_savedLevel(LoggerFactory::getInstance().getDefaultLevel())
-  {
-    std::clog.rdbuf(m_buffer.rdbuf());
-  }
-
-  ~LoggerFixture()
-  {
-    std::clog.rdbuf(m_savedBuf);
-    LoggerFactory::getInstance().setDefaultLevel(m_savedLevel);
-  }
-
-  std::stringstream m_buffer;
-  std::streambuf* m_savedBuf;
-  LogLevel m_savedLevel;
-
-};
-
-BOOST_FIXTURE_TEST_CASE(Basic, LoggerFixture)
-{
-  using namespace ndn::time;
-  using std::string;
-
-  const ndn::time::microseconds::rep ONE_SECOND = 1000000;
-
-  NFD_LOG_INIT("BasicTests");
-  g_logger.setLogLevel(LOG_ALL);
-
-  const string EXPECTED[] =
-    {
-      "TRACE:",   "[BasicTests]", "trace-message-JHGFDSR^1\n",
-      "DEBUG:",   "[BasicTests]", "debug-message-IGg2474fdksd-fo-151617\n",
-      "WARNING:", "[BasicTests]", "warning-message-XXXhdhd111x\n",
-      "INFO:",    "[BasicTests]", "info-message-Jjxjshj13\n",
-      "ERROR:",   "[BasicTests]", "error-message-!#$&^%$#@\n",
-      "FATAL:",   "[BasicTests]", "fatal-message-JJSjaamcng\n",
-    };
-
-  const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(string);
-
-  microseconds::rep before =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  NFD_LOG_TRACE("trace-message-JHGFDSR^1");
-  NFD_LOG_DEBUG("debug-message-IGg2474fdksd-fo-" << 15 << 16 << 17);
-  NFD_LOG_WARN("warning-message-XXXhdhd11" << 1 <<"x");
-  NFD_LOG_INFO("info-message-Jjxjshj13");
-  NFD_LOG_ERROR("error-message-!#$&^%$#@");
-  NFD_LOG_FATAL("fatal-message-JJSjaamcng");
-
-  microseconds::rep after =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  LoggerFactory::getInstance().flushBackend();
-
-  const string buffer = m_buffer.str();
-
-  std::vector<string> components;
-  boost::split(components, buffer, boost::is_any_of(" ,\n"));
-
-  // std::cout << components.size() << " for " << moduleName  << std::endl;
-  // for (size_t i = 0; i < components.size(); ++i)
-  //   {
-  //     std::cout << "-> " << components[i] << std::endl;
-  //   }
-
-  // expected + number of timestamps (one per log statement) + trailing newline of last statement
-  BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 6 + 1);
-
-  std::vector<std::string>::const_iterator componentIter = components.begin();
-  for (size_t i = 0; i < N_EXPECTED; ++i)
-    {
-      // timestamp LOG_LEVEL: [ModuleName] message\n
-
-      const string& timestamp = *componentIter;
-      // std::cout << "timestamp = " << timestamp << std::endl;
-      ++componentIter;
-
-      size_t timeDelimiterPosition = timestamp.find(".");
-
-      BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition);
-
-      string secondsString = timestamp.substr(0, timeDelimiterPosition);
-      string usecondsString = timestamp.substr(timeDelimiterPosition + 1);
-
-      microseconds::rep extractedTime =
-        ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) +
-        boost::lexical_cast<microseconds::rep>(usecondsString);
-
-      // std::cout << "before=" << before
-      //           << " extracted=" << extractedTime
-      //           << " after=" << after << std::endl;
-
-
-      BOOST_CHECK_LE(before, extractedTime);
-      BOOST_CHECK_LE(extractedTime, after);
-
-      // LOG_LEVEL:
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      // [ModuleName]
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      const string& message = *componentIter;
-
-      // std::cout << "message = " << message << std::endl;
-
-      // add back the newline that we split on
-      BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]);
-      ++componentIter;
-    }
-
-}
-
-
-BOOST_FIXTURE_TEST_CASE(ConfigureFactory, LoggerFixture)
-{
-  using namespace ndn::time;
-  using std::string;
-
-  const ndn::time::microseconds::rep ONE_SECOND = 1000000;
-
-  NFD_LOG_INIT("ConfigureFactoryTests");
-
-  const string LOG_CONFIG =
-    "log\n"
-    "{\n"
-    "  default_level INFO\n"
-    "}\n";
-
-  LoggerFactory::getInstance().setDefaultLevel(LOG_ALL);
-
-  ConfigFile config;
-  LoggerFactory::getInstance().setConfigFile(config);
-
-  config.parse(LOG_CONFIG, false, "LOG_CONFIG");
-
-  BOOST_REQUIRE_EQUAL(LoggerFactory::getInstance().getDefaultLevel(), LOG_INFO);
-
-  const std::string EXPECTED[] =
-    {
-      "WARNING:", "[ConfigureFactoryTests]", "warning-message-XXXhdhd111x\n",
-      "INFO:",    "[ConfigureFactoryTests]", "info-message-Jjxjshj13\n",
-      "ERROR:",   "[ConfigureFactoryTests]", "error-message-!#$&^%$#@\n",
-      "FATAL:",   "[ConfigureFactoryTests]", "fatal-message-JJSjaamcng\n",
-    };
-
-  const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(std::string);
-
-  microseconds::rep before =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  NFD_LOG_TRACE("trace-message-JHGFDSR^1");
-  NFD_LOG_DEBUG("debug-message-IGg2474fdksd-fo-" << 15 << 16 << 17);
-  NFD_LOG_WARN("warning-message-XXXhdhd11" << 1 <<"x");
-  NFD_LOG_INFO("info-message-Jjxjshj13");
-  NFD_LOG_ERROR("error-message-!#$&^%$#@");
-  NFD_LOG_FATAL("fatal-message-JJSjaamcng");
-
-  microseconds::rep after =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  LoggerFactory::getInstance().flushBackend();
-
-  const string buffer = m_buffer.str();
-
-  std::vector<string> components;
-  boost::split(components, buffer, boost::is_any_of(" ,\n"));
-
-  // std::cout << components.size() << " for " << moduleName  << std::endl;
-  // for (size_t i = 0; i < components.size(); ++i)
-  //   {
-  //     std::cout << "-> " << components[i] << std::endl;
-  //   }
-
-  // expected + number of timestamps (one per log statement) + trailing newline of last statement
-  BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 4 + 1);
-
-  std::vector<std::string>::const_iterator componentIter = components.begin();
-  for (size_t i = 0; i < N_EXPECTED; ++i)
-    {
-      // timestamp LOG_LEVEL: [ModuleName] message\n
-
-      const string& timestamp = *componentIter;
-      // std::cout << "timestamp = " << timestamp << std::endl;
-      ++componentIter;
-
-      size_t timeDelimiterPosition = timestamp.find(".");
-
-      BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition);
-
-      string secondsString = timestamp.substr(0, timeDelimiterPosition);
-      string usecondsString = timestamp.substr(timeDelimiterPosition + 1);
-
-      microseconds::rep extractedTime =
-        ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) +
-        boost::lexical_cast<microseconds::rep>(usecondsString);
-
-      // std::cout << "before=" << before
-      //           << " extracted=" << extractedTime
-      //           << " after=" << after << std::endl;
-
-      BOOST_CHECK_LE(before, extractedTime);
-      BOOST_CHECK_LE(extractedTime, after);
-
-      // LOG_LEVEL:
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      // [ModuleName]
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      const string& message = *componentIter;
-
-      // std::cout << "message = " << message << std::endl;
-
-      // add back the newline that we split on
-      BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]);
-      ++componentIter;
-    }
-}
-
-BOOST_FIXTURE_TEST_CASE(TestNumberLevel, LoggerFixture)
-{
-  const std::string LOG_CONFIG =
-    "log\n"
-    "{\n"
-    "  default_level 2\n" // equivalent of WARN
-    "}\n";
-
-  LoggerFactory::getInstance().setDefaultLevel(LOG_ALL);
-
-  ConfigFile config;
-  LoggerFactory::getInstance().setConfigFile(config);
-
-  config.parse(LOG_CONFIG, false, "LOG_CONFIG");
-
-  BOOST_REQUIRE_EQUAL(LoggerFactory::getInstance().getDefaultLevel(), LOG_WARN);
-}
-
-static void
-testModuleBPrint()
-{
-  NFD_LOG_INIT("TestModuleB");
-  NFD_LOG_DEBUG("debug-message-IGg2474fdksd-fo-" << 15 << 16 << 17);
-}
-
-BOOST_FIXTURE_TEST_CASE(LimitModules, LoggerFixture)
-{
-  using namespace ndn::time;
-  using std::string;
-
-  NFD_LOG_INIT("TestModuleA");
-
-  const ndn::time::microseconds::rep ONE_SECOND = 1000000;
-
-  const std::string EXPECTED[] =
-    {
-      "WARNING:", "[TestModuleA]", "warning-message-XXXhdhd111x\n",
-    };
-
-  const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(std::string);
-
-  const std::string LOG_CONFIG =
-    "log\n"
-    "{\n"
-    "  default_level WARN\n"
-    "}\n";
-
-  ConfigFile config;
-  LoggerFactory::getInstance().setConfigFile(config);
-
-  config.parse(LOG_CONFIG, false, "LOG_CONFIG");
-
-  microseconds::rep before =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  // this should print
-  NFD_LOG_WARN("warning-message-XXXhdhd11" << 1 << "x");
-
-  // this should not because it's level is < WARN
-  testModuleBPrint();
-
-  microseconds::rep after =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  LoggerFactory::getInstance().flushBackend();
-
-  const string buffer = m_buffer.str();
-
-  std::vector<string> components;
-  boost::split(components, buffer, boost::is_any_of(" ,\n"));
-
-  // expected + number of timestamps (one per log statement) + trailing newline of last statement
-  BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 1 + 1);
-
-  std::vector<std::string>::const_iterator componentIter = components.begin();
-  for (size_t i = 0; i < N_EXPECTED; ++i)
-    {
-      // timestamp LOG_LEVEL: [ModuleName] message\n
-
-      const string& timestamp = *componentIter;
-      // std::cout << "timestamp = " << timestamp << std::endl;
-      ++componentIter;
-
-      size_t timeDelimiterPosition = timestamp.find(".");
-
-      BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition);
-
-      string secondsString = timestamp.substr(0, timeDelimiterPosition);
-      string usecondsString = timestamp.substr(timeDelimiterPosition + 1);
-
-      microseconds::rep extractedTime =
-        ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) +
-        boost::lexical_cast<microseconds::rep>(usecondsString);
-
-      // std::cout << "before=" << before
-      //           << " extracted=" << extractedTime
-      //           << " after=" << after << std::endl;
-
-      BOOST_CHECK_LE(before, extractedTime);
-      BOOST_CHECK_LE(extractedTime, after);
-
-      // LOG_LEVEL:
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      // [ModuleName]
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      const string& message = *componentIter;
-
-      // std::cout << "message = " << message << std::endl;
-
-      // add back the newline that we split on
-      BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]);
-      ++componentIter;
-    }
-}
-
-BOOST_FIXTURE_TEST_CASE(ExplicitlySetModule, LoggerFixture)
-{
-  using namespace ndn::time;
-  using std::string;
-
-  NFD_LOG_INIT("TestModuleA");
-
-  const ndn::time::microseconds::rep ONE_SECOND = 1000000;
-
-  const std::string LOG_CONFIG =
-    "log\n"
-    "{\n"
-    "  default_level WARN\n"
-    "  TestModuleB DEBUG\n"
-    "}\n";
-
-  ConfigFile config;
-  LoggerFactory::getInstance().setConfigFile(config);
-
-  config.parse(LOG_CONFIG, false, "LOG_CONFIG");
-
-  microseconds::rep before =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
- // this should print
-  NFD_LOG_WARN("warning-message-XXXhdhd11" << 1 << "x");
-
-  // this too because its level is explicitly set to DEBUG
-  testModuleBPrint();
-
-  microseconds::rep after =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  const std::string EXPECTED[] =
-    {
-      "WARNING:", "[TestModuleA]", "warning-message-XXXhdhd111x\n",
-      "DEBUG:",   "[TestModuleB]", "debug-message-IGg2474fdksd-fo-151617\n",
-    };
-
-  const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(std::string);
-
-  LoggerFactory::getInstance().flushBackend();
-
-  const string buffer = m_buffer.str();
-
-  std::vector<string> components;
-  boost::split(components, buffer, boost::is_any_of(" ,\n"));
-
-  // for (size_t i = 0; i < components.size(); ++i)
-  //   {
-  //     std::cout << "-> " << components[i] << std::endl;
-  //   }
-
-  // expected + number of timestamps (one per log statement) + trailing newline of last statement
-  BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 2 + 1);
-
-  std::vector<std::string>::const_iterator componentIter = components.begin();
-  for (size_t i = 0; i < N_EXPECTED; ++i)
-    {
-      // timestamp LOG_LEVEL: [ModuleName] message\n
-
-      const string& timestamp = *componentIter;
-      // std::cout << "timestamp = " << timestamp << std::endl;
-      ++componentIter;
-
-      size_t timeDelimiterPosition = timestamp.find(".");
-
-      BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition);
-
-      string secondsString = timestamp.substr(0, timeDelimiterPosition);
-      string usecondsString = timestamp.substr(timeDelimiterPosition + 1);
-
-      microseconds::rep extractedTime =
-        ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) +
-        boost::lexical_cast<microseconds::rep>(usecondsString);
-
-      // std::cout << "before=" << before
-      //           << " extracted=" << extractedTime
-      //           << " after=" << after << std::endl;
-
-      BOOST_CHECK_LE(before, extractedTime);
-      BOOST_CHECK_LE(extractedTime, after);
-
-      // LOG_LEVEL:
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      // [ModuleName]
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      const string& message = *componentIter;
-
-      // std::cout << "message = " << message << std::endl;
-
-      // add back the newline that we split on
-      BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]);
-      ++componentIter;
-    }
-}
-
-BOOST_FIXTURE_TEST_CASE(UnknownModule, LoggerFixture)
-{
-  using namespace ndn::time;
-  using std::string;
-
-  const ndn::time::microseconds::rep ONE_SECOND = 1000000;
-
-  const std::string LOG_CONFIG =
-    "log\n"
-    "{\n"
-    "  default_level DEBUG\n"
-    "  TestMadeUpModule INFO\n"
-    "}\n";
-
-  ConfigFile config;
-  LoggerFactory::getInstance().setDefaultLevel(LOG_ALL);
-  LoggerFactory::getInstance().setConfigFile(config);
-
-  const std::string EXPECTED = "DEBUG: [LoggerFactory] "
-    "Failed to configure logging level for module \"TestMadeUpModule\" (module not found)\n";
-
-  microseconds::rep before =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  config.parse(LOG_CONFIG, false, "LOG_CONFIG");
-
-  microseconds::rep after =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  LoggerFactory::getInstance().flushBackend();
-
-  const string buffer = m_buffer.str();
-
-  const size_t firstSpace = buffer.find(" ");
-  BOOST_REQUIRE(firstSpace != string::npos);
-
-  const string timestamp = buffer.substr(0, firstSpace);
-  const string message = buffer.substr(firstSpace + 1);
-
-  size_t timeDelimiterPosition = timestamp.find(".");
-
-  BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition);
-
-  string secondsString = timestamp.substr(0, timeDelimiterPosition);
-  string usecondsString = timestamp.substr(timeDelimiterPosition + 1);
-
-  microseconds::rep extractedTime =
-    ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) +
-    boost::lexical_cast<microseconds::rep>(usecondsString);
-
-  // std::cout << "before=" << before
-  //           << " extracted=" << extractedTime
-  //           << " after=" << after << std::endl;
-
-  BOOST_CHECK_LE(before, extractedTime);
-  BOOST_CHECK_LE(extractedTime, after);
-
-  BOOST_CHECK_EQUAL(message, EXPECTED);
-}
-
-static bool
-checkError(const LoggerFactory::Error& error, const std::string& expected)
-{
-  return error.what() == expected;
-}
-
-BOOST_FIXTURE_TEST_CASE(UnknownLevelString, LoggerFixture)
-{
-  const std::string LOG_CONFIG =
-    "log\n"
-    "{\n"
-    "  default_level TestMadeUpLevel\n"
-    "}\n";
-
-  ConfigFile config;
-  LoggerFactory::getInstance().setConfigFile(config);
-
-  BOOST_REQUIRE_EXCEPTION(config.parse(LOG_CONFIG, false, "LOG_CONFIG"),
-                          LoggerFactory::Error,
-                          bind(&checkError,
-                               _1,
-                               "Unsupported logging level \"TestMadeUpLevel\""));
-}
-
-class InClassLogger : public LoggerFixture
-{
-public:
-
-  InClassLogger()
-  {
-    g_logger.setLogLevel(LOG_ALL);
-  }
-
-  void
-  writeLogs()
-  {
-    NFD_LOG_TRACE("trace-message-JHGFDSR^1");
-    NFD_LOG_DEBUG("debug-message-IGg2474fdksd-fo-" << 15 << 16 << 17);
-    NFD_LOG_WARN("warning-message-XXXhdhd11" << 1 <<"x");
-    NFD_LOG_INFO("info-message-Jjxjshj13");
-    NFD_LOG_ERROR("error-message-!#$&^%$#@");
-    NFD_LOG_FATAL("fatal-message-JJSjaamcng");
-  }
-
-private:
-  NFD_LOG_INCLASS_DECLARE();
-};
-
-NFD_LOG_INCLASS_DEFINE(InClassLogger, "InClassLogger");
-
-BOOST_FIXTURE_TEST_CASE(InClass, InClassLogger)
-{
-  using namespace ndn::time;
-  using std::string;
-
-  const ndn::time::microseconds::rep ONE_SECOND = 1000000;
-
-  microseconds::rep before =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  writeLogs();
-
-  microseconds::rep after =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  const string EXPECTED[] =
-    {
-      "TRACE:",   "[InClassLogger]", "trace-message-JHGFDSR^1\n",
-      "DEBUG:",   "[InClassLogger]", "debug-message-IGg2474fdksd-fo-151617\n",
-      "WARNING:", "[InClassLogger]", "warning-message-XXXhdhd111x\n",
-      "INFO:",    "[InClassLogger]", "info-message-Jjxjshj13\n",
-      "ERROR:",   "[InClassLogger]", "error-message-!#$&^%$#@\n",
-      "FATAL:",   "[InClassLogger]", "fatal-message-JJSjaamcng\n",
-    };
-
-  const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(string);
-
-  LoggerFactory::getInstance().flushBackend();
-
-  const string buffer = m_buffer.str();
-
-  std::vector<string> components;
-  boost::split(components, buffer, boost::is_any_of(" ,\n"));
-
-  // expected + number of timestamps (one per log statement) + trailing newline of last statement
-  BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 6 + 1);
-
-  std::vector<std::string>::const_iterator componentIter = components.begin();
-  for (size_t i = 0; i < N_EXPECTED; ++i)
-    {
-      // timestamp LOG_LEVEL: [ModuleName] message\n
-
-      const string& timestamp = *componentIter;
-      // std::cout << "timestamp = " << timestamp << std::endl;
-      ++componentIter;
-
-      size_t timeDelimiterPosition = timestamp.find(".");
-
-      BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition);
-
-      string secondsString = timestamp.substr(0, timeDelimiterPosition);
-      string usecondsString = timestamp.substr(timeDelimiterPosition + 1);
-
-      microseconds::rep extractedTime =
-        ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) +
-        boost::lexical_cast<microseconds::rep>(usecondsString);
-
-      // std::cout << "before=" << before
-      //           << " extracted=" << extractedTime
-      //           << " after=" << after << std::endl;
-
-      BOOST_CHECK_LE(before, extractedTime);
-      BOOST_CHECK_LE(extractedTime, after);
-
-      // LOG_LEVEL:
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      // [ModuleName]
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      const string& message = *componentIter;
-
-      // std::cout << "message = " << message << std::endl;
-
-      // add back the newline that we split on
-      BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]);
-      ++componentIter;
-    }
-}
-
-
-template<class T>
-class InClassTemplateLogger : public LoggerFixture
-{
-public:
-  InClassTemplateLogger()
-  {
-    g_logger.setLogLevel(LOG_ALL);
-  }
-
-  void
-  writeLogs()
-  {
-    NFD_LOG_TRACE("trace-message-JHGFDSR^1");
-    NFD_LOG_DEBUG("debug-message-IGg2474fdksd-fo-" << 15 << 16 << 17);
-    NFD_LOG_WARN("warning-message-XXXhdhd11" << 1 <<"x");
-    NFD_LOG_INFO("info-message-Jjxjshj13");
-    NFD_LOG_ERROR("error-message-!#$&^%$#@");
-    NFD_LOG_FATAL("fatal-message-JJSjaamcng");
-  }
-
-private:
-  NFD_LOG_INCLASS_DECLARE();
-};
-
-NFD_LOG_INCLASS_TEMPLATE_DEFINE(InClassTemplateLogger, "GenericInClassTemplateLogger");
-NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(InClassTemplateLogger, int, "IntInClassLogger");
-
-BOOST_FIXTURE_TEST_CASE(GenericInTemplatedClass, InClassTemplateLogger<bool>)
-{
-  using namespace ndn::time;
-  using std::string;
-
-  const ndn::time::microseconds::rep ONE_SECOND = 1000000;
-
-  microseconds::rep before =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  writeLogs();
-
-  microseconds::rep after =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  const string EXPECTED[] =
-    {
-      "TRACE:",   "[GenericInClassTemplateLogger]", "trace-message-JHGFDSR^1\n",
-      "DEBUG:",   "[GenericInClassTemplateLogger]", "debug-message-IGg2474fdksd-fo-151617\n",
-      "WARNING:", "[GenericInClassTemplateLogger]", "warning-message-XXXhdhd111x\n",
-      "INFO:",    "[GenericInClassTemplateLogger]", "info-message-Jjxjshj13\n",
-      "ERROR:",   "[GenericInClassTemplateLogger]", "error-message-!#$&^%$#@\n",
-      "FATAL:",   "[GenericInClassTemplateLogger]", "fatal-message-JJSjaamcng\n",
-    };
-
-  const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(string);
-
-  LoggerFactory::getInstance().flushBackend();
-
-  const string buffer = m_buffer.str();
-
-  std::vector<string> components;
-  boost::split(components, buffer, boost::is_any_of(" ,\n"));
-
-  // expected + number of timestamps (one per log statement) + trailing newline of last statement
-  BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 6 + 1);
-
-  std::vector<std::string>::const_iterator componentIter = components.begin();
-  for (size_t i = 0; i < N_EXPECTED; ++i)
-    {
-      // timestamp LOG_LEVEL: [ModuleName] message\n
-
-      const string& timestamp = *componentIter;
-      // std::cout << "timestamp = " << timestamp << std::endl;
-      ++componentIter;
-
-      size_t timeDelimiterPosition = timestamp.find(".");
-
-      BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition);
-
-      string secondsString = timestamp.substr(0, timeDelimiterPosition);
-      string usecondsString = timestamp.substr(timeDelimiterPosition + 1);
-
-      microseconds::rep extractedTime =
-        ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) +
-        boost::lexical_cast<microseconds::rep>(usecondsString);
-
-      // std::cout << "before=" << before
-      //           << " extracted=" << extractedTime
-      //           << " after=" << after << std::endl;
-
-      BOOST_CHECK_LE(before, extractedTime);
-      BOOST_CHECK_LE(extractedTime, after);
-
-      // LOG_LEVEL:
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      // [ModuleName]
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      const string& message = *componentIter;
-
-      // std::cout << "message = " << message << std::endl;
-
-      // add back the newline that we split on
-      BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]);
-      ++componentIter;
-    }
-}
-
-
-BOOST_FIXTURE_TEST_CASE(SpecializedInTemplatedClass, InClassTemplateLogger<int>)
-{
-  using namespace ndn::time;
-  using std::string;
-
-  const ndn::time::microseconds::rep ONE_SECOND = 1000000;
-
-  microseconds::rep before =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  writeLogs();
-
-  microseconds::rep after =
-    duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
-
-  const string EXPECTED[] =
-    {
-      "TRACE:",   "[IntInClassLogger]", "trace-message-JHGFDSR^1\n",
-      "DEBUG:",   "[IntInClassLogger]", "debug-message-IGg2474fdksd-fo-151617\n",
-      "WARNING:", "[IntInClassLogger]", "warning-message-XXXhdhd111x\n",
-      "INFO:",    "[IntInClassLogger]", "info-message-Jjxjshj13\n",
-      "ERROR:",   "[IntInClassLogger]", "error-message-!#$&^%$#@\n",
-      "FATAL:",   "[IntInClassLogger]", "fatal-message-JJSjaamcng\n",
-    };
-
-  const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(string);
-
-  LoggerFactory::getInstance().flushBackend();
-
-  const string buffer = m_buffer.str();
-
-  std::vector<string> components;
-  boost::split(components, buffer, boost::is_any_of(" ,\n"));
-
-  // expected + number of timestamps (one per log statement) + trailing newline of last statement
-  BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 6 + 1);
-
-  std::vector<std::string>::const_iterator componentIter = components.begin();
-  for (size_t i = 0; i < N_EXPECTED; ++i)
-    {
-      // timestamp LOG_LEVEL: [ModuleName] message\n
-
-      const string& timestamp = *componentIter;
-      // std::cout << "timestamp = " << timestamp << std::endl;
-      ++componentIter;
-
-      size_t timeDelimiterPosition = timestamp.find(".");
-
-      BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition);
-
-      string secondsString = timestamp.substr(0, timeDelimiterPosition);
-      string usecondsString = timestamp.substr(timeDelimiterPosition + 1);
-
-      microseconds::rep extractedTime =
-        ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) +
-        boost::lexical_cast<microseconds::rep>(usecondsString);
-
-      // std::cout << "before=" << before << " extracted=" << extractedTime << " after=" << after << std::endl;
-
-      BOOST_CHECK_LE(before, extractedTime);
-      BOOST_CHECK_LE(extractedTime, after);
-
-      // LOG_LEVEL:
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      // [ModuleName]
-      BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]);
-      ++componentIter;
-      ++i;
-
-      const string& message = *componentIter;
-
-      // std::cout << "message = " << message << std::endl;
-
-      // add back the newline that we split on
-      BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]);
-      ++componentIter;
-    }
-}
-
-BOOST_FIXTURE_TEST_CASE(LoggerFactoryListModules, LoggerFixture)
-{
-  std::set<std::string> testCaseLoggers{"LoggerFactoryListModules1", "LoggerFactoryListModules2"};
-
-  for (const auto& name : testCaseLoggers) {
-    LoggerFactory::create(name);
-  }
-
-  auto&& modules = LoggerFactory::getInstance().getModules();
-  BOOST_CHECK_GE(modules.size(), 2);
-
-  for (const auto& name : modules) {
-    testCaseLoggers.erase(name);
-  }
-
-  BOOST_CHECK_EQUAL(testCaseLoggers.size(), 0);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace tests
-} // namespace nfd
-
-// Testing compilation of the logger outside ::nfd namespace
-
-namespace test_logger { // another root namespace
-
-void
-Test1()
-{
-  NFD_LOG_INIT("Test");
-
-  NFD_LOG_TRACE("Trace");
-  NFD_LOG_DEBUG("Debug");
-  NFD_LOG_INFO("Info");
-  NFD_LOG_WARN("Warn");
-  NFD_LOG_ERROR("Error");
-  NFD_LOG_FATAL("Fatal");
-}
-
-class Test2
-{
-  NFD_LOG_INCLASS_DECLARE();
-};
-
-NFD_LOG_INCLASS_DEFINE(Test2, "Test2");
-
-template<class T>
-class Test3
-{
-  NFD_LOG_INCLASS_DECLARE();
-};
-
-NFD_LOG_INCLASS_TEMPLATE_DEFINE(Test3, "Test3");
-
-NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(Test3, int, "Test3Int");
-
-template<class X, class Y>
-class Test4
-{
-  NFD_LOG_INCLASS_DECLARE();
-};
-
-NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(Test4, int, int, "Test4IntInt");
-
-namespace nfd { // nested nfd namespace, different from ::nfd
-
-void
-Test1()
-{
-  NFD_LOG_INIT("Test");
-
-  NFD_LOG_TRACE("Trace");
-  NFD_LOG_DEBUG("Debug");
-  NFD_LOG_INFO("Info");
-  NFD_LOG_WARN("Warn");
-  NFD_LOG_ERROR("Error");
-  NFD_LOG_FATAL("Fatal");
-}
-
-class Test2
-{
-  NFD_LOG_INCLASS_DECLARE();
-};
-
-NFD_LOG_INCLASS_DEFINE(Test2, "Test2");
-
-template<class T>
-class Test3
-{
-  NFD_LOG_INCLASS_DECLARE();
-};
-
-NFD_LOG_INCLASS_TEMPLATE_DEFINE(Test3, "Test3");
-
-NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(Test3, int, "Test3Int");
-
-template<class X, class Y>
-class Test4
-{
-  NFD_LOG_INCLASS_DECLARE();
-};
-
-NFD_LOG_INCLASS_2TEMPLATE_SPECIALIZATION_DEFINE(Test4, int, int, "Test4IntInt");
-
-} // namespace nfd
-} // namespace test_logger
diff --git a/tests/core/network-predicate.t.cpp b/tests/core/network-predicate.t.cpp
index d7ef008..a0a510e 100644
--- a/tests/core/network-predicate.t.cpp
+++ b/tests/core/network-predicate.t.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "core/network-predicate.hpp"
+#include "core/config-file.hpp"
 
 #include "tests/test-common.hpp"
 
diff --git a/tests/daemon/mgmt/general-config-section.t.cpp b/tests/daemon/mgmt/general-config-section.t.cpp
index 26e87ea..226a541 100644
--- a/tests/daemon/mgmt/general-config-section.t.cpp
+++ b/tests/daemon/mgmt/general-config-section.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,6 +24,7 @@
  */
 
 #include "mgmt/general-config-section.hpp"
+#include "core/config-file.hpp"
 #include "core/privilege-helper.hpp"
 
 #include "tests/test-common.hpp"
diff --git a/tests/global-configuration.cpp b/tests/global-configuration.cpp
index 7cb26b5..25d5061 100644
--- a/tests/global-configuration.cpp
+++ b/tests/global-configuration.cpp
@@ -24,7 +24,7 @@
  */
 
 #include "core/config-file.hpp"
-#include "core/logger-factory.hpp"
+#include "core/log-config-section.hpp"
 
 #include "boost-test.hpp"
 
@@ -47,7 +47,7 @@
     const std::string filename = "unit-tests.conf";
     if (boost::filesystem::exists(filename)) {
       ConfigFile config;
-      LoggerFactory::getInstance().setConfigFile(config);
+      log::setConfigFile(config);
       config.parse(filename, false);
     }
 
diff --git a/tests/limited-io.cpp b/tests/limited-io.cpp
index dfc1a09..66a0946 100644
--- a/tests/limited-io.cpp
+++ b/tests/limited-io.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -31,7 +31,7 @@
 namespace nfd {
 namespace tests {
 
-NFD_LOG_INIT("LimitedIo");
+NFD_LOG_INIT(tests.LimitedIo);
 
 const int LimitedIo::UNLIMITED_OPS = std::numeric_limits<int>::max();
 const time::nanoseconds LimitedIo::UNLIMITED_TIME = time::nanoseconds::min();
diff --git a/tests/test-common.hpp b/tests/test-common.hpp
index b365f9b..110a1e2 100644
--- a/tests/test-common.hpp
+++ b/tests/test-common.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2018,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -29,7 +29,6 @@
 #include "boost-test.hpp"
 
 #include "core/global-io.hpp"
-#include "core/logger.hpp"
 
 #include <ndn-cxx/util/time-unit-test-clock.hpp>
 
diff --git a/unit-tests.conf.sample b/unit-tests.conf.sample
index d75c19c..3ebb9f7 100644
--- a/unit-tests.conf.sample
+++ b/unit-tests.conf.sample
@@ -22,10 +22,11 @@
   ; Run:
   ;   nfd --modules
   ;
-  ; Or look for NFD_LOG_INIT(<module name>) statements in .cpp files
+  ; Or look for NFD_LOG_INIT(<module name>) statements in source files.
+  ; Note that the "nfd." prefix can be omitted.
   ;
   ; Example module-level settings:
   ;
   ; FibManager DEBUG
   ; Forwarder INFO
-}
\ No newline at end of file
+}
diff --git a/wscript b/wscript
index 8a2efd4..d9836ab 100644
--- a/wscript
+++ b/wscript
@@ -56,10 +56,6 @@
     nfdopt.add_option('--with-other-tests', action='store_true', default=False,
                       help='Build other tests')
 
-    nfdopt.add_option('--with-custom-logger', metavar='PATH',
-                      help='Path to custom-logger.hpp and custom-logger-factory.hpp '
-                           'implementing Logger and LoggerFactory interfaces')
-
 PRIVILEGE_CHECK_CODE = '''
 #include <unistd.h>
 #include <grp.h>
@@ -147,11 +143,6 @@
                        fragment='''#include <pcap/pcap.h>
                                    int main() { pcap_t* p; pcap_set_immediate_mode(p, 1); }''')
 
-    if conf.options.with_custom_logger:
-        conf.define('HAVE_CUSTOM_LOGGER', 1)
-        conf.env.HAVE_CUSTOM_LOGGER = True
-        conf.env.INCLUDES_CUSTOM_LOGGER = [conf.options.with_custom_logger]
-
     conf.check_compiler_flags()
 
     # Loading "late" to prevent tests from being compiled with profiling flags
@@ -181,20 +172,15 @@
         VERSION_MINOR=VERSION_SPLIT[1],
         VERSION_PATCH=VERSION_SPLIT[2])
 
-    core = bld.objects(
+    bld.objects(
         target='core-objects',
         features='pch',
-        source=bld.path.ant_glob('core/**/*.cpp', excl=['core/logger*.cpp']),
+        source=bld.path.ant_glob('core/**/*.cpp'),
         use='version.hpp NDN_CXX BOOST LIBRT',
         includes='.',
         export_includes='.',
         headers='core/common.hpp')
 
-    if bld.env.HAVE_CUSTOM_LOGGER:
-        core.use += ' CUSTOM_LOGGER'
-    else:
-        core.source += bld.path.ant_glob('core/logger*.cpp')
-
     nfd_objects = bld.objects(
         target='daemon-objects',
         source=bld.path.ant_glob('daemon/**/*.cpp',