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

gehafearless 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 3cdad1861 feat(shell): support options `sample_interval_ms` for shell 
`app_stat` and `nodes` commands (#1923)
3cdad1861 is described below

commit 3cdad18618e604bfe5449970285dc982b0cf006e
Author: Dan Wang <[email protected]>
AuthorDate: Thu Feb 29 10:41:22 2024 +0800

    feat(shell): support options `sample_interval_ms` for shell `app_stat` and 
`nodes` commands (#1923)
    
    Support specifying sample_interval_ms options while executing
    commands app_stat and nodes, to give the custom duration
    while aggregating rates on stats.
---
 src/shell/command_helper.h              |  7 +++++++
 src/shell/commands/node_management.cpp  | 17 +++++++++++++----
 src/shell/commands/table_management.cpp | 20 ++++++++++++++------
 src/shell/main.cpp                      |  9 +++++----
 4 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/src/shell/command_helper.h b/src/shell/command_helper.h
index 6b6577fec..de2e8b9dc 100644
--- a/src/shell/command_helper.h
+++ b/src/shell/command_helper.h
@@ -59,6 +59,7 @@
 #include "utils/errors.h"
 #include "utils/metrics.h"
 #include "utils/ports.h"
+#include "utils/string_conv.h"
 #include "utils/strings.h"
 #include "utils/synchronize.h"
 #include "utils/time_utils.h"
@@ -76,6 +77,12 @@ using namespace dsn::replication;
 DEFINE_TASK_CODE(LPC_SCAN_DATA, TASK_PRIORITY_COMMON, 
::dsn::THREAD_POOL_DEFAULT)
 DEFINE_TASK_CODE(LPC_GET_METRICS, TASK_PRIORITY_COMMON, 
::dsn::THREAD_POOL_DEFAULT)
 
+#define RETURN_FALSE_IF_SAMPLE_INTERVAL_MS_INVALID()                           
                    \
+    verify_logged(dsn::buf2uint32(optarg, sample_interval_ms),                 
                    \
+                  "parse sample_interval_ms(%s) failed\n",                     
                    \
+                  optarg);                                                     
                    \
+    verify_logged(sample_interval_ms > 0, "sample_interval_ms should be > 0\n")
+
 enum scan_data_operator
 {
     SCAN_COPY,
diff --git a/src/shell/commands/node_management.cpp 
b/src/shell/commands/node_management.cpp
index 52910671f..b12e66d81 100644
--- a/src/shell/commands/node_management.cpp
+++ b/src/shell/commands/node_management.cpp
@@ -55,6 +55,7 @@
 #include "utils/utils.h"
 
 DSN_DEFINE_uint32(shell, nodes_sample_interval_ms, 1000, "The interval between 
sampling metrics.");
+DSN_DEFINE_validator(nodes_sample_interval_ms, [](uint32_t value) -> bool { 
return value > 0; });
 
 bool query_cluster_info(command_executor *e, shell_context *sc, arguments args)
 {
@@ -238,23 +239,28 @@ bool ls_nodes(command_executor *e, shell_context *sc, 
arguments args)
                                            {"json", no_argument, 0, 'j'},
                                            {"status", required_argument, 0, 
's'},
                                            {"output", required_argument, 0, 
'o'},
+                                           {"sample_interval_ms", 
required_argument, 0, 't'},
                                            {0, 0, 0, 0}};
 
     std::string status;
     std::string output_file;
+    uint32_t sample_interval_ms = FLAGS_nodes_sample_interval_ms;
     bool detailed = false;
     bool resolve_ip = false;
     bool resource_usage = false;
     bool show_qps = false;
     bool show_latency = false;
     bool json = false;
+
     optind = 0;
     while (true) {
         int option_index = 0;
-        int c;
-        c = getopt_long(args.argc, args.argv, "druqjs:o:", long_options, 
&option_index);
-        if (c == -1)
+        int c = getopt_long(args.argc, args.argv, "druqjs:o:t:", long_options, 
&option_index);
+        if (c == -1) {
+            // -1 means all command-line options have been parsed.
             break;
+        }
+
         switch (c) {
         case 'd':
             detailed = true;
@@ -278,6 +284,9 @@ bool ls_nodes(command_executor *e, shell_context *sc, 
arguments args)
         case 'o':
             output_file = optarg;
             break;
+        case 't':
+            RETURN_FALSE_IF_SAMPLE_INTERVAL_MS_INVALID();
+            break;
         default:
             return false;
         }
@@ -392,7 +401,7 @@ bool ls_nodes(command_executor *e, shell_context *sc, 
arguments args)
 
         const auto &query_string = rw_requests_filters().to_query_string();
         const auto &results_start = get_metrics(nodes, query_string);
-        
std::this_thread::sleep_for(std::chrono::milliseconds(FLAGS_nodes_sample_interval_ms));
+        
std::this_thread::sleep_for(std::chrono::milliseconds(sample_interval_ms));
         const auto &results_end = get_metrics(nodes, query_string);
 
         for (size_t i = 0; i < nodes.size(); ++i) {
diff --git a/src/shell/commands/table_management.cpp 
b/src/shell/commands/table_management.cpp
index 6cede043d..9edb44149 100644
--- a/src/shell/commands/table_management.cpp
+++ b/src/shell/commands/table_management.cpp
@@ -55,6 +55,7 @@
 #include "utils/utils.h"
 
 DSN_DEFINE_uint32(shell, tables_sample_interval_ms, 1000, "The interval 
between sampling metrics.");
+DSN_DEFINE_validator(tables_sample_interval_ms, [](uint32_t value) -> bool { 
return value > 0; });
 
 double convert_to_ratio(double hit, double total)
 {
@@ -480,10 +481,11 @@ bool app_disk(command_executor *e, shell_context *sc, 
arguments args)
 bool app_stat(command_executor *e, shell_context *sc, arguments args)
 {
     static struct option long_options[] = {{"app_name", required_argument, 0, 
'a'},
-                                           {"only_qps", required_argument, 0, 
'q'},
-                                           {"only_usage", required_argument, 
0, 'u'},
+                                           {"only_qps", no_argument, 0, 'q'},
+                                           {"only_usage", no_argument, 0, 'u'},
                                            {"json", no_argument, 0, 'j'},
                                            {"output", required_argument, 0, 
'o'},
+                                           {"sample_interval_ms", 
required_argument, 0, 't'},
                                            {0, 0, 0, 0}};
 
     std::string app_name;
@@ -491,14 +493,17 @@ bool app_stat(command_executor *e, shell_context *sc, 
arguments args)
     bool only_qps = false;
     bool only_usage = false;
     bool json = false;
+    uint32_t sample_interval_ms = FLAGS_tables_sample_interval_ms;
 
     optind = 0;
     while (true) {
         int option_index = 0;
-        int c;
-        c = getopt_long(args.argc, args.argv, "a:qujo:", long_options, 
&option_index);
-        if (c == -1)
+        int c = getopt_long(args.argc, args.argv, "a:qujo:t:", long_options, 
&option_index);
+        if (c == -1) {
+            // -1 means all command-line options have been parsed.
             break;
+        }
+
         switch (c) {
         case 'a':
             app_name = optarg;
@@ -515,6 +520,9 @@ bool app_stat(command_executor *e, shell_context *sc, 
arguments args)
         case 'o':
             out_file = optarg;
             break;
+        case 't':
+            RETURN_FALSE_IF_SAMPLE_INTERVAL_MS_INVALID();
+            break;
         default:
             return false;
         }
@@ -527,7 +535,7 @@ bool app_stat(command_executor *e, shell_context *sc, 
arguments args)
     }
 
     std::vector<row_data> rows;
-    if (!get_app_stat(sc, app_name, FLAGS_tables_sample_interval_ms, rows)) {
+    if (!get_app_stat(sc, app_name, sample_interval_ms, rows)) {
         std::cout << "ERROR: query app stat from server failed" << std::endl;
         return true;
     }
diff --git a/src/shell/main.cpp b/src/shell/main.cpp
index 186fb92ba..66ab8da4f 100644
--- a/src/shell/main.cpp
+++ b/src/shell/main.cpp
@@ -86,15 +86,16 @@ static command_executor commands[] = {
     {
         "ls",
         "list all apps",
-        "[-a|-all] [-d|--detailed] [-j|--json] [-o|--output file_name]"
+        "[-a|-all] [-d|--detailed] [-j|--json] [-o|--output file_name] "
         "[-s|--status all|available|creating|dropping|dropped]",
         ls_apps,
     },
     {
         "nodes",
         "get the node status for this cluster",
-        "[-d|--detailed] [-j|--json] [-r|--resolve_ip] [-u|--resource_usage]"
-        "[-o|--output file_name] [-s|--status all|alive|unalive] [-q|--qps]",
+        "[-d|--detailed] [-j|--json] [-r|--resolve_ip] [-u|--resource_usage] "
+        "[-o|--output file_name] [-s|--status all|alive|unalive] [-q|--qps] "
+        "[-t|--sample_interval_ms num]",
         ls_nodes,
     },
     {
@@ -352,7 +353,7 @@ static command_executor commands[] = {
         "app_stat",
         "get stat of apps",
         "[-a|--app_name str] [-q|--only_qps] [-u|--only_usage] [-j|--json] "
-        "[-o|--output file_name]",
+        "[-o|--output file_name] [-t|--sample_interval_ms num]",
         app_stat,
     },
     {


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

Reply via email to