You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by if...@apache.org on 2021/03/11 02:55:39 UTC

[rocketmq-client-cpp] branch re_dev updated: refactor: Logging

This is an automated email from the ASF dual-hosted git repository.

ifplusor pushed a commit to branch re_dev
in repository https://gitbox.apache.org/repos/asf/rocketmq-client-cpp.git


The following commit(s) were added to refs/heads/re_dev by this push:
     new 487dfee  refactor: Logging
487dfee is described below

commit 487dfeea6ba9974c9cead5b2e7037a63eb24b34e
Author: James Yin <yw...@hotmail.com>
AuthorDate: Wed Mar 10 19:14:58 2021 +0800

    refactor: Logging
---
 src/extern/CProducer.cpp     |   7 +-
 src/extern/CPushConsumer.cpp |   7 +-
 src/log/Logging.cpp          | 121 +++++++++++++---------------
 src/log/Logging.h            | 184 ++++++++++++++++++++++++++++++++-----------
 4 files changed, 201 insertions(+), 118 deletions(-)

diff --git a/src/extern/CProducer.cpp b/src/extern/CProducer.cpp
index 7629594..893143a 100644
--- a/src/extern/CProducer.cpp
+++ b/src/extern/CProducer.cpp
@@ -511,7 +511,9 @@ int SetProducerLogFileNumAndSize(CProducer* producer, int fileNum, long fileSize
   if (producer == NULL) {
     return NULL_POINTER;
   }
-  DEFAULT_LOGGER_INSTANCE->setLogFileNumAndSize(fileNum, fileSize);
+  auto& default_logger_config = GetDefaultLoggerConfig();
+  default_logger_config.set_file_count(fileNum);
+  default_logger_config.set_file_size(fileSize);
   return OK;
 }
 
@@ -519,7 +521,8 @@ int SetProducerLogLevel(CProducer* producer, CLogLevel level) {
   if (producer == NULL) {
     return NULL_POINTER;
   }
-  DEFAULT_LOGGER_INSTANCE->set_log_level((LogLevel)level);
+  auto& default_logger_config = GetDefaultLoggerConfig();
+  default_logger_config.set_level(static_cast<LogLevel>(level));
   return OK;
 }
 
diff --git a/src/extern/CPushConsumer.cpp b/src/extern/CPushConsumer.cpp
index f90802e..4beee35 100644
--- a/src/extern/CPushConsumer.cpp
+++ b/src/extern/CPushConsumer.cpp
@@ -258,7 +258,9 @@ int SetPushConsumerLogFileNumAndSize(CPushConsumer* consumer, int fileNum, long
   if (consumer == NULL) {
     return NULL_POINTER;
   }
-  DEFAULT_LOGGER_INSTANCE->setLogFileNumAndSize(fileNum, fileSize);
+  auto& default_logger_config = GetDefaultLoggerConfig();
+  default_logger_config.set_file_count(fileNum);
+  default_logger_config.set_file_size(fileSize);
   return OK;
 }
 
@@ -266,6 +268,7 @@ int SetPushConsumerLogLevel(CPushConsumer* consumer, CLogLevel level) {
   if (consumer == NULL) {
     return NULL_POINTER;
   }
-  DEFAULT_LOGGER_INSTANCE->set_log_level((LogLevel)level);
+  auto& default_logger_config = GetDefaultLoggerConfig();
+  default_logger_config.set_level(static_cast<LogLevel>(level));
   return OK;
 }
diff --git a/src/log/Logging.cpp b/src/log/Logging.cpp
index 7d29170..6eb958e 100644
--- a/src/log/Logging.cpp
+++ b/src/log/Logging.cpp
@@ -17,6 +17,8 @@
 #include "Logging.h"
 
 #include <iostream>  // std::cerr, std::endl
+#include <memory>
+#include <mutex>
 
 #if SPDLOG_VER_MAJOR >= 1
 #include <spdlog/async.h>
@@ -29,30 +31,35 @@
 
 namespace rocketmq {
 
-Logger* Logger::getLoggerInstance() {
-  static Logger singleton_("default");
-  return &singleton_;
+static void ConfigSpdlog() {
+  spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread@%t] - %v [%@ (%!)]");
+  // when an error occurred, flush disk immediately
+  spdlog::flush_on(spdlog::level::err);
+#if SPDLOG_VER_MAJOR >= 1
+  spdlog::init_thread_pool(spdlog::details::default_async_q_size, 1);
+  spdlog::flush_every(std::chrono::seconds(3));
+#else
+  spdlog::set_async_mode(8192, async_overflow_policy::block_retry, nullptr, std::chrono::milliseconds(3000), nullptr);
+#endif
 }
 
-Logger::Logger(const std::string& name) : log_level_(LOG_LEVEL_INFO) {
-  try {
-    init_log_dir_();
-    init_spdlog_env_();
-    logger_ = create_rotating_logger_(name, log_file_, 1024 * 1024 * 100, 3);
-    set_log_level_(log_level_);
-  } catch (std::exception& e) {
-    std::cerr << "initialite logger failed" << std::endl;
-    exit(-1);
-  }
+static std::shared_ptr<spdlog::logger> CreateRotatingLogger(const std::string& name,
+                                                            const std::string& filepath,
+                                                            std::size_t max_size,
+                                                            std::size_t max_files) {
+#if SPDLOG_VER_MAJOR >= 1
+  return spdlog::create_async<spdlog::sinks::rotating_file_sink_mt>(name, filepath, max_size, max_files);
+#else
+  return spdlog::rotating_logger_mt(name, filepath, max_size, max_files);
+#endif
 }
 
-Logger::~Logger() {
-  if (logger_ != nullptr) {
-    spdlog::drop(logger_->name());
-  }
+static spdlog::level::level_enum ConvertLogLevel(LogLevel log_level) {
+  int level = static_cast<int>(log_level);
+  return static_cast<spdlog::level::level_enum>(6 - level);
 }
 
-void Logger::init_log_dir_() {
+static std::string GetDefaultLogDir() {
   std::string log_dir;
   const char* dir = std::getenv(ROCKETMQ_CPP_LOG_DIR_ENV.c_str());
   if (dir != nullptr && dir[0] != '\0') {
@@ -66,64 +73,44 @@ void Logger::init_log_dir_() {
     log_dir += FILE_SEPARATOR;
   }
   std::string log_file_name = UtilAll::to_string(UtilAll::getProcessId()) + "_" + "rocketmq-cpp.log";
-  log_file_ = log_dir + log_file_name;
+  return log_dir + log_file_name;
 }
 
-void Logger::init_spdlog_env_() {
-  spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [thread@%t] - %v");
-  // when an error occurred, flush disk immediately
-  spdlog::flush_on(spdlog::level::err);
-#if SPDLOG_VER_MAJOR >= 1
-  spdlog::init_thread_pool(spdlog::details::default_async_q_size, 1);
-  spdlog::flush_every(std::chrono::seconds(3));
-#else
-  spdlog::set_async_mode(8192, async_overflow_policy::block_retry, nullptr, std::chrono::milliseconds(3000), nullptr);
-#endif
+LoggerConfig& GetDefaultLoggerConfig() {
+  static LoggerConfig default_logger_config("default", GetDefaultLogDir());
+  return default_logger_config;
 }
 
-std::shared_ptr<spdlog::logger> Logger::create_rotating_logger_(const std::string& name,
-                                                                const std::string& filepath,
-                                                                std::size_t max_size,
-                                                                std::size_t max_files) {
-#if SPDLOG_VER_MAJOR >= 1
-  return spdlog::create_async<spdlog::sinks::rotating_file_sink_mt>(name, filepath, max_size, max_files);
-#else
-  return spdlog::rotating_logger_mt(name, filepath, max_size, max_files);
-#endif
+static std::once_flag default_logger_init_flag;
+static std::unique_ptr<Logger> default_logger;
+
+Logger& GetDefaultLogger() {
+  if (default_logger == nullptr) {
+    std::call_once(default_logger_init_flag, [] {
+      auto& default_logger_config = GetDefaultLoggerConfig();
+      if (default_logger_config.config_spdlog()) {
+        ConfigSpdlog();
+      }
+      default_logger.reset(new Logger(default_logger_config));
+    });
+  }
+  return *default_logger;
 }
 
-void Logger::set_log_level_(LogLevel log_level) {
-  switch (log_level) {
-    case LOG_LEVEL_FATAL:
-      logger_->set_level(spdlog::level::critical);
-      break;
-    case LOG_LEVEL_ERROR:
-      logger_->set_level(spdlog::level::err);
-      break;
-    case LOG_LEVEL_WARN:
-      logger_->set_level(spdlog::level::warn);
-      break;
-    case LOG_LEVEL_INFO:
-      logger_->set_level(spdlog::level::info);
-      break;
-    case LOG_LEVEL_DEBUG:
-      logger_->set_level(spdlog::level::debug);
-      break;
-    case LOG_LEVEL_TRACE:
-      logger_->set_level(spdlog::level::trace);
-      break;
-    default:
-      logger_->set_level(spdlog::level::info);
-      break;
+Logger::Logger(const LoggerConfig& config) {
+  try {
+    logger_ = CreateRotatingLogger(config.name(), config.path(), config.file_size(), config.file_count());
+    logger_->set_level(ConvertLogLevel(config.level()));
+  } catch (std::exception& e) {
+    std::cerr << "initialite logger failed" << std::endl;
+    exit(-1);
   }
 }
 
-void Logger::setLogFileNumAndSize(int logNum, int sizeOfPerFile) {
-  // FIXME: set after clients started
-  auto name = logger_->name();
-  spdlog::drop(name);
-  logger_ = create_rotating_logger_(name, log_file_, sizeOfPerFile, logNum);
-  set_log_level_(log_level_);
+Logger::~Logger() {
+  if (logger_ != nullptr) {
+    spdlog::drop(logger_->name());
+  }
 }
 
 }  // namespace rocketmq
diff --git a/src/log/Logging.h b/src/log/Logging.h
index 42b1f3b..24bbd95 100644
--- a/src/log/Logging.h
+++ b/src/log/Logging.h
@@ -19,6 +19,7 @@
 
 #include <memory>  // std::shared_ptr
 #include <string>  // std::string
+#include <utility>
 #include <vector>  // std::vector
 
 // clang-format off
@@ -42,70 +43,159 @@ enum LogLevel {
   LOG_LEVEL_LEVEL_NUM = 7
 };
 
-class Logger {
+class LoggerConfig {
  public:
-  static Logger* getLoggerInstance();
+  LoggerConfig(const std::string& name, const std::string& path)
+      : LoggerConfig(name, LOG_LEVEL_INFO, path, 1024 * 1024 * 100, 3) {}
+  LoggerConfig(const std::string& name, LogLevel level, const std::string& path, int file_size, int file_count)
+      : name_(name), level_(level), path_(path), file_size_(file_size), file_count_(file_count) {}
 
  public:
+  inline const std::string& name() const { return name_; }
+  inline void set_name(const std::string& name) { name_ = name; }
+
+  inline LogLevel level() const { return level_; }
+  inline void set_level(LogLevel level) { level_ = level; }
+
+  inline const std::string& path() const { return path_; }
+  inline void set_path(const std::string& path) { path_ = path; }
+
+  inline int file_size() const { return file_size_; }
+  inline void set_file_size(int file_size) { file_size_ = file_size; }
+
+  inline int file_count() const { return file_count_; }
+  inline void set_file_count(int file_count) { file_count_ = file_count; }
+
+  inline bool config_spdlog() const { return config_spdlog_; }
+  inline void set_config_spdlog(bool config_spdlog) { config_spdlog_ = config_spdlog; }
+
+ private:
+  std::string name_;
+  LogLevel level_;
+  std::string path_;
+  int file_size_;
+  int file_count_;
+  bool config_spdlog_{true};
+};
+
+class Logger {
+ public:
+  Logger(const LoggerConfig& config);
+
   virtual ~Logger();
 
-  inline spdlog::logger* getSeverityLogger() { return logger_.get(); }
+  template <typename FormatString, typename... Args>
+  inline void Log(spdlog::source_loc&& location,
+                  spdlog::level::level_enum level,
+                  FormatString&& format,
+                  Args&&... args) {
+    logger_->log(std::forward<spdlog::source_loc>(location), level, format, std::forward<Args>(args)...);
+  }
 
-  void setLogFileNumAndSize(int logNum, int sizeOfPerFile);
+  template <typename FormatString, typename... Args>
+  inline void Trace(spdlog::source_loc&& location, FormatString&& format, Args&&... args) {
+    Log(std::forward<spdlog::source_loc>(location), spdlog::level::trace, std::forward<FormatString>(format),
+        std::forward<Args>(args)...);
+  }
 
-  inline LogLevel log_level() const { return log_level_; }
-  inline void set_log_level(LogLevel log_level) {
-    log_level_ = log_level;
-    set_log_level_(log_level);
+  template <typename FormatString, typename... Args>
+  inline void Debug(spdlog::source_loc&& location, FormatString&& format, Args&&... args) {
+    Log(std::forward<spdlog::source_loc>(location), spdlog::level::debug, std::forward<FormatString>(format),
+        std::forward<Args>(args)...);
   }
 
- private:
-  Logger(const std::string& name);
+  template <typename FormatString, typename... Args>
+  inline void Info(spdlog::source_loc&& location, FormatString&& format, Args&&... args) {
+    Log(std::forward<spdlog::source_loc>(location), spdlog::level::info, std::forward<FormatString>(format),
+        std::forward<Args>(args)...);
+  }
+
+  template <typename FormatString, typename... Args>
+  inline void Warn(spdlog::source_loc&& location, FormatString&& format, Args&&... args) {
+    Log(std::forward<spdlog::source_loc>(location), spdlog::level::warn, std::forward<FormatString>(format),
+        std::forward<Args>(args)...);
+  }
 
-  void init_log_dir_();
-  void init_spdlog_env_();
+  template <typename FormatString, typename... Args>
+  inline void Error(spdlog::source_loc&& location, FormatString&& format, Args&&... args) {
+    Log(std::forward<spdlog::source_loc>(location), spdlog::level::err, std::forward<FormatString>(format),
+        std::forward<Args>(args)...);
+  }
 
-  std::shared_ptr<spdlog::logger> create_rotating_logger_(const std::string& name,
-                                                          const std::string& filepath,
-                                                          std::size_t max_size,
-                                                          std::size_t max_files);
+  template <typename FormatString, typename... Args>
+  inline void Fatal(spdlog::source_loc&& location, FormatString&& format, Args&&... args) {
+    Log(std::forward<spdlog::source_loc>(location), spdlog::level::critical, std::forward<FormatString>(format),
+        std::forward<Args>(args)...);
+  }
 
-  void set_log_level_(LogLevel log_level);
+  template <typename FormatString, typename... Args>
+  inline void Printf(spdlog::source_loc&& location,
+                     spdlog::level::level_enum level,
+                     FormatString&& format,
+                     Args&&... args) {
+    if (logger_->should_log(level)) {
+      std::string message = fmt::sprintf(format, std::forward<Args>(args)...);
+      logger_->log(std::forward<spdlog::source_loc>(location), level, message);
+    }
+  }
 
- private:
-  LogLevel log_level_;
-  std::string log_file_;
+  template <typename FormatString, typename... Args>
+  inline void TracePrintf(spdlog::source_loc&& location, FormatString&& format, Args&&... args) {
+    Printf(std::forward<spdlog::source_loc>(location), spdlog::level::trace, std::forward<FormatString>(format),
+           std::forward<Args>(args)...);
+  }
 
+  template <typename FormatString, typename... Args>
+  inline void DebugPrintf(spdlog::source_loc&& location, FormatString&& format, Args&&... args) {
+    Printf(std::forward<spdlog::source_loc>(location), spdlog::level::debug, std::forward<FormatString>(format),
+           std::forward<Args>(args)...);
+  }
+
+  template <typename FormatString, typename... Args>
+  inline void InfoPrintf(spdlog::source_loc&& location, FormatString&& format, Args&&... args) {
+    Printf(std::forward<spdlog::source_loc>(location), spdlog::level::info, std::forward<FormatString>(format),
+           std::forward<Args>(args)...);
+  }
+
+  template <typename FormatString, typename... Args>
+  inline void WarnPrintf(spdlog::source_loc&& location, FormatString&& format, Args&&... args) {
+    Printf(std::forward<spdlog::source_loc>(location), spdlog::level::warn, std::forward<FormatString>(format),
+           std::forward<Args>(args)...);
+  }
+
+  template <typename FormatString, typename... Args>
+  inline void ErrorPrintf(spdlog::source_loc&& location, FormatString&& format, Args&&... args) {
+    Printf(std::forward<spdlog::source_loc>(location), spdlog::level::err, std::forward<FormatString>(format),
+           std::forward<Args>(args)...);
+  }
+
+  template <typename FormatString, typename... Args>
+  inline void FatalPrintf(spdlog::source_loc&& location, FormatString&& format, Args&&... args) {
+    Printf(std::forward<spdlog::source_loc>(location), spdlog::level::critical, std::forward<FormatString>(format),
+           std::forward<Args>(args)...);
+  }
+
+ private:
   std::shared_ptr<spdlog::logger> logger_;
 };
 
-#define DEFAULT_LOGGER_INSTANCE Logger::getLoggerInstance()
-#define DEFAULT_LOGGER DEFAULT_LOGGER_INSTANCE->getSeverityLogger()
-
-#define SPDLOG_PRINTF(logger, level, format, ...)                        \
-  do {                                                                   \
-    if (logger->should_log(level)) {                                     \
-      std::string message = fmt::sprintf(format, ##__VA_ARGS__);         \
-      logger->log(level, "{} [{}:{}]", message, __FUNCTION__, __LINE__); \
-    }                                                                    \
-  } while (0)
-
-#define LOG_FATAL(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::critical, __VA_ARGS__)
-#define LOG_ERROR(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::err, __VA_ARGS__)
-#define LOG_WARN(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::warn, __VA_ARGS__)
-#define LOG_INFO(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::info, __VA_ARGS__)
-#define LOG_DEBUG(...) SPDLOG_PRINTF(DEFAULT_LOGGER, spdlog::level::debug, __VA_ARGS__)
-
-#define SPDLOG_EXT(logger, level, format, ...)                                    \
-  do {                                                                            \
-    logger->log(level, format " [{}:{}]", ##__VA_ARGS__, __FUNCTION__, __LINE__); \
-  } while (0)
-
-#define LOG_FATAL_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::critical, __VA_ARGS__)
-#define LOG_ERROR_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::err, __VA_ARGS__)
-#define LOG_WARN_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::warn, __VA_ARGS__)
-#define LOG_INFO_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::info, __VA_ARGS__)
-#define LOG_DEBUG_NEW(...) SPDLOG_EXT(DEFAULT_LOGGER, spdlog::level::debug, __VA_ARGS__)
+LoggerConfig& GetDefaultLoggerConfig();
+Logger& GetDefaultLogger();
+
+#define LOG_SOURCE_LOCATION \
+  spdlog::source_loc { __FILE__, __LINE__, SPDLOG_FUNCTION }
+
+#define LOG_FATAL(...) GetDefaultLogger().FatalPrintf(LOG_SOURCE_LOCATION, __VA_ARGS__)
+#define LOG_ERROR(...) GetDefaultLogger().ErrorPrintf(LOG_SOURCE_LOCATION, __VA_ARGS__)
+#define LOG_WARN(...) GetDefaultLogger().WarnPrintf(LOG_SOURCE_LOCATION, __VA_ARGS__)
+#define LOG_INFO(...) GetDefaultLogger().InfoPrintf(LOG_SOURCE_LOCATION, __VA_ARGS__)
+#define LOG_DEBUG(...) GetDefaultLogger().DebugPrintf(LOG_SOURCE_LOCATION, __VA_ARGS__)
+
+#define LOG_FATAL_NEW(...) GetDefaultLogger().Fatal(LOG_SOURCE_LOCATION, __VA_ARGS__)
+#define LOG_ERROR_NEW(...) GetDefaultLogger().Error(LOG_SOURCE_LOCATION, __VA_ARGS__)
+#define LOG_WARN_NEW(...) GetDefaultLogger().Warn(LOG_SOURCE_LOCATION, __VA_ARGS__)
+#define LOG_INFO_NEW(...) GetDefaultLogger().Info(LOG_SOURCE_LOCATION, __VA_ARGS__)
+#define LOG_DEBUG_NEW(...) GetDefaultLogger().Debug(LOG_SOURCE_LOCATION, __VA_ARGS__)
 
 }  // namespace rocketmq