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

laiyingchun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pegasus.git


The following commit(s) were added to refs/heads/master by this push:
     new b39e18b74 refactor(logging): Minor refactor on logging module (#2022)
b39e18b74 is described below

commit b39e18b742e112e2d5abdfa84a3b2a54346a0dab
Author: Yingchun Lai <[email protected]>
AuthorDate: Fri May 24 17:26:00 2024 +0800

    refactor(logging): Minor refactor on logging module (#2022)
    
    Mainly including:
    - Using fmt::format/print instead of sprintf/printf, which is more 
convenient
      and faster
    - Add some configuration validators
    - Encapsulate print_header(), print_long_header() and print_body() for
      screen_logger and simple_logger
    - Add more comments
    - Naming improvment
---
 src/runtime/service_api_c.cpp | 106 ++++++++++++++++------------------
 src/utils/simple_logger.cpp   | 131 ++++++++++++++++++++++++++++++------------
 src/utils/simple_logger.h     |  19 +++++-
 3 files changed, 162 insertions(+), 94 deletions(-)

diff --git a/src/runtime/service_api_c.cpp b/src/runtime/service_api_c.cpp
index f2195f95a..fb4e5154e 100644
--- a/src/runtime/service_api_c.cpp
+++ b/src/runtime/service_api_c.cpp
@@ -76,6 +76,7 @@
 #include "utils/join_point.h"
 #include "utils/logging_provider.h"
 #include "utils/process_utils.h"
+#include "utils/string_conv.h"
 #include "utils/strings.h"
 #include "utils/sys_exit_hook.h"
 #include "utils/threadpool_spec.h"
@@ -343,45 +344,29 @@ inline void dsn_global_init()
 
 static std::string dsn_log_prefixed_message_func()
 {
-    std::string res;
-    res.resize(100);
-    char *prefixed_message = const_cast<char *>(res.c_str());
-
-    int tid = dsn::utils::get_current_tid();
-    auto t = dsn::task::get_current_task_id();
+    const int tid = dsn::utils::get_current_tid();
+    const auto t = dsn::task::get_current_task_id();
     if (t) {
         if (nullptr != dsn::task::get_current_worker2()) {
-            sprintf(prefixed_message,
-                    "%6s.%7s%d.%016" PRIx64 ": ",
-                    dsn::task::get_current_node_name(),
-                    dsn::task::get_current_worker2()->pool_spec().name.c_str(),
-                    dsn::task::get_current_worker2()->index(),
-                    t);
+            return fmt::format("{}.{}{}.{:016}: ",
+                               dsn::task::get_current_node_name(),
+                               
dsn::task::get_current_worker2()->pool_spec().name,
+                               dsn::task::get_current_worker2()->index(),
+                               t);
         } else {
-            sprintf(prefixed_message,
-                    "%6s.%7s.%05d.%016" PRIx64 ": ",
-                    dsn::task::get_current_node_name(),
-                    "io-thrd",
-                    tid,
-                    t);
+            return fmt::format(
+                "{}.io-thrd.{}.{:016}: ", dsn::task::get_current_node_name(), 
tid, t);
         }
     } else {
         if (nullptr != dsn::task::get_current_worker2()) {
-            sprintf(prefixed_message,
-                    "%6s.%7s%u: ",
-                    dsn::task::get_current_node_name(),
-                    dsn::task::get_current_worker2()->pool_spec().name.c_str(),
-                    dsn::task::get_current_worker2()->index());
+            return fmt::format("{}.{}{}: ",
+                               dsn::task::get_current_node_name(),
+                               
dsn::task::get_current_worker2()->pool_spec().name,
+                               dsn::task::get_current_worker2()->index());
         } else {
-            sprintf(prefixed_message,
-                    "%6s.%7s.%05d: ",
-                    dsn::task::get_current_node_name(),
-                    "io-thrd",
-                    tid);
+            return fmt::format("{}.io-thrd.{}: ", 
dsn::task::get_current_node_name(), tid);
         }
     }
-
-    return res;
 }
 
 bool run(const char *config_file,
@@ -457,14 +442,14 @@ bool run(const char *config_file,
     }
     dsn::utils::filesystem::create_directory(spec.log_dir);
 
-    // init tools
+    // Initialize tools.
     
dsn_all.tool.reset(::dsn::utils::factory_store<::dsn::tools::tool_app>::create(
         spec.tool.c_str(), ::dsn::PROVIDER_TYPE_MAIN, spec.tool.c_str()));
     dsn_all.tool->install(spec);
 
-    // init app specs
+    // Initialize app specs.
     if (!spec.init_app_specs()) {
-        printf("error in config file %s, exit ...\n", config_file);
+        fmt::print(stderr, "error in config file {}, exit ...\n", config_file);
         return false;
     }
 
@@ -475,7 +460,7 @@ bool run(const char *config_file,
     // init logging
     dsn_log_init(spec.logging_factory_name, spec.log_dir, 
dsn_log_prefixed_message_func);
 
-    // prepare minimum necessary
+    // Prepare the minimum necessary.
     ::dsn::service_engine::instance().init_before_toollets(spec);
 
     LOG_INFO("process({}) start: {}, date: {}",
@@ -483,10 +468,10 @@ bool run(const char *config_file,
              dsn::utils::process_start_millis(),
              dsn::utils::process_start_date_time_mills());
 
-    // init toollets
-    for (auto it = spec.toollets.begin(); it != spec.toollets.end(); ++it) {
-        auto tlet =
-            dsn::tools::internal_use_only::get_toollet(it->c_str(), 
::dsn::PROVIDER_TYPE_MAIN);
+    // Initialize toollets.
+    for (const auto &toollet_name : spec.toollets) {
+        auto tlet = 
dsn::tools::internal_use_only::get_toollet(toollet_name.c_str(),
+                                                               
::dsn::PROVIDER_TYPE_MAIN);
         CHECK_NOTNULL(tlet, "toolet not found");
         tlet->install(spec);
     }
@@ -517,29 +502,37 @@ bool run(const char *config_file,
         }
     }
 
-    // split app_name and app_index
-    std::list<std::string> applistkvs;
-    ::dsn::utils::split_args(app_list.c_str(), applistkvs, ';');
-
     // init apps
     for (auto &sp : spec.app_specs) {
-        if (!sp.run)
+        if (!sp.run) {
             continue;
+        }
 
         bool create_it = false;
-
         // create all apps
-        if (app_list == "") {
+        if (app_list.empty()) {
             create_it = true;
         } else {
-            for (auto &kv : applistkvs) {
-                std::list<std::string> argskvs;
-                ::dsn::utils::split_args(kv.c_str(), argskvs, '@');
-                if (std::string("apps.") + argskvs.front() == 
sp.config_section) {
-                    if (argskvs.size() < 2)
+            // Extract app_names.
+            std::list<std::string> app_names_and_indexes;
+            ::dsn::utils::split_args(app_list.c_str(), app_names_and_indexes, 
';');
+            for (const auto &app_name_and_index : app_names_and_indexes) {
+                std::vector<std::string> name_and_index;
+                ::dsn::utils::split_args(app_name_and_index.c_str(), 
name_and_index, '@');
+                CHECK(!name_and_index.empty(),
+                      "app_name should be specified in '{}'",
+                      app_name_and_index);
+                if (std::string("apps.") + name_and_index.front() == 
sp.config_section) {
+                    if (name_and_index.size() < 2) {
                         create_it = true;
-                    else
-                        create_it = (std::stoi(argskvs.back()) == sp.index);
+                    } else {
+                        int32_t index = 0;
+                        const auto index_str = name_and_index.back();
+                        CHECK(dsn::buf2int32(index_str, index),
+                              "'{}' is not a valid index",
+                              index_str);
+                        create_it = (index == sp.index);
+                    }
                     break;
                 }
             }
@@ -550,10 +543,11 @@ bool run(const char *config_file,
         }
     }
 
-    if (dsn::service_engine::instance().get_all_nodes().size() == 0) {
-        printf("no app are created, usually because \n"
-               "app_name is not specified correctly, should be 'xxx' in 
[apps.xxx]\n"
-               "or app_index (1-based) is greater than specified count in 
config file\n");
+    if (dsn::service_engine::instance().get_all_nodes().empty()) {
+        fmt::print(stderr,
+                   "no app are created, usually because \n"
+                   "app_name is not specified correctly, should be 'xxx' in 
[apps.xxx]\n"
+                   "or app_index (1-based) is greater than specified count in 
config file\n");
         exit(1);
     }
 
diff --git a/src/utils/simple_logger.cpp b/src/utils/simple_logger.cpp
index d54e03025..0234cee6f 100644
--- a/src/utils/simple_logger.cpp
+++ b/src/utils/simple_logger.cpp
@@ -28,10 +28,11 @@
 
 // IWYU pragma: no_include <ext/alloc_traits.h>
 #include <fmt/core.h>
-#include <stdint.h>
+#include <fmt/printf.h>
+#include <cstdint>
 #include <functional>
 #include <memory>
-#include <sstream>
+#include <ostream>
 #include <vector>
 
 #include "absl/strings/string_view.h"
@@ -44,7 +45,6 @@
 #include "utils/ports.h"
 #include "utils/process_utils.h"
 #include "utils/string_conv.h"
-#include "utils/strings.h"
 #include "utils/time_utils.h"
 
 DSN_DEFINE_bool(tools.simple_logger, fast_flush, false, "Whether to flush logs 
immediately");
@@ -60,23 +60,27 @@ DSN_DEFINE_uint64(
     max_number_of_log_files_on_disk,
     20,
     "The maximum number of log files to be reserved on disk, older logs are 
deleted automatically");
+DSN_DEFINE_validator(max_number_of_log_files_on_disk,
+                     [](int32_t value) -> bool { return value > 0; });
 
 DSN_DEFINE_string(
     tools.simple_logger,
     stderr_start_level,
     "LOG_LEVEL_WARNING",
     "The lowest level of log messages to be copied to stderr in addition to 
log files");
-DSN_DEFINE_validator(stderr_start_level, [](const char *level) -> bool {
-    return !dsn::utils::equals(level, "LOG_LEVEL_INVALID");
+DSN_DEFINE_validator(stderr_start_level, [](const char *value) -> bool {
+    const auto level = enum_from_string(value, LOG_LEVEL_INVALID);
+    return LOG_LEVEL_DEBUG <= level && level <= LOG_LEVEL_FATAL;
 });
 
 DSN_DECLARE_string(logging_start_level);
 
 namespace dsn {
 namespace tools {
-static void print_header(FILE *fp, log_level_t log_level)
+namespace {
+int print_header(FILE *fp, log_level_t stderr_start_level, log_level_t 
log_level)
 {
-    // The leading character of each log lines, corresponding to the log level
+    // The leading character of each log line, corresponding to the log level
     // D: Debug
     // I: Info
     // W: Warning
@@ -89,16 +93,43 @@ static void print_header(FILE *fp, log_level_t log_level)
     dsn::utils::time_ms_to_string(ts / 1000000, time_str);
 
     int tid = dsn::utils::get_current_tid();
-    fmt::print(fp,
-               "{}{} ({} {}) {}",
-               s_level_char[log_level],
-               time_str,
-               ts,
-               tid,
-               log_prefixed_message_func().c_str());
+    const auto header = fmt::format(
+        "{}{} ({} {}) {}", s_level_char[log_level], time_str, ts, tid, 
log_prefixed_message_func());
+    const int written_size = fmt::fprintf(fp, "%s", header.c_str());
+    if (log_level >= stderr_start_level) {
+        fmt::fprintf(stderr, "%s", header.c_str());
+    }
+    return written_size;
 }
 
-namespace {
+int print_long_header(FILE *fp,
+                      const char *file,
+                      const char *function,
+                      const int line,
+                      bool short_header,
+                      log_level_t stderr_start_level,
+                      log_level_t log_level)
+{
+    if (short_header) {
+        return 0;
+    }
+
+    const auto long_header = fmt::format("{}:{}:{}(): ", file, line, function);
+    const int written_size = fmt::fprintf(fp, "%s", long_header.c_str());
+    if (log_level >= stderr_start_level) {
+        fmt::fprintf(stderr, "%s", long_header.c_str());
+    }
+    return written_size;
+}
+
+int print_body(FILE *fp, const char *body, log_level_t stderr_start_level, 
log_level_t log_level)
+{
+    const int written_size = fmt::fprintf(fp, "%s\n", body);
+    if (log_level >= stderr_start_level) {
+        fmt::fprintf(stderr, "%s\n", body);
+    }
+    return written_size;
+}
 
 inline void process_fatal_log(log_level_t log_level)
 {
@@ -122,19 +153,33 @@ inline void process_fatal_log(log_level_t log_level)
 
 screen_logger::screen_logger(bool short_header) : _short_header(short_header) 
{}
 
-screen_logger::~screen_logger(void) {}
+void screen_logger::print_header(log_level_t log_level)
+{
+    ::dsn::tools::print_header(stdout, LOG_LEVEL_COUNT, log_level);
+}
+
+void screen_logger::print_long_header(const char *file,
+                                      const char *function,
+                                      const int line,
+                                      log_level_t log_level)
+{
+    ::dsn::tools::print_long_header(
+        stdout, file, function, line, _short_header, LOG_LEVEL_COUNT, 
log_level);
+}
+
+void screen_logger::print_body(const char *body, log_level_t log_level)
+{
+    ::dsn::tools::print_body(stdout, body, LOG_LEVEL_COUNT, log_level);
+}
 
 void screen_logger::log(
     const char *file, const char *function, const int line, log_level_t 
log_level, const char *str)
 {
     utils::auto_lock<::dsn::utils::ex_lock_nr> l(_lock);
 
-    print_header(stdout, log_level);
-    if (!_short_header) {
-        printf("%s:%d:%s(): ", file, line, function);
-    }
-    printf("%s\n", str);
-
+    print_header(log_level);
+    print_long_header(file, function, line, log_level);
+    print_body(str, log_level);
     if (log_level >= LOG_LEVEL_ERROR) {
         ::fflush(stdout);
     }
@@ -222,8 +267,10 @@ simple_logger::simple_logger(const char *log_dir)
 
 void simple_logger::create_log_file()
 {
+    // Close the current log file if it is opened.
     if (_log != nullptr) {
         ::fclose(_log);
+        _log = nullptr;
     }
 
     _lines = 0;
@@ -246,41 +293,53 @@ void simple_logger::create_log_file()
     }
 }
 
-simple_logger::~simple_logger(void)
+simple_logger::~simple_logger()
 {
     utils::auto_lock<::dsn::utils::ex_lock> l(_lock);
     ::fclose(_log);
+    _log = nullptr;
 }
 
 void simple_logger::flush()
 {
     utils::auto_lock<::dsn::utils::ex_lock> l(_lock);
     ::fflush(_log);
+    ::fflush(stderr);
     ::fflush(stdout);
 }
 
+void simple_logger::print_header(log_level_t log_level)
+{
+    ::dsn::tools::print_header(_log, _stderr_start_level, log_level);
+}
+
+void simple_logger::print_long_header(const char *file,
+                                      const char *function,
+                                      const int line,
+                                      log_level_t log_level)
+{
+    ::dsn::tools::print_long_header(
+        _log, file, function, line, FLAGS_short_header, _stderr_start_level, 
log_level);
+}
+
+void simple_logger::print_body(const char *body, log_level_t log_level)
+{
+    ::dsn::tools::print_body(_log, body, _stderr_start_level, log_level);
+}
+
 void simple_logger::log(
     const char *file, const char *function, const int line, log_level_t 
log_level, const char *str)
 {
     utils::auto_lock<::dsn::utils::ex_lock> l(_lock);
 
-    print_header(_log, log_level);
-    if (!FLAGS_short_header) {
-        fprintf(_log, "%s:%d:%s(): ", file, line, function);
-    }
-    fprintf(_log, "%s\n", str);
+    CHECK_NOTNULL(_log, "Log file hasn't been initialized yet");
+    print_header(log_level);
+    print_long_header(file, function, line, log_level);
+    print_body(str, log_level);
     if (FLAGS_fast_flush || log_level >= LOG_LEVEL_ERROR) {
         ::fflush(_log);
     }
 
-    if (log_level >= _stderr_start_level) {
-        print_header(stdout, log_level);
-        if (!FLAGS_short_header) {
-            printf("%s:%d:%s(): ", file, line, function);
-        }
-        printf("%s\n", str);
-    }
-
     process_fatal_log(log_level);
 
     if (++_lines >= 200000) {
diff --git a/src/utils/simple_logger.h b/src/utils/simple_logger.h
index e9657a801..7da324139 100644
--- a/src/utils/simple_logger.h
+++ b/src/utils/simple_logger.h
@@ -43,7 +43,7 @@ class screen_logger : public logging_provider
 {
 public:
     explicit screen_logger(bool short_header);
-    ~screen_logger() override;
+    ~screen_logger() override = default;
 
     void log(const char *file,
              const char *function,
@@ -54,6 +54,13 @@ public:
     virtual void flush();
 
 private:
+    static void print_header(log_level_t log_level);
+    void print_long_header(const char *file,
+                           const char *function,
+                           const int line,
+                           log_level_t log_level);
+    static void print_body(const char *body, log_level_t log_level);
+
     ::dsn::utils::ex_lock_nr _lock;
     const bool _short_header;
 };
@@ -77,17 +84,25 @@ public:
     void flush() override;
 
 private:
+    void print_header(log_level_t log_level);
+    void print_long_header(const char *file,
+                           const char *function,
+                           const int line,
+                           log_level_t log_level);
+    void print_body(const char *body, log_level_t log_level);
+
     void create_log_file();
 
 private:
     ::dsn::utils::ex_lock _lock; // use recursive lock to avoid dead lock when 
flush() is called
                                  // in signal handler if cored for bad logging 
format reason.
+    // The directory to store log files.
     const std::string _log_dir;
     FILE *_log;
     int _start_index;
     int _index;
     int _lines;
-    log_level_t _stderr_start_level;
+    const log_level_t _stderr_start_level;
 };
 } // namespace tools
 } // namespace dsn


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to