util: Make use of attributes in logging facilities

Refs: #4969
Change-Id: Ib7e495629107d9ebe2105a7fe1f99d89ad92e244
diff --git a/ndn-cxx/util/logger.cpp b/ndn-cxx/util/logger.cpp
index 5f6c2de..15203ec 100644
--- a/ndn-cxx/util/logger.cpp
+++ b/ndn-cxx/util/logger.cpp
@@ -21,12 +21,8 @@
 
 #include "ndn-cxx/util/logger.hpp"
 #include "ndn-cxx/util/logging.hpp"
-#include "ndn-cxx/util/time.hpp"
 
-#include <cinttypes> // for PRIdLEAST64
-#include <cstdlib>   // for std::abs()
-#include <cstring>   // for std::strspn()
-#include <stdio.h>   // for snprintf()
+#include <cstring> // for std::strspn()
 
 namespace ndn {
 namespace util {
@@ -107,6 +103,7 @@
     NDN_THROW(std::invalid_argument("Logger name '" + m_moduleName + "' is invalid"));
   }
   this->setLevel(LogLevel::NONE);
+  this->add_attribute(log::module.get_name(), boost::log::attributes::constant<std::string>(m_moduleName));
   Logging::get().addLoggerImpl(*this);
 }
 
@@ -120,32 +117,5 @@
   Logging::get().registerLoggerNameImpl(std::move(moduleName));
 }
 
-namespace detail {
-
-std::ostream&
-operator<<(std::ostream& os, 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 detail
 } // namespace util
 } // namespace ndn
diff --git a/ndn-cxx/util/logger.hpp b/ndn-cxx/util/logger.hpp
index f785c7b..30b8779 100644
--- a/ndn-cxx/util/logger.hpp
+++ b/ndn-cxx/util/logger.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -29,7 +29,9 @@
 #else
 
 #include <boost/log/common.hpp>
-#include <boost/log/sources/logger.hpp>
+#include <boost/log/expressions/keyword.hpp>
+#include <boost/log/sources/severity_logger.hpp>
+
 #include <atomic>
 
 namespace ndn {
@@ -60,12 +62,19 @@
 LogLevel
 parseLogLevel(const std::string& s);
 
+namespace log {
+
+BOOST_LOG_ATTRIBUTE_KEYWORD(module, "Module", std::string)
+BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", LogLevel)
+
+} // namespace log
+
 /** \brief Represents a log module in the logging facility.
  *
  *  \note Normally, loggers should be defined using #NDN_LOG_INIT, #NDN_LOG_MEMBER_INIT,
  *        or #NDN_LOG_MEMBER_INIT_SPECIALIZED.
  */
-class Logger : public boost::log::sources::logger_mt
+class Logger : public boost::log::sources::severity_logger_mt<LogLevel>
 {
 public:
   explicit
@@ -99,21 +108,6 @@
 
 namespace detail {
 
-/** \brief A tag type used to output a timestamp to a stream.
- *  \code
- *  std::clog << LoggerTimestamp();
- *  \endcode
- */
-struct LoggerTimestamp
-{
-};
-
-/** \brief Write a timestamp to \p os.
- *  \note This function is thread-safe.
- */
-std::ostream&
-operator<<(std::ostream& os, LoggerTimestamp);
-
 /** \cond */
 template<class T>
 struct ExtractArgument;
@@ -235,51 +229,51 @@
 /** \cond */
 #if BOOST_VERSION == 105900
 // workaround Boost bug 11549
-#define NDN_BOOST_LOG(x) BOOST_LOG(x) << ""
+#define NDN_BOOST_LOG(x, sev) BOOST_LOG_SEV(x, sev) << ""
 #else
-#define NDN_BOOST_LOG(x) BOOST_LOG(x)
+#define NDN_BOOST_LOG(x, sev) BOOST_LOG_SEV(x, sev)
 #endif
 
 // implementation detail
-#define NDN_LOG_INTERNAL(lvl, lvlstr, expression) \
+#define NDN_LOG_INTERNAL(lvl, expression) \
   do { \
     if (ndn_cxx_getLogger().isLevelEnabled(::ndn::util::LogLevel::lvl)) { \
-      NDN_BOOST_LOG(ndn_cxx_getLogger()) << ::ndn::util::detail::LoggerTimestamp{} \
-        << " " BOOST_STRINGIZE(lvlstr) ": [" << ndn_cxx_getLogger().getModuleName() << "] " \
+      NDN_BOOST_LOG(ndn_cxx_getLogger(), ::ndn::util::LogLevel::lvl)  \
         << expression; \
     } \
   } while (false)
+
 /** \endcond */
 
 /** \brief Log at TRACE level.
  *  \pre A log module must be declared in the same translation unit, class, struct, or namespace.
  */
-#define NDN_LOG_TRACE(expression) NDN_LOG_INTERNAL(TRACE, TRACE, expression)
+#define NDN_LOG_TRACE(expression) NDN_LOG_INTERNAL(TRACE, expression)
 
 /** \brief Log at DEBUG level.
  *  \pre A log module must be declared in the same translation unit, class, struct, or namespace.
  */
-#define NDN_LOG_DEBUG(expression) NDN_LOG_INTERNAL(DEBUG, DEBUG, expression)
+#define NDN_LOG_DEBUG(expression) NDN_LOG_INTERNAL(DEBUG, expression)
 
 /** \brief Log at INFO level.
  *  \pre A log module must be declared in the same translation unit, class, struct, or namespace.
  */
-#define NDN_LOG_INFO(expression) NDN_LOG_INTERNAL(INFO, INFO, expression)
+#define NDN_LOG_INFO(expression) NDN_LOG_INTERNAL(INFO, expression)
 
 /** \brief Log at WARN level.
  *  \pre A log module must be declared in the same translation unit, class, struct, or namespace.
  */
-#define NDN_LOG_WARN(expression) NDN_LOG_INTERNAL(WARN, WARNING, expression)
+#define NDN_LOG_WARN(expression) NDN_LOG_INTERNAL(WARN, expression)
 
 /** \brief Log at ERROR level.
  *  \pre A log module must be declared in the same translation unit, class, struct, or namespace.
  */
-#define NDN_LOG_ERROR(expression) NDN_LOG_INTERNAL(ERROR, ERROR, expression)
+#define NDN_LOG_ERROR(expression) NDN_LOG_INTERNAL(ERROR, expression)
 
 /** \brief Log at FATAL level.
  *  \pre A log module must be declared in the same translation unit, class, struct, or namespace.
  */
-#define NDN_LOG_FATAL(expression) NDN_LOG_INTERNAL(FATAL, FATAL, expression)
+#define NDN_LOG_FATAL(expression) NDN_LOG_INTERNAL(FATAL, expression)
 
 } // namespace util
 } // namespace ndn
diff --git a/ndn-cxx/util/logging.cpp b/ndn-cxx/util/logging.cpp
index 5f19548..45f4ba7 100644
--- a/ndn-cxx/util/logging.cpp
+++ b/ndn-cxx/util/logging.cpp
@@ -21,15 +21,22 @@
 
 #include "ndn-cxx/util/logging.hpp"
 #include "ndn-cxx/util/logger.hpp"
+#include "ndn-cxx/util/time.hpp"
 
+#include <boost/log/attributes/function.hpp>
 #include <boost/log/expressions.hpp>
+#include <boost/log/expressions/attr.hpp>
+#include <boost/log/expressions/formatters/date_time.hpp>
+#include <boost/log/support/date_time.hpp>
 #include <boost/range/adaptor/map.hpp>
 #include <boost/range/algorithm/copy.hpp>
 #include <boost/range/iterator_range.hpp>
 
-#include <cstdlib>
+#include <cinttypes> // for PRIdLEAST64
+#include <cstdlib>   // for std::abs()
 #include <iostream>
 #include <sstream>
+#include <stdio.h>   // for snprintf()
 
 // suppress warning caused by <boost/log/sinks/text_ostream_backend.hpp>
 #ifdef __clang__
@@ -38,6 +45,37 @@
 
 namespace ndn {
 namespace util {
+namespace log {
+
+static std::string
+makeTimestamp()
+{
+  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'
+  std::string buffer(10 + 1 + 6 + 1, '\0'); // note 1 extra byte still needed for snprintf
+  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.front(), buffer.size(), "%" PRIdLEAST64 ".%06" PRIdLEAST64,
+             usecs / usecsPerSec, usecs % usecsPerSec);
+
+  // need to remove extra 1 byte ('\0')
+  buffer.pop_back();
+  return buffer;
+}
+
+BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp, "Timestamp", std::string)
+
+} // namespace log
 
 static const LogLevel INITIAL_DEFAULT_LEVEL = LogLevel::NONE;
 
@@ -58,6 +96,8 @@
   if (environ != nullptr) {
     this->setLevelImpl(environ);
   }
+
+  boost::log::core::get()->add_global_attribute("Timestamp", boost::log::attributes::make_function(&log::makeTimestamp));
 }
 
 void
@@ -222,8 +262,13 @@
     m_sink.reset();
   }
 
+  namespace expr = boost::log::expressions;
   m_sink = boost::make_shared<Sink>(backend);
-  m_sink->set_formatter(boost::log::expressions::stream << boost::log::expressions::message);
+  m_sink->set_formatter(expr::stream
+                        << expr::attr<std::string>(log::timestamp.get_name())
+                        << " " << std::setw(5) << expr::attr<LogLevel>(log::severity.get_name()) << ": "
+                        << "[" << expr::attr<std::string>(log::module.get_name()) << "] "
+                        << expr::smessage);
   boost::log::core::get()->add_sink(m_sink);
 }
 
diff --git a/tests/unit/util/logging.t.cpp b/tests/unit/util/logging.t.cpp
index fd867d2..5be163a 100644
--- a/tests/unit/util/logging.t.cpp
+++ b/tests/unit/util/logging.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -205,7 +205,7 @@
 
   Logging::flush();
   BOOST_CHECK(os.is_equal(
-    LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module1] warn1\n" +
     LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
     LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
     ));
@@ -218,8 +218,8 @@
 
   Logging::flush();
   BOOST_CHECK(os.is_equal(
-    LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
-    LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
+    LOG_SYSTIME_STR + "  INFO: [Module1] info1\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module1] warn1\n" +
     LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
     LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
     ));
@@ -233,8 +233,8 @@
   Logging::flush();
   BOOST_CHECK(os.is_equal(
     LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
-    LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
-    LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
+    LOG_SYSTIME_STR + "  INFO: [Module1] info1\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module1] warn1\n" +
     LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
     LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
     ));
@@ -249,8 +249,8 @@
   BOOST_CHECK(os.is_equal(
     LOG_SYSTIME_STR + " TRACE: [Module1] trace1\n" +
     LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
-    LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
-    LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
+    LOG_SYSTIME_STR + "  INFO: [Module1] info1\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module1] warn1\n" +
     LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
     LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
     ));
@@ -265,8 +265,8 @@
   BOOST_CHECK(os.is_equal(
     LOG_SYSTIME_STR + " TRACE: [Module1] trace1\n" +
     LOG_SYSTIME_STR + " DEBUG: [Module1] debug1\n" +
-    LOG_SYSTIME_STR + " INFO: [Module1] info1\n" +
-    LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
+    LOG_SYSTIME_STR + "  INFO: [Module1] info1\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module1] warn1\n" +
     LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
     LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n"
     ));
@@ -293,8 +293,8 @@
 
   Logging::flush();
   BOOST_CHECK(os.is_equal(
-    LOG_SYSTIME_STR + " INFO: [ndn.util.tests.ns1] hello world from ns1\n" +
-    LOG_SYSTIME_STR + " INFO: [ndn.util.tests.ns2] hi there from ns2\n"
+    LOG_SYSTIME_STR + "  INFO: [ndn.util.tests.ns1] hello world from ns1\n" +
+    LOG_SYSTIME_STR + "  INFO: [ndn.util.tests.ns2] hi there from ns2\n"
     ));
 }
 
@@ -314,8 +314,8 @@
 
   Logging::flush();
   BOOST_CHECK(os.is_equal(
-    LOG_SYSTIME_STR + " INFO: [ndn.util.tests.ClassWithLogger] static member function\n" +
-    LOG_SYSTIME_STR + " INFO: [ndn.util.tests.ClassWithLogger] const member function\n"
+    LOG_SYSTIME_STR + "  INFO: [ndn.util.tests.ClassWithLogger] static member function\n" +
+    LOG_SYSTIME_STR + "  INFO: [ndn.util.tests.ClassWithLogger] const member function\n"
     ));
 
   ClassTemplateWithLogger<int, double>::logFromStaticMemberFunction();
@@ -325,8 +325,8 @@
 
   Logging::flush();
   BOOST_CHECK(os.is_equal(
-    LOG_SYSTIME_STR + " INFO: [ndn.util.tests.Specialized1] class template static member function\n" +
-    LOG_SYSTIME_STR + " INFO: [ndn.util.tests.Specialized1] class template non-static member function\n"
+    LOG_SYSTIME_STR + "  INFO: [ndn.util.tests.Specialized1] class template static member function\n" +
+    LOG_SYSTIME_STR + "  INFO: [ndn.util.tests.Specialized1] class template non-static member function\n"
     ));
 }
 
@@ -340,10 +340,10 @@
 
   Logging::flush();
   BOOST_CHECK(os.is_equal(
-    LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module1] warn1\n" +
     LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
     LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
-    LOG_SYSTIME_STR + " WARNING: [Module1] warnModule1\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module1] warnModule1\n" +
     LOG_SYSTIME_STR + " ERROR: [Module1] errorModule1\n" +
     LOG_SYSTIME_STR + " FATAL: [Module1] fatalModule1\n"
     ));
@@ -357,8 +357,8 @@
   Logging::flush();
   BOOST_CHECK(os.is_equal(
     LOG_SYSTIME_STR + " DEBUG: [Module3] debugModule3\n" +
-    LOG_SYSTIME_STR + " INFO: [Module3] infoModule3\n" +
-    LOG_SYSTIME_STR + " WARNING: [Module3] warnModule3\n" +
+    LOG_SYSTIME_STR + "  INFO: [Module3] infoModule3\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module3] warnModule3\n" +
     LOG_SYSTIME_STR + " ERROR: [Module3] errorModule3\n" +
     LOG_SYSTIME_STR + " FATAL: [Module3] fatalModule3\n"
     ));
@@ -386,10 +386,10 @@
 
   Logging::flush();
   BOOST_CHECK(os.is_equal(
-    LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module1] warn1\n" +
     LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
     LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
-    LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module2] warn2\n" +
     LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
     LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
     ));
@@ -404,12 +404,12 @@
 
   Logging::flush();
   BOOST_CHECK(os.is_equal(
-    LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module1] warn1\n" +
     LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
     LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
     LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
-    LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
-    LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
+    LOG_SYSTIME_STR + "  INFO: [Module2] info2\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module2] warn2\n" +
     LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
     LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
     ));
@@ -446,10 +446,10 @@
 
   Logging::flush();
   BOOST_CHECK(os.is_equal(
-    LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module1] warn1\n" +
     LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
     LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
-    LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module2] warn2\n" +
     LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
     LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
     ));
@@ -485,12 +485,12 @@
 
   Logging::flush();
   BOOST_CHECK(os.is_equal(
-    LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module1] warn1\n" +
     LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
     LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
     LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
-    LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
-    LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
+    LOG_SYSTIME_STR + "  INFO: [Module2] info2\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module2] warn2\n" +
     LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
     LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
     ));
@@ -510,12 +510,12 @@
 
   Logging::flush();
   BOOST_CHECK(os.is_equal(
-    LOG_SYSTIME_STR + " WARNING: [Module1] warn1\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module1] warn1\n" +
     LOG_SYSTIME_STR + " ERROR: [Module1] error1\n" +
     LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
     LOG_SYSTIME_STR + " DEBUG: [Module2] debug2\n" +
-    LOG_SYSTIME_STR + " INFO: [Module2] info2\n" +
-    LOG_SYSTIME_STR + " WARNING: [Module2] warn2\n" +
+    LOG_SYSTIME_STR + "  INFO: [Module2] info2\n" +
+    LOG_SYSTIME_STR + "  WARN: [Module2] warn2\n" +
     LOG_SYSTIME_STR + " ERROR: [Module2] error2\n" +
     LOG_SYSTIME_STR + " FATAL: [Module2] fatal2\n"
     ));
@@ -563,8 +563,8 @@
   BOOST_CHECK(os.is_equal(
     LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
     LOG_SYSTIME_STR + " DEBUG: [fm.FilterModule] debugFM\n" +
-    LOG_SYSTIME_STR + " INFO: [fm.FilterModule] infoFM\n" +
-    LOG_SYSTIME_STR + " WARNING: [fm.FilterModule] warnFM\n" +
+    LOG_SYSTIME_STR + "  INFO: [fm.FilterModule] infoFM\n" +
+    LOG_SYSTIME_STR + "  WARN: [fm.FilterModule] warnFM\n" +
     LOG_SYSTIME_STR + " ERROR: [fm.FilterModule] errorFM\n" +
     LOG_SYSTIME_STR + " FATAL: [fm.FilterModule] fatalFM\n"
     ));
@@ -586,8 +586,8 @@
   Logging::flush();
   BOOST_CHECK(os.is_equal(
     LOG_SYSTIME_STR + " FATAL: [Module1] fatal1\n" +
-    LOG_SYSTIME_STR + " INFO: [fm.FilterModule] infoFM\n" +
-    LOG_SYSTIME_STR + " WARNING: [fm.FilterModule] warnFM\n" +
+    LOG_SYSTIME_STR + "  INFO: [fm.FilterModule] infoFM\n" +
+    LOG_SYSTIME_STR + "  WARN: [fm.FilterModule] warnFM\n" +
     LOG_SYSTIME_STR + " ERROR: [fm.FilterModule] errorFM\n" +
     LOG_SYSTIME_STR + " FATAL: [fm.FilterModule] fatalFM\n"
     ));
@@ -603,8 +603,8 @@
 
   Logging::flush();
   BOOST_CHECK(os.is_equal(
-    LOG_SYSTIME_STR + " INFO: [fm.a.b] infofm.a.b\n" +
-    LOG_SYSTIME_STR + " WARNING: [fm.a.b] warnfm.a.b\n" +
+    LOG_SYSTIME_STR + "  INFO: [fm.a.b] infofm.a.b\n" +
+    LOG_SYSTIME_STR + "  WARN: [fm.a.b] warnfm.a.b\n" +
     LOG_SYSTIME_STR + " ERROR: [fm.a.b] errorfm.a.b\n" +
     LOG_SYSTIME_STR + " FATAL: [fm.a.b] fatalfm.a.b\n" +
     LOG_SYSTIME_STR + " ERROR: [fm.a.b.c] errorfm.a.b.c\n" +