util: Introduce NDN_LOG_NOFLUSH env variable to disable auto-flushing logs
Change-Id: Id1699d044e318aac315a545e913d0fc80306939b
Refs: #3668
diff --git a/docs/manpages/ndn-log.rst b/docs/manpages/ndn-log.rst
index b8fc3b2..40db707 100644
--- a/docs/manpages/ndn-log.rst
+++ b/docs/manpages/ndn-log.rst
@@ -18,6 +18,11 @@
setting the environment variable. Wildcards can be used to enable logging for all
modules (just ``*``) or all modules under a selected prefix (e.g., ``ndn.*``).
+If an additional environment variable ``NDN_LOG_NOFLUSH`` is set, the automatic flushing
+after each log record will be disabled. This can improve logging performance but may
+cause the log records to appear delayed or, in case of application crash, the last
+few log records may be lost.
+
ndn-cxx logging facility provides a mechanism to manage the type of log messages
that are written by classifying log messages by severity levels. Listed below
are the available log levels.
diff --git a/ndn-cxx/util/logging.cpp b/ndn-cxx/util/logging.cpp
index ca6d584..4db9f28 100644
--- a/ndn-cxx/util/logging.cpp
+++ b/ndn-cxx/util/logging.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -90,11 +90,17 @@
Logging::Logging()
{
+ bool wantAutoFlush = true;
+ const char* environ = std::getenv("NDN_LOG_NOFLUSH");
+ if (environ != nullptr) {
+ wantAutoFlush = false;
+ }
+
// cannot call the static setDestination that uses the singleton Logging object that is not yet constructed
- auto destination = makeDefaultStreamDestination(shared_ptr<std::ostream>(&std::clog, [] (auto) {}));
+ auto destination = makeDefaultStreamDestination(shared_ptr<std::ostream>(&std::clog, [] (auto) {}), wantAutoFlush);
this->setDestinationImpl(std::move(destination));
- const char* environ = std::getenv("NDN_LOG");
+ environ = std::getenv("NDN_LOG");
if (environ != nullptr) {
this->setLevelImpl(environ);
}
@@ -242,19 +248,19 @@
#endif // NDN_CXX_HAVE_TESTS
void
-Logging::setDestination(std::ostream& os)
+Logging::setDestination(std::ostream& os, bool wantAutoFlush)
{
- auto destination = makeDefaultStreamDestination(shared_ptr<std::ostream>(&os, [] (auto) {}));
+ auto destination = makeDefaultStreamDestination(shared_ptr<std::ostream>(&os, [] (auto) {}), wantAutoFlush);
setDestination(std::move(destination));
}
class TextOstreamBackend : public boost::log::sinks::text_ostream_backend
{
public:
- TextOstreamBackend(std::shared_ptr<std::ostream> os)
+ TextOstreamBackend(std::shared_ptr<std::ostream> os, bool wantAutoFlush)
: m_stdPtr(std::move(os))
{
- auto_flush(true);
+ auto_flush(wantAutoFlush);
add_stream(boost::shared_ptr<std::ostream>(m_stdPtr.get(), [] (auto) {}));
}
@@ -265,9 +271,9 @@
};
boost::shared_ptr<boost::log::sinks::sink>
-Logging::makeDefaultStreamDestination(shared_ptr<std::ostream> os)
+Logging::makeDefaultStreamDestination(shared_ptr<std::ostream> os, bool wantAutoFlush)
{
- auto backend = boost::make_shared<TextOstreamBackend>(std::move(os));
+ auto backend = boost::make_shared<TextOstreamBackend>(std::move(os), wantAutoFlush);
auto destination = boost::make_shared<boost::log::sinks::asynchronous_sink<TextOstreamBackend>>(backend);
namespace expr = boost::log::expressions;
diff --git a/ndn-cxx/util/logging.hpp b/ndn-cxx/util/logging.hpp
index 8162358..ccb2196 100644
--- a/ndn-cxx/util/logging.hpp
+++ b/ndn-cxx/util/logging.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -97,12 +97,13 @@
/** \brief Helper method to set stream log destination.
* \param os a stream for log output; caller must ensure it remains valid
* until setDestination() is invoked again or program exits
+ * \param wantAutoFlush if true, the created logging sink will be auto-flushed
*`
* This is equivalent to `setDestination(makeDefaultStreamDestination(shared_ptr<std::ostream>(&os, nullDeleter)))`.
*
*/
static void
- setDestination(std::ostream& os);
+ setDestination(std::ostream& os, bool wantAutoFlush = true);
/** \brief Flush log backend.
*
@@ -114,7 +115,7 @@
/** \brief Create stream log destination using default formatting
*/
static boost::shared_ptr<boost::log::sinks::sink>
- makeDefaultStreamDestination(shared_ptr<std::ostream> os);
+ makeDefaultStreamDestination(shared_ptr<std::ostream> os, bool wantAutoFlush = true);
private:
Logging();