in src/client/replication_ddl_client.cpp [695:825]
dsn::error_code replication_ddl_client::list_app(const std::string &app_name,
bool detailed,
bool json,
const std::string &file_name,
bool resolve_ip)
{
dsn::utils::multi_table_printer mtp;
dsn::utils::table_printer tp_params("parameters");
if (!(app_name.empty() && file_name.empty())) {
if (!app_name.empty())
tp_params.add_row_name_and_data("app_name", app_name);
if (!file_name.empty())
tp_params.add_row_name_and_data("out_file", file_name);
}
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<partition_configuration> partitions;
dsn::error_code err = list_app(app_name, app_id, partition_count, partitions);
if (err != dsn::ERR_OK) {
return err;
}
if (!partitions.empty()) {
max_replica_count = partitions[0].max_replica_count;
}
// print query_cfg_response
std::streambuf *buf;
std::ofstream of;
if (!file_name.empty()) {
of.open(file_name);
buf = of.rdbuf();
} else {
buf = std::cout.rdbuf();
}
std::ostream out(buf);
dsn::utils::table_printer tp_general("general");
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);
mtp.add(std::move(tp_general));
if (detailed) {
dsn::utils::table_printer tp_details("replicas");
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");
std::map<rpc_address, std::pair<int, int>> node_stat;
int total_prim_count = 0;
int total_sec_count = 0;
int fully_healthy = 0;
int write_unhealthy = 0;
int read_unhealthy = 0;
for (const auto &p : partitions) {
int replica_count = 0;
if (!p.primary.is_invalid()) {
replica_count++;
node_stat[p.primary].first++;
total_prim_count++;
}
replica_count += p.secondaries.size();
total_sec_count += p.secondaries.size();
if (!p.primary.is_invalid()) {
if (replica_count >= p.max_replica_count)
fully_healthy++;
else if (replica_count < 2)
write_unhealthy++;
} else {
write_unhealthy++;
read_unhealthy++;
}
tp_details.add_row(p.pid.get_partition_index());
tp_details.append_data(p.ballot);
std::stringstream oss;
oss << replica_count << "/" << p.max_replica_count;
tp_details.append_data(oss.str());
tp_details.append_data(
(p.primary.is_invalid() ? "-" : host_name_resolve(resolve_ip,
p.primary.to_std_string())));
oss.str("");
oss << "[";
// TODO (yingchun) join
for (int j = 0; j < p.secondaries.size(); j++) {
if (j != 0)
oss << ",";
oss << host_name_resolve(resolve_ip, p.secondaries[j].to_std_string());
node_stat[p.secondaries[j]].second++;
}
oss << "]";
tp_details.append_data(oss.str());
}
mtp.add(std::move(tp_details));
// 'node' section.
dsn::utils::table_printer tp_nodes("nodes");
tp_nodes.add_title("node");
tp_nodes.add_column("primary");
tp_nodes.add_column("secondary");
tp_nodes.add_column("total");
for (auto &kv : node_stat) {
tp_nodes.add_row(host_name_resolve(resolve_ip, kv.first.to_std_string()));
tp_nodes.append_data(kv.second.first);
tp_nodes.append_data(kv.second.second);
tp_nodes.append_data(kv.second.first + kv.second.second);
}
tp_nodes.add_row("");
tp_nodes.append_data(total_prim_count);
tp_nodes.append_data(total_sec_count);
tp_nodes.append_data(total_prim_count + total_sec_count);
mtp.add(std::move(tp_nodes));
// healthy partition count section.
dsn::utils::table_printer tp_hpc("healthy");
tp_hpc.add_row_name_and_data("fully_healthy_partition_count", fully_healthy);
tp_hpc.add_row_name_and_data("unhealthy_partition_count", partition_count - fully_healthy);
tp_hpc.add_row_name_and_data("write_unhealthy_partition_count", write_unhealthy);
tp_hpc.add_row_name_and_data("read_unhealthy_partition_count", read_unhealthy);
mtp.add(std::move(tp_hpc));
}
mtp.output(out, json ? tp_output_format::kJsonPretty : tp_output_format::kTabular);
return dsn::ERR_OK;
#undef RESOLVE
}