You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pegasus.apache.org by la...@apache.org on 2022/11/24 03:59:40 UTC

[incubator-pegasus] branch master updated: refactor: enable build warning on unused result (#1248)

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 d54e05fb7 refactor: enable build warning on unused result (#1248)
d54e05fb7 is described below

commit d54e05fb78554dfc508fe156bb80dd867e36c50f
Author: Yingchun Lai <la...@apache.org>
AuthorDate: Thu Nov 24 11:59:34 2022 +0800

    refactor: enable build warning on unused result (#1248)
---
 cmake_modules/BaseFunctions.cmake                  |  1 -
 src/block_service/directio_writable_file.cpp       | 63 +++++++++++----
 src/block_service/directio_writable_file.h         |  2 +
 src/block_service/test/fds_service_test.cpp        | 11 ++-
 src/perf_counter/perf_counters.cpp                 | 80 +++++++++++++++++--
 src/runtime/service_api_c.cpp                      | 41 +++++-----
 src/runtime/task/task_code.cpp                     | 29 +++++++
 src/runtime/task/task_spec.cpp                     | 25 ------
 src/runtime/tracer.cpp                             | 32 ++++----
 src/runtime/tracer.h                               | 23 +++---
 src/server/brief_stat.cpp                          | 89 ----------------------
 src/server/brief_stat.h                            | 24 ------
 src/server/main.cpp                                | 34 ++++-----
 .../function_test/restore_test/test_restore.cpp    |  2 +-
 src/test/function_test/utils/test_util.cpp         |  2 +-
 src/test/kill_test/process_kill_testor.cpp         |  7 +-
 src/utils/command_manager.cpp                      |  9 ++-
 src/utils/command_manager.h                        | 10 +--
 src/utils/customizable_id.h                        | 16 ++--
 src/utils/logging.cpp                              | 46 ++---------
 src/utils/logging_provider.h                       | 24 +++---
 src/utils/ports.h                                  |  9 +++
 src/utils/simple_logger.cpp                        | 47 ++++++++++--
 src/utils/simple_logger.h                          | 37 ++++-----
 src/utils/test/logger.cpp                          | 77 +++++++++----------
 25 files changed, 368 insertions(+), 372 deletions(-)

diff --git a/cmake_modules/BaseFunctions.cmake b/cmake_modules/BaseFunctions.cmake
index a301d87ff..359e7a79a 100644
--- a/cmake_modules/BaseFunctions.cmake
+++ b/cmake_modules/BaseFunctions.cmake
@@ -213,7 +213,6 @@ function(dsn_setup_compiler_flags)
   add_compile_options(-Wno-sign-compare)
   add_compile_options(-Wno-strict-aliasing)
   add_compile_options(-Wuninitialized)
-  add_compile_options(-Wno-unused-result)
   add_compile_options(-Wno-unused-variable)
   add_compile_options(-Wno-deprecated-declarations)
   add_compile_options(-Wno-inconsistent-missing-override)
diff --git a/src/block_service/directio_writable_file.cpp b/src/block_service/directio_writable_file.cpp
index bf42c2d07..f6b29fe68 100644
--- a/src/block_service/directio_writable_file.cpp
+++ b/src/block_service/directio_writable_file.cpp
@@ -15,6 +15,8 @@
 // specific language governing permissions and limitations
 // under the License.
 
+#include "block_service/directio_writable_file.h"
+
 #include <algorithm>
 #include <cstring>
 #include <fcntl.h>
@@ -24,10 +26,9 @@
 #include <sys/types.h>
 #include <unistd.h> // getpagesize
 
-#include "utils/fmt_logging.h"
 #include "utils/flags.h"
-
-#include "block_service/directio_writable_file.h"
+#include "utils/fmt_logging.h"
+#include "utils/safe_strerror_posix.h"
 
 namespace dsn {
 namespace dist {
@@ -65,14 +66,15 @@ direct_io_writable_file::~direct_io_writable_file()
     // Here is an ensurance, users shuold call finalize manually
     CHECK_EQ_MSG(_offset, 0, "finalize() should be called before destructor");
 
-    free(_buffer);
-    close(_fd);
+    ::free(_buffer);
+    CHECK_EQ_MSG(
+        0, ::close(_fd), "Failed to close {}, err = {}", _file_path, utils::safe_strerror(errno));
 }
 
 bool direct_io_writable_file::initialize()
 {
     if (posix_memalign(&_buffer, g_page_size, _buffer_size) != 0) {
-        LOG_ERROR_F("Allocate memaligned buffer failed, errno = {}", errno);
+        LOG_ERROR_F("Allocate memaligned buffer failed, err = {}", utils::safe_strerror(errno));
         return false;
     }
 
@@ -80,10 +82,15 @@ bool direct_io_writable_file::initialize()
 #if !defined(__APPLE__)
     flag |= O_DIRECT;
 #endif
-    _fd = open(_file_path.c_str(), flag, S_IRUSR | S_IWUSR | S_IRGRP);
+    // TODO(yingchun): there maybe serious error of the disk driver when these system call failed,
+    // maybe just terminate the process or mark the disk as failed would be better
+    _fd = ::open(_file_path.c_str(), flag, S_IRUSR | S_IWUSR | S_IRGRP);
     if (_fd < 0) {
-        LOG_ERROR_F("Failed to open {} with flag {}, errno = {}", _file_path, flag, errno);
-        free(_buffer);
+        LOG_ERROR_F("Failed to open {} with flag {}, err = {}",
+                    _file_path,
+                    flag,
+                    utils::safe_strerror(errno));
+        ::free(_buffer);
         _buffer = nullptr;
         return false;
     }
@@ -95,13 +102,27 @@ bool direct_io_writable_file::finalize()
     CHECK(_buffer && _fd >= 0, "Initialize the instance first");
 
     if (_offset > 0) {
-        if (::write(_fd, _buffer, _buffer_size) != _buffer_size) {
-            LOG_ERROR_F(
-                "Failed to write last chunk, filie_path = {}, errno = {}", _file_path, errno);
+        ssize_t written_bytes = ::write(_fd, _buffer, _buffer_size);
+        if (dsn_unlikely(written_bytes < 0)) {
+            LOG_ERROR_F("Failed to write the last chunk, file_path = {}, err = {}",
+                        _file_path,
+                        utils::safe_strerror(errno));
+            return false;
+        }
+        // TODO(yingchun): would better to retry
+        if (dsn_unlikely(written_bytes != _buffer_size)) {
+            LOG_ERROR_F("Failed to write the last chunk, file_path = {}, data bytes = {}, written "
+                        "bytes = {}",
+                        _file_path,
+                        _buffer_size,
+                        written_bytes);
             return false;
         }
         _offset = 0;
-        ftruncate(_fd, _file_size);
+        if (::ftruncate(_fd, _file_size) < 0) {
+            LOG_ERROR_F("Failed to truncate {}, err = {}", _file_path, utils::safe_strerror(errno));
+            return false;
+        }
     }
     return true;
 }
@@ -119,8 +140,20 @@ bool direct_io_writable_file::write(const char *s, size_t n)
         s += bytes;
         // buffer is full, flush to file
         if (_offset == _buffer_size) {
-            if (::write(_fd, _buffer, _buffer_size) != _buffer_size) {
-                LOG_ERROR_F("Failed to write to direct_io_writable_file, errno = {}", errno);
+            ssize_t written_bytes = ::write(_fd, _buffer, _buffer_size);
+            if (dsn_unlikely(written_bytes < 0)) {
+                LOG_ERROR_F("Failed to write chunk, file_path = {}, err = {}",
+                            _file_path,
+                            utils::safe_strerror(errno));
+                return false;
+            }
+            // TODO(yingchun): would better to retry
+            if (dsn_unlikely(written_bytes != _buffer_size)) {
+                LOG_ERROR_F(
+                    "Failed to write chunk, file_path = {}, data bytes = {}, written bytes = {}",
+                    _file_path,
+                    _buffer_size,
+                    written_bytes);
                 return false;
             }
             // reset offset
diff --git a/src/block_service/directio_writable_file.h b/src/block_service/directio_writable_file.h
index b690f13f6..d39134278 100644
--- a/src/block_service/directio_writable_file.h
+++ b/src/block_service/directio_writable_file.h
@@ -19,6 +19,8 @@
 
 #include <string>
 
+#include "utils/ports.h"
+
 namespace dsn {
 namespace dist {
 namespace block_service {
diff --git a/src/block_service/test/fds_service_test.cpp b/src/block_service/test/fds_service_test.cpp
index aacb1262a..8d939fb7e 100644
--- a/src/block_service/test/fds_service_test.cpp
+++ b/src/block_service/test/fds_service_test.cpp
@@ -28,6 +28,7 @@
 #include "utils/fmt_logging.h"
 #include "utils/filesystem.h"
 #include "utils/rand.h"
+#include "utils/safe_strerror_posix.h"
 #include "utils/utils.h"
 
 using namespace dsn;
@@ -634,8 +635,8 @@ TEST_F(FDSClientTest, test_basic_operation)
 static void
 generate_file(const char *filename, unsigned long long file_size, char *block, unsigned block_size)
 {
-    int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-    ASSERT_TRUE(fd > 0) << strerror(errno) << std::endl;
+    int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+    ASSERT_GT(fd, 0) << utils::safe_strerror(errno);
     for (unsigned long long i = 0; i < file_size;) {
         int batch_size = (file_size - i);
         if (batch_size > block_size)
@@ -645,9 +646,11 @@ generate_file(const char *filename, unsigned long long file_size, char *block, u
         for (int j = 0; j < batch_size; ++j) {
             block[j] = (char)rand::next_u32(0, 255);
         }
-        write(fd, block, batch_size);
+        ASSERT_EQ(batch_size, ::write(fd, block, batch_size))
+            << "write file " << filename << " failed, err = " << utils::safe_strerror(errno);
     }
-    close(fd);
+    ASSERT_EQ(0, ::close(fd)) << "close file " << filename
+                              << " failed, err = " << utils::safe_strerror(errno);
 }
 
 TEST_F(FDSClientTest, test_concurrent_upload_download)
diff --git a/src/perf_counter/perf_counters.cpp b/src/perf_counter/perf_counters.cpp
index 5bbceb6d3..afe910978 100644
--- a/src/perf_counter/perf_counters.cpp
+++ b/src/perf_counter/perf_counters.cpp
@@ -24,15 +24,16 @@
  * THE SOFTWARE.
  */
 
-#include <regex>
+#include "perf_counters.h"
 
-#include "perf_counter.h"
+#include <iomanip>
+#include <regex>
 
 #include "builtin_counters.h"
 #include "common/json_helper.h"
-#include "perf_counter_atomic.h"
-#include "perf_counter_utils.h"
-#include "perf_counters.h"
+#include "perf_counter/perf_counter_atomic.h"
+#include "perf_counter/perf_counter_utils.h"
+#include "perf_counter/perf_counter.h"
 #include "runtime/service_app.h"
 #include "runtime/service_engine.h"
 #include "runtime/task/task.h"
@@ -42,6 +43,69 @@
 
 namespace dsn {
 
+namespace {
+std::map<std::string, std::string> s_brief_stat_map = {
+    {"zion*profiler*RPC_RRDB_RRDB_GET.qps", "get_qps"},
+    {"zion*profiler*RPC_RRDB_RRDB_GET.latency.server", "get_p99(ns)"},
+    {"zion*profiler*RPC_RRDB_RRDB_MULTI_GET.qps", "multi_get_qps"},
+    {"zion*profiler*RPC_RRDB_RRDB_MULTI_GET.latency.server", "multi_get_p99(ns)"},
+    {"zion*profiler*RPC_RRDB_RRDB_BATCH_GET.qps", "batch_get_qps"},
+    {"zion*profiler*RPC_RRDB_RRDB_BATCH_GET.latency.server", "batch_get_p99(ns)"},
+    {"zion*profiler*RPC_RRDB_RRDB_PUT.qps", "put_qps"},
+    {"zion*profiler*RPC_RRDB_RRDB_PUT.latency.server", "put_p99(ns)"},
+    {"zion*profiler*RPC_RRDB_RRDB_MULTI_PUT.qps", "multi_put_qps"},
+    {"zion*profiler*RPC_RRDB_RRDB_MULTI_PUT.latency.server", "multi_put_p99(ns)"},
+    {"replica*eon.replica_stub*replica(Count)", "serving_replica_count"},
+    {"replica*eon.replica_stub*opening.replica(Count)", "opening_replica_count"},
+    {"replica*eon.replica_stub*closing.replica(Count)", "closing_replica_count"},
+    {"replica*eon.replica_stub*replicas.commit.qps", "commit_throughput"},
+    {"replica*eon.replica_stub*replicas.learning.count", "learning_count"},
+    {"replica*app.pegasus*manual.compact.running.count", "manual_compact_running_count"},
+    {"replica*app.pegasus*manual.compact.enqueue.count", "manual_compact_enqueue_count"},
+    {"replica*app.pegasus*rdb.block_cache.memory_usage", "rdb_block_cache_memory_usage"},
+    {"replica*eon.replica_stub*shared.log.size(MB)", "shared_log_size(MB)"},
+    {"replica*server*memused.virt(MB)", "memused_virt(MB)"},
+    {"replica*server*memused.res(MB)", "memused_res(MB)"},
+    {"replica*eon.replica_stub*disk.capacity.total(MB)", "disk_capacity_total(MB)"},
+    {"replica*eon.replica_stub*disk.available.total.ratio", "disk_available_total_ratio"},
+    {"replica*eon.replica_stub*disk.available.min.ratio", "disk_available_min_ratio"},
+    {"replica*eon.replica_stub*disk.available.max.ratio", "disk_available_max_ratio"},
+};
+
+std::string get_brief_stat()
+{
+    std::vector<std::string> stat_counters;
+    for (const auto &kv : s_brief_stat_map) {
+        stat_counters.push_back(kv.first);
+    }
+
+    std::ostringstream oss;
+    oss << std::fixed << std::setprecision(0);
+    bool first_item = true;
+    dsn::perf_counters::snapshot_iterator iter =
+        [&oss, &first_item](const dsn::perf_counters::counter_snapshot &cs) mutable {
+            if (!first_item)
+                oss << ", ";
+            oss << s_brief_stat_map.find(cs.name)->second << "=" << cs.value;
+            first_item = false;
+        };
+    std::vector<bool> match_result;
+    dsn::perf_counters::instance().query_snapshot(stat_counters, iter, &match_result);
+
+    CHECK_EQ(stat_counters.size(), match_result.size());
+    for (int i = 0; i < match_result.size(); ++i) {
+        if (!match_result[i]) {
+            if (!first_item)
+                oss << ", ";
+            oss << stat_counters[i] << "=not_found";
+            first_item = false;
+        }
+    }
+    return oss.str();
+}
+
+} // anonymous namespace
+
 perf_counters::perf_counters()
 {
     // make shared_io_service destructed after perf_counters,
@@ -91,6 +155,12 @@ perf_counters::perf_counters()
                                     arg.size()) == 0;
                 });
         }));
+
+    _cmds.emplace_back(command_manager::instance().register_command(
+        {"server-stat"},
+        "server-stat - query selected perf counters",
+        "server-stat",
+        [](const std::vector<std::string> &args) { return get_brief_stat(); }));
 }
 
 perf_counters::~perf_counters()
diff --git a/src/runtime/service_api_c.cpp b/src/runtime/service_api_c.cpp
index 2c23899da..e2ecd55d5 100644
--- a/src/runtime/service_api_c.cpp
+++ b/src/runtime/service_api_c.cpp
@@ -80,6 +80,8 @@ static struct _all_info_
 
 } dsn_all;
 
+std::unique_ptr<dsn::command_deregister> dump_log_cmd;
+
 volatile int *dsn_task_queue_virtual_length_ptr(dsn::task_code code, int hash)
 {
     return dsn::task::get_current_node()->computation()->get_task_queue_virtual_length_ptr(code,
@@ -181,6 +183,8 @@ bool dsn_run_config(const char *config, bool is_server)
 
 [[noreturn]] void dsn_exit(int code)
 {
+    dump_log_cmd.reset();
+
     printf("dsn exit with code %d\n", code);
     fflush(stdout);
     ::dsn::tools::sys_exit.execute(::dsn::SYS_EXIT_NORMAL);
@@ -510,24 +514,25 @@ bool run(const char *config_file,
         exit(1);
     }
 
-    dsn::command_manager::instance().register_command({"config-dump"},
-                                                      "config-dump - dump configuration",
-                                                      "config-dump [to-this-config-file]",
-                                                      [](const std::vector<std::string> &args) {
-                                                          std::ostringstream oss;
-                                                          std::ofstream off;
-                                                          std::ostream *os = &oss;
-                                                          if (args.size() > 0) {
-                                                              off.open(args[0]);
-                                                              os = &off;
-
-                                                              oss << "config dump to file "
-                                                                  << args[0] << std::endl;
-                                                          }
-
-                                                          dsn_config_dump(*os);
-                                                          return oss.str();
-                                                      });
+    dump_log_cmd =
+        dsn::command_manager::instance().register_command({"config-dump"},
+                                                          "config-dump - dump configuration",
+                                                          "config-dump [to-this-config-file]",
+                                                          [](const std::vector<std::string> &args) {
+                                                              std::ostringstream oss;
+                                                              std::ofstream off;
+                                                              std::ostream *os = &oss;
+                                                              if (args.size() > 0) {
+                                                                  off.open(args[0]);
+                                                                  os = &off;
+
+                                                                  oss << "config dump to file "
+                                                                      << args[0] << std::endl;
+                                                              }
+
+                                                              dsn_config_dump(*os);
+                                                              return oss.str();
+                                                          });
 
     // invoke customized init after apps are created
     dsn::tools::sys_init_after_app_created.execute();
diff --git a/src/runtime/task/task_code.cpp b/src/runtime/task/task_code.cpp
index 06cd3b0ac..b39c5ec46 100644
--- a/src/runtime/task/task_code.cpp
+++ b/src/runtime/task/task_code.cpp
@@ -33,6 +33,35 @@ namespace dsn {
 
 typedef dsn::utils::customized_id_mgr<dsn::task_code> task_code_mgr;
 
+template <>
+void task_code_mgr::register_commands()
+{
+    _cmds.emplace_back(command_manager::instance().register_command(
+        {"task-code"},
+        "task-code - query task code containing any given keywords",
+        "task-code keyword1 keyword2 ...",
+        [](const std::vector<std::string> &args) {
+            std::stringstream ss;
+
+            for (int code = 0; code <= dsn::task_code::max(); code++) {
+                if (code == TASK_CODE_INVALID)
+                    continue;
+
+                std::string codes = dsn::task_code(code).to_string();
+                if (args.size() == 0) {
+                    ss << "    " << codes << std::endl;
+                } else {
+                    for (auto &arg : args) {
+                        if (codes.find(arg.c_str()) != std::string::npos) {
+                            ss << "    " << codes << std::endl;
+                        }
+                    }
+                }
+            }
+            return ss.str();
+        }));
+}
+
 /*static*/
 int task_code::max() { return task_code_mgr::instance().max_value(); }
 
diff --git a/src/runtime/task/task_spec.cpp b/src/runtime/task/task_spec.cpp
index d34df2a68..3a9d21818 100644
--- a/src/runtime/task/task_spec.cpp
+++ b/src/runtime/task/task_spec.cpp
@@ -226,31 +226,6 @@ bool task_spec::init()
         }
     }
 
-    ::dsn::command_manager::instance().register_command(
-        {"task-code"},
-        "task-code - query task code containing any given keywords",
-        "task-code keyword1 keyword2 ...",
-        [](const std::vector<std::string> &args) {
-            std::stringstream ss;
-
-            for (int code = 0; code <= dsn::task_code::max(); code++) {
-                if (code == TASK_CODE_INVALID)
-                    continue;
-
-                std::string codes = dsn::task_code(code).to_string();
-                if (args.size() == 0) {
-                    ss << "    " << codes << std::endl;
-                } else {
-                    for (auto &arg : args) {
-                        if (codes.find(arg.c_str()) != std::string::npos) {
-                            ss << "    " << codes << std::endl;
-                        }
-                    }
-                }
-            }
-            return ss.str();
-        });
-
     return true;
 }
 
diff --git a/src/runtime/tracer.cpp b/src/runtime/tracer.cpp
index 6a096c779..ba142c1cb 100644
--- a/src/runtime/tracer.cpp
+++ b/src/runtime/tracer.cpp
@@ -24,19 +24,11 @@
  * THE SOFTWARE.
  */
 
-/*
- * Description:
- *     What is this file about?
- *
- * Revision history:
- *     xxxx-xx-xx, author, first version
- *     xxxx-xx-xx, author, fix bug about xxx
- */
-
 #include "runtime/tracer.h"
+
+#include "aio/aio_task.h"
 #include "utils/filesystem.h"
 #include "utils/command_manager.h"
-#include "aio/aio_task.h"
 
 namespace dsn {
 namespace tools {
@@ -396,14 +388,18 @@ void tracer::install(service_spec &spec)
             spec->on_rpc_create_response.put_back(tracer_on_rpc_create_response, "tracer");
     }
 
-    command_manager::instance().register_command(
-        {"tracer.find"},
-        "tracer.find - find related logs",
-        "tracer.find forward|f|backward|b rpc|r|task|t trace_id|task_id(e.g., "
-        "a023003920302390) log_file_name(log.xx.txt)",
-        tracer_log_flow);
+    static std::once_flag flag;
+    std::call_once(flag, [&]() {
+        _tracer_find_cmd = command_manager::instance().register_command(
+            {"tracer.find"},
+            "tracer.find - find related logs",
+            "tracer.find forward|f|backward|b rpc|r|task|t trace_id|task_id(e.g., "
+            "a023003920302390) log_file_name(log.xx.txt)",
+            tracer_log_flow);
+    });
 }
 
 tracer::tracer(const char *name) : toollet(name) {}
-}
-}
+
+} // namespace tools
+} // namespace dsn
diff --git a/src/runtime/tracer.h b/src/runtime/tracer.h
index 72e6c6b19..f0dfb9215 100644
--- a/src/runtime/tracer.h
+++ b/src/runtime/tracer.h
@@ -24,16 +24,6 @@
  * THE SOFTWARE.
  */
 
-/*
- * Description:
- *     the tracer toollets traces all the asynchonous execution flow
- *     in the system through the join-point mechanism
- *
- * Revision history:
- *     Mar., 2015, @imzhenyu (Zhenyu Guo), first version
- *     xxxx-xx-xx, author, fix bug about xxx
- */
-
 #pragma once
 
 #include "runtime/tool_api.h"
@@ -101,13 +91,20 @@ is_trace = false
 </PRE>
 */
 namespace dsn {
+
+class command_deregister;
+
 namespace tools {
 
 class tracer : public toollet
 {
 public:
     tracer(const char *name);
-    virtual void install(service_spec &spec);
+    void install(service_spec &spec) override;
+
+private:
+    std::unique_ptr<command_deregister> _tracer_find_cmd;
 };
-}
-}
+
+} // namespace tools
+} // namespace dsn
diff --git a/src/server/brief_stat.cpp b/src/server/brief_stat.cpp
deleted file mode 100644
index c3e44781c..000000000
--- a/src/server/brief_stat.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "brief_stat.h"
-
-#include <iomanip>
-
-#include "perf_counter/perf_counters.h"
-#include "utils/api_utilities.h"
-#include "utils/fmt_logging.h"
-
-namespace pegasus {
-
-static std::map<std::string, std::string> s_brief_stat_map = {
-    {"zion*profiler*RPC_RRDB_RRDB_GET.qps", "get_qps"},
-    {"zion*profiler*RPC_RRDB_RRDB_GET.latency.server", "get_p99(ns)"},
-    {"zion*profiler*RPC_RRDB_RRDB_MULTI_GET.qps", "multi_get_qps"},
-    {"zion*profiler*RPC_RRDB_RRDB_MULTI_GET.latency.server", "multi_get_p99(ns)"},
-    {"zion*profiler*RPC_RRDB_RRDB_BATCH_GET.qps", "batch_get_qps"},
-    {"zion*profiler*RPC_RRDB_RRDB_BATCH_GET.latency.server", "batch_get_p99(ns)"},
-    {"zion*profiler*RPC_RRDB_RRDB_PUT.qps", "put_qps"},
-    {"zion*profiler*RPC_RRDB_RRDB_PUT.latency.server", "put_p99(ns)"},
-    {"zion*profiler*RPC_RRDB_RRDB_MULTI_PUT.qps", "multi_put_qps"},
-    {"zion*profiler*RPC_RRDB_RRDB_MULTI_PUT.latency.server", "multi_put_p99(ns)"},
-    {"replica*eon.replica_stub*replica(Count)", "serving_replica_count"},
-    {"replica*eon.replica_stub*opening.replica(Count)", "opening_replica_count"},
-    {"replica*eon.replica_stub*closing.replica(Count)", "closing_replica_count"},
-    {"replica*eon.replica_stub*replicas.commit.qps", "commit_throughput"},
-    {"replica*eon.replica_stub*replicas.learning.count", "learning_count"},
-    {"replica*app.pegasus*manual.compact.running.count", "manual_compact_running_count"},
-    {"replica*app.pegasus*manual.compact.enqueue.count", "manual_compact_enqueue_count"},
-    {"replica*app.pegasus*rdb.block_cache.memory_usage", "rdb_block_cache_memory_usage"},
-    {"replica*eon.replica_stub*shared.log.size(MB)", "shared_log_size(MB)"},
-    {"replica*server*memused.virt(MB)", "memused_virt(MB)"},
-    {"replica*server*memused.res(MB)", "memused_res(MB)"},
-    {"replica*eon.replica_stub*disk.capacity.total(MB)", "disk_capacity_total(MB)"},
-    {"replica*eon.replica_stub*disk.available.total.ratio", "disk_available_total_ratio"},
-    {"replica*eon.replica_stub*disk.available.min.ratio", "disk_available_min_ratio"},
-    {"replica*eon.replica_stub*disk.available.max.ratio", "disk_available_max_ratio"},
-};
-
-std::string get_brief_stat()
-{
-    std::vector<std::string> stat_counters;
-    for (const auto &kv : s_brief_stat_map) {
-        stat_counters.push_back(kv.first);
-    }
-
-    std::ostringstream oss;
-    oss << std::fixed << std::setprecision(0);
-    bool first_item = true;
-    dsn::perf_counters::snapshot_iterator iter =
-        [&oss, &first_item](const dsn::perf_counters::counter_snapshot &cs) mutable {
-            if (!first_item)
-                oss << ", ";
-            oss << s_brief_stat_map.find(cs.name)->second << "=" << cs.value;
-            first_item = false;
-        };
-    std::vector<bool> match_result;
-    dsn::perf_counters::instance().query_snapshot(stat_counters, iter, &match_result);
-
-    CHECK_EQ(stat_counters.size(), match_result.size());
-    for (int i = 0; i < match_result.size(); ++i) {
-        if (!match_result[i]) {
-            if (!first_item)
-                oss << ", ";
-            oss << stat_counters[i] << "=not_found";
-            first_item = false;
-        }
-    }
-    return oss.str();
-}
-}
diff --git a/src/server/brief_stat.h b/src/server/brief_stat.h
deleted file mode 100644
index 3cd43452d..000000000
--- a/src/server/brief_stat.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include <string>
-
-namespace pegasus {
-std::string get_brief_stat();
-}
diff --git a/src/server/main.cpp b/src/server/main.cpp
index 722fe79e8..344db2f69 100644
--- a/src/server/main.cpp
+++ b/src/server/main.cpp
@@ -20,7 +20,6 @@
 #include "pegasus_server_impl.h"
 #include "pegasus_service_app.h"
 #include "info_collector_app.h"
-#include "brief_stat.h"
 #include "compaction_operation.h"
 
 #include <pegasus/version.h>
@@ -70,24 +69,6 @@ void dsn_app_registration_pegasus()
     service_app::register_factory<pegasus::server::pegasus_replication_service_app>("replica");
     service_app::register_factory<pegasus::server::info_collector_app>("collector");
     pegasus::server::pegasus_server_impl::register_service();
-
-    dsn::command_manager::instance().register_command(
-        {"server-info"},
-        "server-info - query server information",
-        "server-info",
-        [](const std::vector<std::string> &args) {
-            char str[100];
-            ::dsn::utils::time_ms_to_date_time(dsn::utils::process_start_millis(), str, 100);
-            std::ostringstream oss;
-            oss << "Pegasus Server " << PEGASUS_VERSION << " (" << PEGASUS_GIT_COMMIT << ") "
-                << PEGASUS_BUILD_TYPE << ", Started at " << str;
-            return oss.str();
-        });
-    dsn::command_manager::instance().register_command(
-        {"server-stat"},
-        "server-stat - query selected perf counters",
-        "server-stat",
-        [](const std::vector<std::string> &args) { return pegasus::get_brief_stat(); });
     pegasus::server::register_compaction_operations();
 }
 
@@ -106,6 +87,21 @@ int main(int argc, char **argv)
     LOG_INFO(
         "pegasus server starting, pid(%d), version(%s)", (int)getpid(), pegasus_server_rcsid());
     dsn_app_registration_pegasus();
+
+    std::unique_ptr<command_deregister> server_info_cmd =
+        dsn::command_manager::instance().register_command(
+            {"server-info"},
+            "server-info - query server information",
+            "server-info",
+            [](const std::vector<std::string> &args) {
+                char str[100];
+                ::dsn::utils::time_ms_to_date_time(dsn::utils::process_start_millis(), str, 100);
+                std::ostringstream oss;
+                oss << "Pegasus Server " << PEGASUS_VERSION << " (" << PEGASUS_GIT_COMMIT << ") "
+                    << PEGASUS_BUILD_TYPE << ", Started at " << str;
+                return oss.str();
+            });
+
     dsn_run(argc, argv, true);
 
     return 0;
diff --git a/src/test/function_test/restore_test/test_restore.cpp b/src/test/function_test/restore_test/test_restore.cpp
index 18d36460d..6082cd3da 100644
--- a/src/test/function_test/restore_test/test_restore.cpp
+++ b/src/test/function_test/restore_test/test_restore.cpp
@@ -241,7 +241,7 @@ public:
     int64_t get_first_backup_timestamp()
     {
         std::string pegasus_root_dir = global_env::instance()._pegasus_root;
-        chdir(pegasus_root_dir.c_str());
+        CHECK_EQ(0, ::chdir(pegasus_root_dir.c_str()));
         std::string cmd = "cd " + backup_dir + "; "
                                                "ls -c > restore_app_from_backup_test_tmp; "
                                                "tail -n 1 restore_app_from_backup_test_tmp; "
diff --git a/src/test/function_test/utils/test_util.cpp b/src/test/function_test/utils/test_util.cpp
index d8d8af9db..321e3b8fc 100644
--- a/src/test/function_test/utils/test_util.cpp
+++ b/src/test/function_test/utils/test_util.cpp
@@ -77,7 +77,7 @@ void test_util::SetUp()
 
 void test_util::run_cmd_from_project_root(const std::string &cmd)
 {
-    ASSERT_EQ(0, chdir(global_env::instance()._pegasus_root.c_str()));
+    ASSERT_EQ(0, ::chdir(global_env::instance()._pegasus_root.c_str()));
     ASSERT_NO_FATAL_FAILURE(run_cmd(cmd));
 }
 
diff --git a/src/test/kill_test/process_kill_testor.cpp b/src/test/kill_test/process_kill_testor.cpp
index c49df77d4..526fdbca7 100644
--- a/src/test/kill_test/process_kill_testor.cpp
+++ b/src/test/kill_test/process_kill_testor.cpp
@@ -218,8 +218,11 @@ bool process_kill_testor::start_job_by_index(job_type type, int index)
 
 void process_kill_testor::stop_verifier_and_exit(const char *msg)
 {
-    system("ps aux | grep pegasus | grep verifier | awk '{print $2}' | xargs kill -9");
-    CHECK(false, "{}", msg);
+    std::stringstream ss;
+    int ret = dsn::utils::pipe_execute(
+        "ps aux | grep pegasus | grep verifier | awk '{print $2}' | xargs kill -9", ss);
+    CHECK(ret == 0 || ret == 256, "");
+    LOG_FATAL(msg);
 }
 
 bool process_kill_testor::check_coredump()
diff --git a/src/utils/command_manager.cpp b/src/utils/command_manager.cpp
index 5cafeff42..18abeecb2 100644
--- a/src/utils/command_manager.cpp
+++ b/src/utils/command_manager.cpp
@@ -31,6 +31,7 @@
 #include <thread>
 
 #include "utils/fmt_logging.h"
+#include "utils/logging_provider.h"
 #include "utils/smart_pointers.h"
 #include "utils/utils.h"
 
@@ -177,10 +178,10 @@ command_manager::command_manager()
 command_manager::~command_manager()
 {
     _cmds.clear();
-    _handlers.clear();
-    // TODO(yingchun): enable this check when all commands deregister correctly.
-    // CHECK(_handlers.empty(), "All commands must be deregistered before command_manager been
-    // destroyed", _handlers.begin()->first);
+    CHECK(_handlers.empty(),
+          "All commands must be deregistered before command_manager is destroyed, however {} is "
+          "still registered",
+          _handlers.begin()->first);
 }
 
 } // namespace dsn
diff --git a/src/utils/command_manager.h b/src/utils/command_manager.h
index 27a3b4560..da60630fd 100644
--- a/src/utils/command_manager.h
+++ b/src/utils/command_manager.h
@@ -43,11 +43,11 @@ class command_manager : public ::dsn::utils::singleton<command_manager>
 public:
     typedef std::function<std::string(const std::vector<std::string> &)> command_handler;
 
-    // TODO(yingchun): add __attribute__((warn_unused_result)) in future refactor
-    std::unique_ptr<command_deregister> register_command(const std::vector<std::string> &commands,
-                                                         const std::string &help_one_line,
-                                                         const std::string &help_long,
-                                                         command_handler handler);
+    std::unique_ptr<command_deregister>
+    register_command(const std::vector<std::string> &commands,
+                     const std::string &help_one_line,
+                     const std::string &help_long,
+                     command_handler handler) WARN_UNUSED_RESULT;
 
     bool run_command(const std::string &cmd,
                      const std::vector<std::string> &args,
diff --git a/src/utils/customizable_id.h b/src/utils/customizable_id.h
index 629caebab..46acfcbfe 100644
--- a/src/utils/customizable_id.h
+++ b/src/utils/customizable_id.h
@@ -24,20 +24,16 @@
  * THE SOFTWARE.
  */
 
-/*
- * Description:
- *     dynamic and seperated string to/from integer id mapping
- *     in constrast to defining all enums in a single file
- */
-
 #pragma once
 
-#include "singleton.h"
-#include "ports.h"
 #include <string>
 #include <unordered_map>
 #include <vector>
 
+#include "utils/ports.h"
+#include "utils/singleton.h"
+#include "utils/command_manager.h"
+
 namespace dsn {
 namespace utils {
 
@@ -54,16 +50,18 @@ template <typename T>
 class customized_id_mgr : public dsn::utils::singleton<customized_id_mgr<T>>
 {
 public:
-    customized_id_mgr() : _names(199) {}
+    customized_id_mgr() : _names(199) { register_commands(); }
     int get_id(const char *name) const;
     int get_id(const std::string &name) const;
     const char *get_name(int id) const;
     int register_id(const char *name);
     int max_value() const { return static_cast<int>(_names2.size()) - 1; }
+    void register_commands() {}
 
 private:
     std::unordered_map<std::string, int> _names;
     std::vector<std::string> _names2;
+    std::vector<std::unique_ptr<command_deregister>> _cmds;
 };
 
 template <typename T>
diff --git a/src/utils/logging.cpp b/src/utils/logging.cpp
index cc79866ba..76ad8ff2e 100644
--- a/src/utils/logging.cpp
+++ b/src/utils/logging.cpp
@@ -24,14 +24,15 @@
  * THE SOFTWARE.
  */
 
-#include "utils/command_manager.h"
 #include "utils/logging_provider.h"
-#include "utils/error_code.h"
-#include "utils/threadpool_code.h"
-#include "runtime/task/task_code.h"
+
 #include "common/gpid.h"
+#include "runtime/task/task_code.h"
+#include "utils/command_manager.h"
+#include "utils/error_code.h"
 #include "utils/flags.h"
 #include "utils/smart_pointers.h"
+#include "utils/threadpool_code.h"
 #include "simple_logger.h"
 
 dsn_log_level_t dsn_log_start_level = dsn_log_level_t::LOG_LEVEL_INFO;
@@ -82,37 +83,6 @@ void dsn_log_init(const std::string &logging_factory_name,
         logging_factory_name.c_str(), dsn::PROVIDER_TYPE_MAIN, dir_log.c_str());
     dsn::logging_provider::set_logger(logger);
 
-    // register command for logging
-    ::dsn::command_manager::instance().register_command(
-        {"flush-log"},
-        "flush-log - flush log to stderr or log file",
-        "flush-log",
-        [](const std::vector<std::string> &args) {
-            dsn::logging_provider *logger = dsn::logging_provider::instance();
-            logger->flush();
-            return "Flush done.";
-        });
-    ::dsn::command_manager::instance().register_command(
-        {"reset-log-start-level"},
-        "reset-log-start-level - reset the log start level",
-        "reset-log-start-level [DEBUG | INFO | WARNING | ERROR | FATAL]",
-        [](const std::vector<std::string> &args) {
-            dsn_log_level_t start_level;
-            if (args.size() == 0) {
-                start_level =
-                    enum_from_string(FLAGS_logging_start_level, dsn_log_level_t::LOG_LEVEL_INVALID);
-            } else {
-                std::string level_str = "LOG_LEVEL_" + args[0];
-                start_level =
-                    enum_from_string(level_str.c_str(), dsn_log_level_t::LOG_LEVEL_INVALID);
-                if (start_level == dsn_log_level_t::LOG_LEVEL_INVALID) {
-                    return "ERROR: invalid level '" + args[0] + "'";
-                }
-            }
-            dsn_log_set_start_level(start_level);
-            return std::string("OK, current level is ") + enum_to_string(start_level);
-        });
-
     if (dsn_log_prefixed_message_func != nullptr) {
         dsn::set_log_prefixed_message_func(dsn_log_prefixed_message_func);
     }
@@ -158,13 +128,11 @@ void dsn_log(const char *file,
 
 namespace dsn {
 
-std::unique_ptr<logging_provider> logging_provider::_logger =
-    std::unique_ptr<logging_provider>(nullptr);
+std::unique_ptr<logging_provider> logging_provider::_logger;
 
 logging_provider *logging_provider::instance()
 {
-    static std::unique_ptr<logging_provider> default_logger =
-        std::unique_ptr<logging_provider>(create_default_instance());
+    static std::unique_ptr<logging_provider> default_logger(create_default_instance());
     return _logger ? _logger.get() : default_logger.get();
 }
 
diff --git a/src/utils/logging_provider.h b/src/utils/logging_provider.h
index 4c517f2a5..9ef8d00e2 100644
--- a/src/utils/logging_provider.h
+++ b/src/utils/logging_provider.h
@@ -24,21 +24,17 @@
  * THE SOFTWARE.
  */
 
-/*
- * Description:
- *     base prototype for logging
- *
- * Revision history:
- *     Mar., 2015, @imzhenyu (Zhenyu Guo), first version
- *     xxxx-xx-xx, author, fix bug about xxx
- */
-
 #pragma once
 
 #include <stdarg.h>
+
+#include "utils/api_utilities.h"
 #include "utils/factory_store.h"
 
 namespace dsn {
+
+class command_deregister;
+
 /*!
 @addtogroup tool-api-providers
 @{
@@ -55,9 +51,7 @@ public:
     typedef logging_provider *(*factory)(const char *);
 
 public:
-    logging_provider(const char *) {}
-
-    virtual ~logging_provider(void) {}
+    virtual ~logging_provider() = default;
 
     // singleton
     static logging_provider *instance();
@@ -80,10 +74,14 @@ public:
 
     virtual void flush() = 0;
 
-private:
+    void deregister_commands() { _cmds.clear(); }
+
+protected:
     static std::unique_ptr<logging_provider> _logger;
 
     static logging_provider *create_default_instance();
+
+    std::vector<std::unique_ptr<command_deregister>> _cmds;
 };
 
 void set_log_prefixed_message_func(std::function<std::string()> func);
diff --git a/src/utils/ports.h b/src/utils/ports.h
index 568fbf231..718810f05 100644
--- a/src/utils/ports.h
+++ b/src/utils/ports.h
@@ -109,3 +109,12 @@ static_assert((CACHELINE_SIZE & (CACHELINE_SIZE - 1)) == 0 &&
 #else
 #define CACHELINE_ALIGNED
 #endif
+
+// Annotate a function indicating the caller must examine the return value.
+// Use like:
+//   int foo() WARN_UNUSED_RESULT;
+#if defined(__GNUC__)
+#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define WARN_UNUSED_RESULT
+#endif
diff --git a/src/utils/simple_logger.cpp b/src/utils/simple_logger.cpp
index dfb86eada..b00b06b50 100644
--- a/src/utils/simple_logger.cpp
+++ b/src/utils/simple_logger.cpp
@@ -24,12 +24,16 @@
  * THE SOFTWARE.
  */
 
-#include "simple_logger.h"
+#include "utils/simple_logger.h"
+
+#include <fmt/format.h>
 #include <sstream>
+
 #include "utils/filesystem.h"
 #include "utils/flags.h"
 #include "utils/time_utils.h"
-#include <fmt/format.h>
+
+DSN_DECLARE_string(logging_start_level);
 
 namespace dsn {
 namespace tools {
@@ -78,12 +82,9 @@ static void print_header(FILE *fp, dsn_log_level_t log_level)
                log_prefixed_message_func().c_str());
 }
 
-screen_logger::screen_logger(bool short_header) : logging_provider("./")
-{
-    _short_header = short_header;
-}
+screen_logger::screen_logger(bool short_header) { _short_header = short_header; }
 
-screen_logger::screen_logger(const char *log_dir) : logging_provider(log_dir)
+screen_logger::screen_logger(const char *log_dir)
 {
     _short_header =
         dsn_config_get_value_bool("tools.screen_logger",
@@ -113,7 +114,7 @@ void screen_logger::dsn_logv(const char *file,
 
 void screen_logger::flush() { ::fflush(stdout); }
 
-simple_logger::simple_logger(const char *log_dir) : logging_provider(log_dir)
+simple_logger::simple_logger(const char *log_dir)
 {
     _log_dir = std::string(log_dir);
     // we assume all valid entries are positive
@@ -151,6 +152,36 @@ simple_logger::simple_logger(const char *log_dir) : logging_provider(log_dir)
         ++_index;
 
     create_log_file();
+
+    _cmds.emplace_back(::dsn::command_manager::instance().register_command(
+        {"flush-log"},
+        "flush-log - flush log to stderr or log file",
+        "flush-log",
+        [this](const std::vector<std::string> &args) {
+            this->flush();
+            return "Flush done.";
+        }));
+
+    _cmds.emplace_back(::dsn::command_manager::instance().register_command(
+        {"reset-log-start-level"},
+        "reset-log-start-level - reset the log start level",
+        "reset-log-start-level [DEBUG | INFO | WARNING | ERROR | FATAL]",
+        [](const std::vector<std::string> &args) {
+            dsn_log_level_t start_level;
+            if (args.size() == 0) {
+                start_level =
+                    enum_from_string(FLAGS_logging_start_level, dsn_log_level_t::LOG_LEVEL_INVALID);
+            } else {
+                std::string level_str = "LOG_LEVEL_" + args[0];
+                start_level =
+                    enum_from_string(level_str.c_str(), dsn_log_level_t::LOG_LEVEL_INVALID);
+                if (start_level == dsn_log_level_t::LOG_LEVEL_INVALID) {
+                    return "ERROR: invalid level '" + args[0] + "'";
+                }
+            }
+            dsn_log_set_start_level(start_level);
+            return std::string("OK, current level is ") + enum_to_string(start_level);
+        }));
 }
 
 void simple_logger::create_log_file()
diff --git a/src/utils/simple_logger.h b/src/utils/simple_logger.h
index fb7286e64..716d695a5 100644
--- a/src/utils/simple_logger.h
+++ b/src/utils/simple_logger.h
@@ -26,9 +26,10 @@
 
 #pragma once
 
-#include "runtime/tool_api.h"
-#include <thread>
 #include <cstdio>
+#include <thread>
+
+#include "runtime/tool_api.h"
 
 namespace dsn {
 namespace tools {
@@ -41,7 +42,7 @@ class screen_logger : public logging_provider
 public:
     screen_logger(bool short_header);
     screen_logger(const char *log_dir);
-    virtual ~screen_logger(void);
+    ~screen_logger() override;
 
     virtual void dsn_logv(const char *file,
                           const char *function,
@@ -71,22 +72,22 @@ class simple_logger : public logging_provider
 {
 public:
     simple_logger(const char *log_dir);
-    virtual ~simple_logger(void);
+    ~simple_logger() override;
 
-    virtual void dsn_logv(const char *file,
-                          const char *function,
-                          const int line,
-                          dsn_log_level_t log_level,
-                          const char *fmt,
-                          va_list args);
+    void dsn_logv(const char *file,
+                  const char *function,
+                  const int line,
+                  dsn_log_level_t log_level,
+                  const char *fmt,
+                  va_list args) override;
 
-    virtual void dsn_log(const char *file,
-                         const char *function,
-                         const int line,
-                         dsn_log_level_t log_level,
-                         const char *str);
+    void dsn_log(const char *file,
+                 const char *function,
+                 const int line,
+                 dsn_log_level_t log_level,
+                 const char *str) override;
 
-    virtual void flush();
+    void flush() override;
 
 private:
     void create_log_file();
@@ -101,5 +102,5 @@ private:
     int _lines;
     dsn_log_level_t _stderr_start_level;
 };
-}
-}
+} // namespace tools
+} // namespace dsn
diff --git a/src/utils/test/logger.cpp b/src/utils/test/logger.cpp
index 1258e5fba..20d0e3018 100644
--- a/src/utils/test/logger.cpp
+++ b/src/utils/test/logger.cpp
@@ -24,31 +24,26 @@
  * THE SOFTWARE.
  */
 
-/*
- * Description:
- *     Unit-test for logger.
- *
- * Revision history:
- *     Nov., 2015, @shengofsun (Weijie Sun), first version
- *     xxxx-xx-xx, author, fix bug about xxx
- */
-
-#include "utils/simple_logger.h"
 #include <gtest/gtest.h>
+
 #include "utils/filesystem.h"
+#include "utils/safe_strerror_posix.h"
+#include "utils/simple_logger.h"
+#include "utils/smart_pointers.h"
+
+using std::vector;
+using std::string;
 
 using namespace dsn;
 using namespace dsn::tools;
 
 static const int simple_logger_gc_gap = 20;
 
-static void get_log_file_index(std::vector<int> &log_index)
+static void get_log_file_index(vector<int> &log_index)
 {
-    std::vector<std::string> sub_list;
-    std::string path = "./";
-    if (!utils::filesystem::get_subfiles(path, sub_list, false)) {
-        ASSERT_TRUE(false);
-    }
+    vector<string> sub_list;
+    string path = "./";
+    ASSERT_TRUE(utils::filesystem::get_subfiles(path, sub_list, false));
 
     for (auto &ptr : sub_list) {
         auto &&name = utils::filesystem::get_file_name(ptr);
@@ -61,29 +56,28 @@ static void get_log_file_index(std::vector<int> &log_index)
     }
 }
 
-static void clear_files(std::vector<int> &log_index)
+static void clear_files(vector<int> &log_index)
 {
-    char file[256];
-    memset(file, 0, sizeof(file));
+    char file[256] = {};
     for (auto i : log_index) {
         snprintf_p(file, 256, "log.%d.txt", i);
-        dsn::utils::filesystem::remove_path(std::string(file));
+        dsn::utils::filesystem::remove_path(string(file));
     }
 }
 
 static void prepare_test_dir()
 {
     const char *dir = "./test";
-    std::string dr(dir);
-    dsn::utils::filesystem::create_directory(dr);
-    chdir(dir);
+    string dr(dir);
+    ASSERT_TRUE(dsn::utils::filesystem::create_directory(dr));
+    ASSERT_EQ(0, ::chdir(dir));
 }
 
 static void finish_test_dir()
 {
     const char *dir = "./test";
-    chdir("..");
-    rmdir(dir);
+    ASSERT_EQ(0, ::chdir("..")) << "chdir failed, err = " << utils::safe_strerror(errno);
+    ASSERT_TRUE(utils::filesystem::remove_path(dir)) << "remove_directory " << dir << " failed";
 }
 
 void log_print(logging_provider *logger, const char *fmt, ...)
@@ -96,32 +90,33 @@ void log_print(logging_provider *logger, const char *fmt, ...)
 
 TEST(tools_common, simple_logger)
 {
-    // cases for print_header
-    screen_logger *logger = new screen_logger("./");
-    log_print(logger, "%s", "test_print");
-    std::thread t([](screen_logger *lg) { log_print(lg, "%s", "test_print"); }, logger);
-    t.join();
+    // Deregister commands to avoid re-register error.
+    dsn::logging_provider::instance()->deregister_commands();
+
+    {
+        auto logger = dsn::make_unique<screen_logger>("./");
+        log_print(logger.get(), "%s", "test_print");
+        std::thread t([](screen_logger *lg) { log_print(lg, "%s", "test_print"); }, logger.get());
+        t.join();
 
-    logger->flush();
-    delete logger;
+        logger->flush();
+    }
 
     prepare_test_dir();
     // create multiple files
     for (unsigned int i = 0; i < simple_logger_gc_gap + 10; ++i) {
-        simple_logger *logger = new simple_logger("./");
-        // in this case stdout is useless
-        for (unsigned int i = 0; i != 1000; ++i)
-            log_print(logger, "%s", "test_print");
+        auto logger = dsn::make_unique<simple_logger>("./");
+        for (unsigned int i = 0; i != 1000; ++i) {
+            log_print(logger.get(), "%s", "test_print");
+        }
         logger->flush();
-
-        delete logger;
     }
 
-    std::vector<int> index;
+    vector<int> index;
     get_log_file_index(index);
-    EXPECT_TRUE(!index.empty());
+    ASSERT_TRUE(!index.empty());
     sort(index.begin(), index.end());
-    EXPECT_EQ(simple_logger_gc_gap, index.size());
+    ASSERT_EQ(simple_logger_gc_gap, index.size());
     clear_files(index);
     finish_test_dir();
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pegasus.apache.org
For additional commands, e-mail: commits-help@pegasus.apache.org