Skip to content

Commit

Permalink
shell: JSON output supported for more commands (#329)
Browse files Browse the repository at this point in the history
  • Loading branch information
acelyc111 authored and qinzuoyan committed May 26, 2019
1 parent 3659ea7 commit fc9764a
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 91 deletions.
37 changes: 33 additions & 4 deletions src/shell/commands/node_management.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
167 changes: 88 additions & 79 deletions src/shell/commands/table_management.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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;
}

Expand All @@ -396,19 +394,21 @@ 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}};

std::string app_name;
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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -676,29 +674,40 @@ 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<std::string, std::string> envs;
::dsn::error_code ret = sc->ddl_client->get_app_envs(sc->current_app_name, envs);
if (ret != ::dsn::ERR_OK) {
fprintf(stderr, "get app env failed with err = %s\n", ret.to_string());
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;
}
Expand Down
Loading

0 comments on commit fc9764a

Please sign in to comment.