in src/shell/commands/table_management.cpp [224:460]
bool app_disk(command_executor *e, shell_context *sc, arguments args)
{
if (args.argc <= 1)
return false;
static struct option long_options[] = {{"resolve_ip", no_argument, 0, 'r'},
{"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;
bool resolve_ip = false;
optind = 0;
while (true) {
int option_index = 0;
int c;
c = getopt_long(args.argc, args.argv, "drjo:", 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;
default:
return false;
}
}
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())) {
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);
mtp.add(std::move(tp_params));
int32_t app_id = 0;
int32_t partition_count = 0;
int32_t max_replica_count = 0;
std::vector<dsn::partition_configuration> pcs;
dsn::error_code err = sc->ddl_client->list_app(app_name, app_id, partition_count, pcs);
if (err != ::dsn::ERR_OK) {
std::cout << "ERROR: list app " << app_name << " failed, error=" << err << std::endl;
return true;
}
if (!pcs.empty()) {
max_replica_count = pcs[0].max_replica_count;
}
std::vector<node_desc> nodes;
if (!fill_nodes(sc, "replica-server", nodes)) {
std::cout << "ERROR: get replica server node list failed" << std::endl;
return true;
}
const auto &results = get_metrics(nodes, sst_stat_filters(app_id).to_query_string());
std::map<dsn::host_port, std::map<int32_t, double>> disk_map;
std::map<dsn::host_port, std::map<int32_t, double>> count_map;
for (size_t i = 0; i < nodes.size(); ++i) {
RETURN_SHELL_IF_GET_METRICS_FAILED(results[i], nodes[i], "sst");
RETURN_SHELL_IF_PARSE_METRICS_FAILED(
parse_sst_stat(results[i].body(), count_map[nodes[i].hp], disk_map[nodes[i].hp]),
nodes[i],
"parse sst stats");
}
::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("details");
if (detailed) {
tp_details.add_title("pidx");
tp_details.add_column("ballot");
tp_details.add_column("replica_count");
tp_details.add_column("primary");
tp_details.add_column("secondaries");
}
double disk_used_for_primary_replicas = 0;
int primary_replicas_count = 0;
double disk_used_for_all_replicas = 0;
int all_replicas_count = 0;
for (const auto &pc : pcs) {
std::string primary_str("-");
if (pc.hp_primary) {
bool disk_found = false;
double disk_value = 0;
auto f1 = disk_map.find(pc.hp_primary);
if (f1 != disk_map.end()) {
auto &sub_map = f1->second;
auto f2 = sub_map.find(pc.pid.get_partition_index());
if (f2 != sub_map.end()) {
disk_found = true;
disk_value = f2->second;
disk_used_for_primary_replicas += disk_value;
primary_replicas_count++;
disk_used_for_all_replicas += disk_value;
all_replicas_count++;
}
}
bool count_found = false;
double count_value = 0;
auto f3 = count_map.find(pc.hp_primary);
if (f3 != count_map.end()) {
auto &sub_map = f3->second;
auto f4 = sub_map.find(pc.pid.get_partition_index());
if (f4 != sub_map.end()) {
count_found = true;
count_value = f4->second;
}
}
std::stringstream oss;
oss << replication_ddl_client::node_name(pc.hp_primary, resolve_ip) << "(";
if (disk_found)
oss << disk_value;
else
oss << "-";
oss << ",";
if (count_found)
oss << "#" << count_value;
else
oss << "-";
oss << ")";
primary_str = oss.str();
}
std::string secondary_str;
{
std::stringstream oss;
oss << "[";
for (int j = 0; j < pc.hp_secondaries.size(); j++) {
if (j != 0)
oss << ",";
bool found = false;
double value = 0;
auto f1 = disk_map.find(pc.hp_secondaries[j]);
if (f1 != disk_map.end()) {
auto &sub_map = f1->second;
auto f2 = sub_map.find(pc.pid.get_partition_index());
if (f2 != sub_map.end()) {
found = true;
value = f2->second;
disk_used_for_all_replicas += value;
all_replicas_count++;
}
}
bool count_found = false;
double count_value = 0;
auto f3 = count_map.find(pc.hp_secondaries[j]);
if (f3 != count_map.end()) {
auto &sub_map = f3->second;
auto f3 = sub_map.find(pc.pid.get_partition_index());
if (f3 != sub_map.end()) {
count_found = true;
count_value = f3->second;
}
}
oss << replication_ddl_client::node_name(pc.hp_secondaries[j], resolve_ip) << "(";
if (found)
oss << value;
else
oss << "-";
oss << ",";
if (count_found)
oss << "#" << count_value;
else
oss << "-";
oss << ")";
}
oss << "]";
secondary_str = oss.str();
}
if (detailed) {
tp_details.add_row(std::to_string(pc.pid.get_partition_index()));
tp_details.append_data(pc.ballot);
tp_details.append_data(fmt::format(
"{}/{}", pc.hp_secondaries.size() + (pc.hp_primary ? 1 : 0), pc.max_replica_count));
tp_details.append_data(primary_str);
tp_details.append_data(secondary_str);
}
}
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.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) {
mtp.add(std::move(tp_details));
}
mtp.output(out, json ? tp_output_format::kJsonPretty : tp_output_format::kTabular);
return true;
}