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 <[email protected]> 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 <[email protected]> Authored: Mon Apr 10 10:35:33 2017 -0400 Committer: Aldrin Piri <[email protected]> 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)); }
