diff --git a/rdsn b/rdsn index 8379453692..0ebf109476 160000 --- a/rdsn +++ b/rdsn @@ -1 +1 @@ -Subproject commit 8379453692880cf24050eb37e135e1899ad6bc7d +Subproject commit 0ebf10947688b9ae4568ba4c8a5ed9b926b144e4 diff --git a/src/shell/commands/node_management.cpp b/src/shell/commands/node_management.cpp index cfc6267055..7ee8db38e1 100644 --- a/src/shell/commands/node_management.cpp +++ b/src/shell/commands/node_management.cpp @@ -6,11 +6,40 @@ bool query_cluster_info(command_executor *e, shell_context *sc, arguments args) { - ::dsn::error_code err = sc->ddl_client->cluster_info(""); - if (err == ::dsn::ERR_OK) - std::cout << "get cluster info succeed" << std::endl; - else + static struct option long_options[] = {{"resolve_ip", no_argument, 0, 'r'}, + {"json", no_argument, 0, 'j'}, + {"output", required_argument, 0, 'o'}, + {0, 0, 0, 0}}; + + std::string out_file; + bool resolve_ip = false; + bool json = false; + + optind = 0; + while (true) { + int option_index = 0; + int c = getopt_long(args.argc, args.argv, "rjo:", long_options, &option_index); + if (c == -1) + break; + switch (c) { + case 'r': + resolve_ip = true; + break; + case 'j': + json = true; + break; + case 'o': + out_file = optarg; + break; + default: + return false; + } + } + + ::dsn::error_code err = sc->ddl_client->cluster_info(out_file, resolve_ip, json); + if (err != ::dsn::ERR_OK) { std::cout << "get cluster info failed, error=" << err.to_string() << std::endl; + } return true; } diff --git a/src/shell/commands/table_management.cpp b/src/shell/commands/table_management.cpp index a5d183861b..d9f913ee1a 100644 --- a/src/shell/commands/table_management.cpp +++ b/src/shell/commands/table_management.cpp @@ -66,24 +66,35 @@ bool query_app(command_executor *e, shell_context *sc, arguments args) if (args.argc <= 1) return false; - static struct option long_options[] = { - {"detailed", no_argument, 0, 'd'}, {"output", required_argument, 0, 'o'}, {0, 0, 0, 0}}; + static struct option long_options[] = {{"detailed", no_argument, 0, 'd'}, + {"resolve_ip", no_argument, 0, 'r'}, + {"output", required_argument, 0, 'o'}, + {"json", no_argument, 0, 'j'}, + {0, 0, 0, 0}}; std::string app_name = args.argv[1]; std::string out_file; bool detailed = false; + bool resolve_ip = false; + bool json = false; optind = 0; while (true) { int option_index = 0; int c; - c = getopt_long(args.argc, args.argv, "do:", long_options, &option_index); + c = getopt_long(args.argc, args.argv, "dro:j", long_options, &option_index); if (c == -1) break; switch (c) { case 'd': detailed = true; break; + case 'r': + resolve_ip = true; + break; + case 'j': + json = true; + break; case 'o': out_file = optarg; break; @@ -92,29 +103,16 @@ bool query_app(command_executor *e, shell_context *sc, arguments args) } } - dsn::utils::table_printer tp; - if (!(app_name.empty() && out_file.empty())) { - std::cout << "[Parameters]" << std::endl; - if (!app_name.empty()) - tp.add_row_name_and_data("app_name", app_name); - if (!out_file.empty()) - tp.add_row_name_and_data("out_file", out_file); - } - tp.add_row_name_and_data("detailed", detailed); - tp.output(std::cout); - - std::cout << std::endl << "[Result]" << std::endl; - if (app_name.empty()) { std::cout << "ERROR: null app name" << std::endl; return false; } + ::dsn::error_code err = - sc->ddl_client->list_app(app_name, detailed, out_file); // TODO resolve ip - if (err == ::dsn::ERR_OK) - std::cout << "list app " << app_name << " succeed" << std::endl; - else - std::cout << "list app " << app_name << " failed, error=" << err.to_string() << std::endl; + sc->ddl_client->list_app(app_name, detailed, json, out_file, resolve_ip); + if (err != ::dsn::ERR_OK) { + std::cout << "query app " << app_name << " failed, error=" << err.to_string() << std::endl; + } return true; } @@ -123,24 +121,30 @@ bool app_disk(command_executor *e, shell_context *sc, arguments args) if (args.argc <= 1) return false; - static struct option long_options[] = { - {"detailed", no_argument, 0, 'd'}, {"output", required_argument, 0, 'o'}, {0, 0, 0, 0}}; + static struct option long_options[] = {{"detailed", no_argument, 0, 'd'}, + {"json", no_argument, 0, 'j'}, + {"output", required_argument, 0, 'o'}, + {0, 0, 0, 0}}; std::string app_name = args.argv[1]; std::string out_file; bool detailed = false; + bool json = false; optind = 0; while (true) { int option_index = 0; int c; - c = getopt_long(args.argc, args.argv, "do:", long_options, &option_index); + c = getopt_long(args.argc, args.argv, "djo:", long_options, &option_index); if (c == -1) break; switch (c) { case 'd': detailed = true; break; + case 'j': + json = true; + break; case 'o': out_file = optarg; break; @@ -149,23 +153,32 @@ bool app_disk(command_executor *e, shell_context *sc, arguments args) } } - dsn::utils::table_printer tp_params; + if (app_name.empty()) { + std::cout << "ERROR: null app name" << std::endl; + return false; + } + + std::streambuf *buf; + std::ofstream of; + + if (!out_file.empty()) { + of.open(out_file); + buf = of.rdbuf(); + } else { + buf = std::cout.rdbuf(); + } + std::ostream out(buf); + + dsn::utils::multi_table_printer mtp; + dsn::utils::table_printer tp_params("parameters"); if (!(app_name.empty() && out_file.empty())) { - std::cout << "[Parameters]" << std::endl; if (!app_name.empty()) tp_params.add_row_name_and_data("app_name", app_name); if (!out_file.empty()) tp_params.add_row_name_and_data("out_file", out_file); } tp_params.add_row_name_and_data("detailed", detailed); - tp_params.output(std::cout); - - std::cout << std::endl << "[Result]" << std::endl; - - if (app_name.empty()) { - std::cout << "ERROR: null app name" << std::endl; - return false; - } + mtp.add(std::move(tp_params)); int32_t app_id = 0; int32_t partition_count = 0; @@ -229,25 +242,13 @@ bool app_disk(command_executor *e, shell_context *sc, arguments args) } } - // print configuration_query_by_index_response - std::streambuf *buf; - std::ofstream of; - - if (!out_file.empty()) { - of.open(out_file); - buf = of.rdbuf(); - } else { - buf = std::cout.rdbuf(); - } - std::ostream out(buf); - - ::dsn::utils::table_printer tp_general; + ::dsn::utils::table_printer tp_general("result"); tp_general.add_row_name_and_data("app_name", app_name); tp_general.add_row_name_and_data("app_id", app_id); tp_general.add_row_name_and_data("partition_count", partition_count); tp_general.add_row_name_and_data("max_replica_count", max_replica_count); - ::dsn::utils::table_printer tp_details; + ::dsn::utils::table_printer tp_details("details"); if (detailed) { tp_details.add_title("pidx"); tp_details.add_column("ballot"); @@ -372,22 +373,19 @@ bool app_disk(command_executor *e, shell_context *sc, arguments args) tp_general.add_row_name_and_data("disk_used_for_primary_replicas(MB)", disk_used_for_primary_replicas); tp_general.add_row_name_and_data("disk_used_for_all_replicas(MB)", disk_used_for_all_replicas); - tp_general.output(out); + tp_general.add_row_name_and_data("partitions not counted", + std::to_string(partition_count - primary_replicas_count) + + "/" + std::to_string(partition_count)); + tp_general.add_row_name_and_data( + "replicas not counted", + std::to_string(partition_count * max_replica_count - all_replicas_count) + "/" + + std::to_string(partition_count * max_replica_count)); + mtp.add(std::move(tp_general)); if (detailed) { - out << "details" << std::endl; - tp_details.output(out); + mtp.add(std::move(tp_details)); } - out << std::endl; + mtp.output(out, json ? tp_output_format::kJsonPretty : tp_output_format::kTabular); - if (primary_replicas_count < partition_count) { - out << " (" << (partition_count - primary_replicas_count) << "/" << partition_count - << " partitions not counted)" << std::endl; - } - if (all_replicas_count < partition_count * max_replica_count) { - out << " (" << (partition_count * max_replica_count - all_replicas_count) << "/" - << (partition_count * max_replica_count) << " replicas not counted)" << std::endl; - } - std::cout << "list disk usage for app " << app_name << " succeed" << std::endl; return true; } @@ -396,6 +394,7 @@ 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'}, + {"json", no_argument, 0, 'j'}, {"output", required_argument, 0, 'o'}, {0, 0, 0, 0}}; @@ -403,12 +402,13 @@ bool app_stat(command_executor *e, shell_context *sc, arguments args) std::string out_file; bool only_qps = false; bool only_usage = false; + bool json = false; optind = 0; while (true) { int option_index = 0; int c; - c = getopt_long(args.argc, args.argv, "a:quo:", long_options, &option_index); + c = getopt_long(args.argc, args.argv, "a:qujo:", long_options, &option_index); if (c == -1) break; switch (c) { @@ -421,6 +421,9 @@ bool app_stat(command_executor *e, shell_context *sc, arguments args) case 'u': only_usage = true; break; + case 'j': + json = true; + break; case 'o': out_file = optarg; break; @@ -481,7 +484,7 @@ bool app_stat(command_executor *e, shell_context *sc, arguments args) } std::ostream out(buf); - ::dsn::utils::table_printer tp; + ::dsn::utils::table_printer tp("app_stat"); tp.add_title(app_name.empty() ? "app_name" : "pidx"); if (app_name.empty()) { tp.add_column("app_id", tp_alignment::kRight); @@ -547,13 +550,8 @@ bool app_stat(command_executor *e, shell_context *sc, arguments args) : row.rdb_block_cache_hit_count / row.rdb_block_cache_total_count; tp.append_data(block_cache_hit_rate); } - tp.output(out); + tp.output(out, json ? tp_output_format::kJsonPretty : tp_output_format::kTabular); - std::cout << std::endl; - if (app_name.empty()) - std::cout << "list statistics for apps succeed" << std::endl; - else - std::cout << "list statistics for app " << app_name << " succeed" << std::endl; return true; } @@ -676,15 +674,28 @@ bool recall_app(command_executor *e, shell_context *sc, arguments args) bool get_app_envs(command_executor *e, shell_context *sc, arguments args) { + static struct option long_options[] = {{"json", no_argument, 0, 'j'}, {0, 0, 0, 0}}; + bool json = false; + optind = 0; + while (true) { + int option_index = 0; + int c = getopt_long(args.argc, args.argv, "j", long_options, &option_index); + if (c == -1) + break; + switch (c) { + case 'j': + json = true; + break; + default: + return false; + } + } + if (sc->current_app_name.empty()) { fprintf(stderr, "No app is using now\nUSAGE: use [app_name]\n"); return true; } - if (args.argc != 1) { - return false; - } - std::map envs; ::dsn::error_code ret = sc->ddl_client->get_app_envs(sc->current_app_name, envs); if (ret != ::dsn::ERR_OK) { @@ -692,13 +703,11 @@ bool get_app_envs(command_executor *e, shell_context *sc, arguments args) return true; } - std::cout << "get app envs succeed, count = " << envs.size() << std::endl; - if (!envs.empty()) { - std::cout << "=================================" << std::endl; - for (auto &kv : envs) - std::cout << kv.first << " = " << kv.second << std::endl; - std::cout << "=================================" << std::endl; + ::dsn::utils::table_printer tp("app_envs"); + for (auto &kv : envs) { + tp.add_row_name_and_data(kv.first, kv.second); } + tp.output(std::cout, json ? tp_output_format::kJsonPretty : tp_output_format::kTabular); return true; } diff --git a/src/shell/main.cpp b/src/shell/main.cpp index 92a729a33b..e28810fdd7 100644 --- a/src/shell/main.cpp +++ b/src/shell/main.cpp @@ -32,31 +32,34 @@ static command_executor commands[] = { "version", "get the shell version", "", version, }, { - "cluster_info", "get the informations for the cluster", "", query_cluster_info, + "cluster_info", + "get the information of the cluster", + "[-r|--resolve_ip] [-o|--output file_name] [-j|--json]", + query_cluster_info, }, { "app", "get the partition information for some specific app", - " [-d|--detailed] [-o|--output file_name]", + " [-d|--detailed] [-r|--resolve_ip] [-o|--output file_name] [-j|--json]", query_app, }, { "app_disk", "get the disk usage information for some specific app", - " [-d|--detailed] [-o|--output file_name]", + " [-d|--detailed] [-j|--json] [-o|--output file_name]", app_disk, }, { "ls", "list all apps", - "[-a|-all] [-d|--detailed] [-j|--json_pretty] [-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_pretty] [-r|--resolve_ip] [-u|--resource_usage]" + "[-d|--detailed] [-j|--json] [-r|--resolve_ip] [-u|--resource_usage]" "[-o|--output file_name] [-s|--status all|alive|unalive]", ls_nodes, }, @@ -309,7 +312,8 @@ static command_executor commands[] = { { "app_stat", "get stat of apps", - "[-a|--app_name str] [-q|--only_qps] [-u|--only_usage] [-o|--output file_name]", + "[-a|--app_name str] [-q|--only_qps] [-u|--only_usage] [-j|--json] " + "[-o|--output file_name]", app_stat, }, { @@ -392,7 +396,7 @@ static command_executor commands[] = { query_restore_status, }, { - "get_app_envs", "get current app envs", "", get_app_envs, + "get_app_envs", "get current app envs", "[-j|--json]", get_app_envs, }, { "set_app_envs", "set current app envs", " [key value...]", set_app_envs,