You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by al...@apache.org on 2017/04/11 13:12:36 UTC

nifi-minifi-cpp git commit: MINIFI-261: Allow std::string to be used for log messages

Repository: nifi-minifi-cpp
Updated Branches:
  refs/heads/master bcabd4451 -> 4a4602a27


MINIFI-261: Allow std::string to be used for log messages

This closes #76.

Signed-off-by: Aldrin Piri <al...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/commit/4a4602a2
Tree: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/tree/4a4602a2
Diff: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/diff/4a4602a2

Branch: refs/heads/master
Commit: 4a4602a27ba4672422a69f0970ee73e000d60b77
Parents: bcabd44
Author: Marc Parisi <ph...@apache.org>
Authored: Mon Apr 10 10:35:33 2017 -0400
Committer: Aldrin Piri <al...@apache.org>
Committed: Tue Apr 11 09:11:55 2017 -0400

----------------------------------------------------------------------
 libminifi/include/core/logging/BaseLogger.h | 100 +++++++++++--
 libminifi/include/core/logging/Logger.h     |  40 +++--
 libminifi/src/core/logging/BaseLogger.cpp   |  55 -------
 libminifi/test/unit/LoggerTests.cpp         | 178 ++++++++++++++++++++++-
 4 files changed, 290 insertions(+), 83 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/4a4602a2/libminifi/include/core/logging/BaseLogger.h
----------------------------------------------------------------------
diff --git a/libminifi/include/core/logging/BaseLogger.h b/libminifi/include/core/logging/BaseLogger.h
index bfdf26f..9d00fb6 100644
--- a/libminifi/include/core/logging/BaseLogger.h
+++ b/libminifi/include/core/logging/BaseLogger.h
@@ -51,11 +51,25 @@ typedef enum {
 } LOG_LEVEL_E;
 
 #define LOG_BUFFER_SIZE 1024
-#define FILL_BUFFER  char buffer[LOG_BUFFER_SIZE]; \
-    va_list args; \
-    va_start(args, format); \
-    std::vsnprintf(buffer, LOG_BUFFER_SIZE,format, args); \
-    va_end(args);
+
+template<typename ... Args>
+inline std::string format_string(char const* format_str, Args&&... args) {
+  char buf[LOG_BUFFER_SIZE];
+  std::snprintf(buf, LOG_BUFFER_SIZE, format_str, args...);
+  return std::string(buf);
+}
+
+inline std::string format_string(char const* format_str) {
+  return format_str;
+}
+inline char const* conditional_conversion(std::string const& str) {
+  return str.c_str();
+}
+
+template<typename T>
+inline T conditional_conversion(T const& t) {
+  return t;
+}
 
 /**
  * Base class that represents a logger configuration.
@@ -113,31 +127,36 @@ class BaseLogger {
    * @param format format string ('man printf' for syntax)
    * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
    */
-  virtual void log_error(const char * const format, ...);
+  template<typename ... Args>
+  void log_error(const char * const format, Args ... args);
   /**
    * @brief Log warn message
    * @param format format string ('man printf' for syntax)
    * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
    */
-  virtual void log_warn(const char * const format, ...);
+  template<typename ... Args>
+  void log_warn(const char * const format, Args ... args);
   /**
    * @brief Log info message
    * @param format format string ('man printf' for syntax)
    * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
    */
-  virtual void log_info(const char * const format, ...);
+  template<typename ... Args>
+  void log_info(const char * const format, Args ... args);
   /**
    * @brief Log debug message
    * @param format format string ('man printf' for syntax)
    * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
    */
-  virtual void log_debug(const char * const format, ...);
+  template<typename ... Args>
+  void log_debug(const char * const format, Args ... args);
   /**
    * @brief Log trace message
    * @param format format string ('man printf' for syntax)
    * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
    */
-  virtual void log_trace(const char * const format, ...);
+  template<typename ... Args>
+  void log_trace(const char * const format, Args ... args);
 
   /**
    * @brief Log error message
@@ -215,6 +234,67 @@ class BaseLogger {
   std::shared_ptr<spdlog::logger> stderr_;
 };
 
+/**
+ * @brief Log error message
+ * @param format format string ('man printf' for syntax)
+ * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
+ */
+template<typename ... Args>
+void BaseLogger::log_error(const char * const format, Args ... args) {
+  if (logger_ == NULL || !logger_->should_log(spdlog::level::level_enum::err))
+    return;
+
+  log_str(err, format_string(format, conditional_conversion(args)...));
+}
+/**
+ * @brief Log warn message
+ * @param format format string ('man printf' for syntax)
+ * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
+ */
+template<typename ... Args>
+void BaseLogger::log_warn(const char * const format, Args ... args) {
+  if (logger_ == NULL || !logger_->should_log(spdlog::level::level_enum::warn))
+    return;
+
+  log_str(warn, format_string(format, conditional_conversion(args)...));
+}
+/**
+ * @brief Log info message
+ * @param format format string ('man printf' for syntax)
+ * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
+ */
+template<typename ... Args>
+void BaseLogger::log_info(const char * const format, Args ... args) {
+  if (logger_ == NULL || !logger_->should_log(spdlog::level::level_enum::info))
+    return;
+
+  log_str(info, format_string(format, conditional_conversion(args)...));
+}
+/**
+ * @brief Log debug message
+ * @param format format string ('man printf' for syntax)
+ * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
+ */
+template<typename ... Args>
+void BaseLogger::log_debug(const char * const format, Args ... args) {
+  if (logger_ == NULL || !logger_->should_log(spdlog::level::level_enum::debug))
+    return;
+
+  log_str(debug, format_string(format, conditional_conversion(args)...));
+}
+/**
+ * @brief Log trace message
+ * @param format format string ('man printf' for syntax)
+ * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
+ */
+template<typename ... Args>
+void BaseLogger::log_trace(const char * const format, Args ... args) {
+  if (logger_ == NULL || !logger_->should_log(spdlog::level::level_enum::trace))
+    return;
+
+  log_str(debug, format_string(format, conditional_conversion(args)...));
+}
+
 } /* namespace logging */
 } /* namespace core */
 } /* namespace minifi */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/4a4602a2/libminifi/include/core/logging/Logger.h
----------------------------------------------------------------------
diff --git a/libminifi/include/core/logging/Logger.h b/libminifi/include/core/logging/Logger.h
index 08ef702..995c96f 100644
--- a/libminifi/include/core/logging/Logger.h
+++ b/libminifi/include/core/logging/Logger.h
@@ -100,57 +100,67 @@ class Logger : public BaseLogger {
    * @param format format string ('man printf' for syntax)
    * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
    */
-  void log_error(const char * const format, ...) {
+  template<typename ... Args>
+  void log_error(const char * const format, Args ... args) {
     if (!current_logger_.load()->shouldLog(err))
       return;
-    FILL_BUFFER
-    current_logger_.load()->log_str(err, buffer);
+
+    current_logger_.load()->log_str(
+        err, format_string(format, conditional_conversion(args)...));
   }
   /**
    * @brief Log warn message
    * @param format format string ('man printf' for syntax)
    * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
    */
-  void log_warn(const char * const format, ...) {
+  template<typename ... Args>
+  void log_warn(const char * const format, Args ... args) {
     if (!current_logger_.load()->shouldLog(warn))
       return;
-    FILL_BUFFER
-    current_logger_.load()->log_str(warn, buffer);
+
+    current_logger_.load()->log_str(
+        warn, format_string(format, conditional_conversion(args)...));
   }
   /**
    * @brief Log info message
    * @param format format string ('man printf' for syntax)
    * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
    */
-  void log_info(const char * const format, ...) {
+  template<typename ... Args>
+  void log_info(const char * const format, Args ... args) {
     if (!current_logger_.load()->shouldLog(info))
       return;
-    FILL_BUFFER
-    current_logger_.load()->log_str(info, buffer);
+
+    current_logger_.load()->log_str(
+        info, format_string(format, conditional_conversion(args)...));
   }
   /**
    * @brief Log debug message
    * @param format format string ('man printf' for syntax)
    * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
    */
-  void log_debug(const char * const format, ...) {
+  template<typename ... Args>
+  void log_debug(const char * const format, Args ... args) {
 
     if (!current_logger_.load()->shouldLog(debug))
       return;
-    FILL_BUFFER
-    current_logger_.load()->log_str(debug, buffer);
+
+    current_logger_.load()->log_str(
+        debug, format_string(format, conditional_conversion(args)...));
   }
   /**
    * @brief Log trace message
    * @param format format string ('man printf' for syntax)
    * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
    */
-  void log_trace(const char * const format, ...) {
+  template<typename ... Args>
+  void log_trace(const char * const format, Args ... args) {
 
     if (!current_logger_.load()->shouldLog(trace))
       return;
-    FILL_BUFFER
-    current_logger_.load()->log_str(trace, buffer);
+
+    current_logger_.load()->log_str(
+        trace, format_string(format, conditional_conversion(args)...));
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/4a4602a2/libminifi/src/core/logging/BaseLogger.cpp
----------------------------------------------------------------------
diff --git a/libminifi/src/core/logging/BaseLogger.cpp b/libminifi/src/core/logging/BaseLogger.cpp
index d4774df..9164270 100644
--- a/libminifi/src/core/logging/BaseLogger.cpp
+++ b/libminifi/src/core/logging/BaseLogger.cpp
@@ -33,61 +33,6 @@ namespace logging {
 const char *BaseLogger::nifi_log_level = "nifi.log.level";
 const char *BaseLogger::nifi_log_appender = "nifi.log.appender";
 
-/**
- * @brief Log error message
- * @param format format string ('man printf' for syntax)
- * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
- */
-void BaseLogger::log_error(const char * const format, ...) {
-  if (logger_ == NULL || !logger_->should_log(spdlog::level::level_enum::err))
-    return;
-  FILL_BUFFER
-  log_str(err, buffer);
-}
-/**
- * @brief Log warn message
- * @param format format string ('man printf' for syntax)
- * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
- */
-void BaseLogger::log_warn(const char * const format, ...) {
-  if (logger_ == NULL || !logger_->should_log(spdlog::level::level_enum::warn))
-    return;
-  FILL_BUFFER
-  log_str(warn, buffer);
-}
-/**
- * @brief Log info message
- * @param format format string ('man printf' for syntax)
- * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
- */
-void BaseLogger::log_info(const char * const format, ...) {
-  if (logger_ == NULL || !logger_->should_log(spdlog::level::level_enum::info))
-    return;
-  FILL_BUFFER
-  log_str(info, buffer);
-}
-/**
- * @brief Log debug message
- * @param format format string ('man printf' for syntax)
- * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
- */
-void BaseLogger::log_debug(const char * const format, ...) {
-  if (logger_ == NULL || !logger_->should_log(spdlog::level::level_enum::debug))
-    return;
-  FILL_BUFFER
-  log_str(debug, buffer);
-}
-/**
- * @brief Log trace message
- * @param format format string ('man printf' for syntax)
- * @warning does not check @p log or @p format for null. Caller must ensure parameters and format string lengths match
- */
-void BaseLogger::log_trace(const char * const format, ...) {
-  if (logger_ == NULL || !logger_->should_log(spdlog::level::level_enum::trace))
-    return;
-  FILL_BUFFER
-  log_str(debug, buffer);
-}
 
 // overridables
 

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/4a4602a2/libminifi/test/unit/LoggerTests.cpp
----------------------------------------------------------------------
diff --git a/libminifi/test/unit/LoggerTests.cpp b/libminifi/test/unit/LoggerTests.cpp
index efa30bf..cbf7a36 100644
--- a/libminifi/test/unit/LoggerTests.cpp
+++ b/libminifi/test/unit/LoggerTests.cpp
@@ -17,7 +17,7 @@
  */
 
 #include <memory>
-
+#include <ctime>
 #include "../TestBase.h"
 #include "core/logging/LogAppenders.h"
 
@@ -154,13 +154,13 @@ TEST_CASE("Test log Levels change", "[ttl5]") {
 
 }
 
+
 TEST_CASE("Test log LevelsConfigured", "[ttl6]") {
   std::ostringstream oss;
 
   minifi::Configure *config = minifi::Configure::getConfigure();
 
-  config->set(BaseLogger::nifi_log_appender,
-              "OutputStreamAppender");
+  config->set(BaseLogger::nifi_log_appender, "OutputStreamAppender");
   config->set(
       org::apache::nifi::minifi::core::logging::OutputStreamAppender::nifi_log_output_stream_error_stderr,
       "true");
@@ -205,5 +205,177 @@ TEST_CASE("Test log LevelsConfigured", "[ttl6]") {
 
   REQUIRE(0 == oss.str().length());
 
+}
+
+TEST_CASE("Test log Levels With std::string", "[ttl1]") {
+  std::ostringstream oss;
+
+  std::unique_ptr<BaseLogger> outputLogger = std::unique_ptr<BaseLogger>(
+      new org::apache::nifi::minifi::core::logging::OutputStreamAppender(oss,
+                                                                         0));
+  std::shared_ptr<logging::Logger> logger = logging::Logger::getLogger();
+  logger->updateLogger(std::move(outputLogger));
+  logger->setLogLevel("trace");
+  std::string world = "world";
+  logger->log_error("hello %s", world);
+
+  REQUIRE(
+      true
+          == contains(
+              oss.str(),
+              "[minifi log -- org::apache::nifi::minifi::core::logging::OutputStreamAppender] [error] hello world"));
+  oss.str("");
+  oss.clear();
+  REQUIRE(0 == oss.str().length());
+  logger->setLogLevel("off");
+
+  logger->log_error("hello world");
+
+  REQUIRE(0 == oss.str().length());
+
+  std::unique_ptr<BaseLogger> nullAppender = std::unique_ptr<BaseLogger>(
+      new org::apache::nifi::minifi::core::logging::NullAppender());
+
+  logger->updateLogger(std::move(nullAppender));
+
+}
+
+TEST_CASE("Test log Levels debug With std::string ", "[ttl2]") {
+  std::ostringstream oss;
+
+  std::unique_ptr<BaseLogger> outputLogger = std::unique_ptr<BaseLogger>(
+      new org::apache::nifi::minifi::core::logging::OutputStreamAppender(oss,
+                                                                         0));
+  std::shared_ptr<logging::Logger> logger = logging::Logger::getLogger();
+  logger->updateLogger(std::move(outputLogger));
+  logger->setLogLevel("trace");
+  std::string world = "world";
+  logger->log_debug("hello %s", world);
+
+  REQUIRE(
+      true
+          == contains(
+              oss.str(),
+              "[minifi log -- org::apache::nifi::minifi::core::logging::OutputStreamAppender] [debug] hello world"));
+
+  std::unique_ptr<BaseLogger> nullAppender = std::unique_ptr<BaseLogger>(
+      new org::apache::nifi::minifi::core::logging::NullAppender());
+
+  logger->updateLogger(std::move(nullAppender));
+}
+
+TEST_CASE("Test log Levels trace With std::string", "[ttl3]") {
+  std::ostringstream oss;
+
+  std::unique_ptr<BaseLogger> outputLogger = std::unique_ptr<BaseLogger>(
+      new org::apache::nifi::minifi::core::logging::OutputStreamAppender(oss,
+                                                                         0));
+  std::shared_ptr<logging::Logger> logger = logging::Logger::getLogger();
+  logger->updateLogger(std::move(outputLogger));
+  logger->setLogLevel("trace");
+  std::string world = "world";
+  logger->log_trace("hello %s", world);
+
+  REQUIRE(
+      true
+          == contains(
+              oss.str(),
+              "[minifi log -- org::apache::nifi::minifi::core::logging::OutputStreamAppender] [trace] hello world"));
+
+  std::unique_ptr<BaseLogger> nullAppender = std::unique_ptr<BaseLogger>(
+      new org::apache::nifi::minifi::core::logging::NullAppender());
+
+  logger->updateLogger(std::move(nullAppender));
+}
+
+TEST_CASE("Test log Levels error With std::string ", "[ttl4]") {
+  std::ostringstream oss;
+
+  std::unique_ptr<BaseLogger> outputLogger = std::unique_ptr<BaseLogger>(
+      new org::apache::nifi::minifi::core::logging::OutputStreamAppender(oss,
+                                                                         0));
+  std::shared_ptr<logging::Logger> logger = logging::Logger::getLogger();
+  logger->updateLogger(std::move(outputLogger));
+  logger->setLogLevel("trace");
+
+  std::string world = "world";
+  logger->log_error("hello %s", world);
+
+  REQUIRE(
+      true
+          == contains(
+              oss.str(),
+              "[minifi log -- org::apache::nifi::minifi::core::logging::OutputStreamAppender] [error] hello world"));
+
+  std::unique_ptr<BaseLogger> nullAppender = std::unique_ptr<BaseLogger>(
+      new org::apache::nifi::minifi::core::logging::NullAppender());
+
+  logger->updateLogger(std::move(nullAppender));
+}
+
+TEST_CASE("Test log Levels change With std::string ", "[ttl5]") {
+  std::ostringstream oss;
+
+  std::unique_ptr<BaseLogger> outputLogger = std::unique_ptr<BaseLogger>(
+      new org::apache::nifi::minifi::core::logging::OutputStreamAppender(oss,
+                                                                         0));
+  std::shared_ptr<logging::Logger> logger = logging::Logger::getLogger();
+  logger->updateLogger(std::move(outputLogger));
+  logger->setLogLevel("trace");
+
+  std::string world = "world";
+  logger->log_error("hello %s", world);
+
+  REQUIRE(
+      true
+          == contains(
+              oss.str(),
+              "[minifi log -- org::apache::nifi::minifi::core::logging::OutputStreamAppender] [error] hello world"));
+  oss.str("");
+  oss.clear();
+  REQUIRE(0 == oss.str().length());
+  logger->setLogLevel("off");
+
+  logger->log_error("hello %s", world);
+
+  REQUIRE(0 == oss.str().length());
+
+  std::unique_ptr<BaseLogger> nullAppender = std::unique_ptr<BaseLogger>(
+      new org::apache::nifi::minifi::core::logging::NullAppender());
+
+  logger->updateLogger(std::move(nullAppender));
+
+}
+
+TEST_CASE("Test log Levels change With std::string maybe ", "[ttl5]") {
+  std::ostringstream oss;
+
+  std::unique_ptr<BaseLogger> outputLogger = std::unique_ptr<BaseLogger>(
+      new org::apache::nifi::minifi::core::logging::OutputStreamAppender(oss,
+                                                                         0));
+  std::shared_ptr<logging::Logger> logger = logging::Logger::getLogger();
+  logger->updateLogger(std::move(outputLogger));
+  logger->setLogLevel("trace");
+
+  logger->log_error("hello %s", "world");
+
+  REQUIRE(
+      true
+          == contains(
+              oss.str(),
+              "[minifi log -- org::apache::nifi::minifi::core::logging::OutputStreamAppender] [error] hello world"));
+  oss.str("");
+  oss.clear();
+  REQUIRE(0 == oss.str().length());
+  logger->setLogLevel("off");
+
+  logger->log_error("hello %s", "world");
+
+  REQUIRE(0 == oss.str().length());
+
+  std::unique_ptr<BaseLogger> nullAppender = std::unique_ptr<BaseLogger>(
+      new org::apache::nifi::minifi::core::logging::NullAppender());
+
+  logger->updateLogger(std::move(nullAppender));
 
 }