in src/client/replication_ddl_client.cpp [321:484]
error_s replication_ddl_client::list_apps(bool detailed,
bool json,
const std::string &output_file,
dsn::app_status::type status,
const std::string &app_name_pattern,
utils::pattern_match_type::type match_type)
{
std::vector<::dsn::app_info> apps;
{
const auto &result = list_apps(status, app_name_pattern, match_type, apps);
if (!result) {
return result;
}
}
size_t max_app_name_size = 20;
for (const auto &app : apps) {
max_app_name_size = std::max(max_app_name_size, app.app_name.size() + 2);
}
dsn::utils::multi_table_printer multi_printer;
dsn::utils::table_printer tp_general("general_info");
tp_general.add_title("app_id");
tp_general.add_column("status");
tp_general.add_column("app_name");
tp_general.add_column("app_type");
tp_general.add_column("partition_count");
tp_general.add_column("replica_count");
tp_general.add_column("is_stateful");
tp_general.add_column("create_time");
tp_general.add_column("drop_time");
tp_general.add_column("drop_expire");
tp_general.add_column("envs_count");
tp_general.add_column("atomic_idempotent");
int available_app_count = 0;
for (const auto &info : apps) {
std::string status_str = enum_to_string(info.status);
status_str = status_str.substr(status_str.find("AS_") + 3);
std::string create_time = "-";
if (info.create_second > 0) {
char ts_buf[20] = {0};
dsn::utils::time_ms_to_date_time((uint64_t)info.create_second * 1000, ts_buf, 20);
ts_buf[10] = '_';
create_time = ts_buf;
}
std::string drop_time = "-";
std::string drop_expire_time = "-";
if (info.status == app_status::AS_AVAILABLE) {
available_app_count++;
} else if (info.status == app_status::AS_DROPPED && info.expire_second > 0) {
if (info.drop_second > 0) {
char ts_buf[20] = {0};
dsn::utils::time_ms_to_date_time((uint64_t)info.drop_second * 1000, ts_buf, 20);
ts_buf[10] = '_';
drop_time = ts_buf;
}
if (info.expire_second > 0) {
char ts_buf[20] = {0};
dsn::utils::time_ms_to_date_time((uint64_t)info.expire_second * 1000, ts_buf, 20);
ts_buf[10] = '_';
drop_expire_time = ts_buf;
}
}
tp_general.add_row(info.app_id);
tp_general.append_data(status_str);
tp_general.append_data(info.app_name);
tp_general.append_data(info.app_type);
tp_general.append_data(info.partition_count);
tp_general.append_data(info.max_replica_count);
tp_general.append_data(info.is_stateful);
tp_general.append_data(create_time);
tp_general.append_data(drop_time);
tp_general.append_data(drop_expire_time);
tp_general.append_data(info.envs.size());
tp_general.append_data(info.atomic_idempotent);
}
multi_printer.add(std::move(tp_general));
int total_fully_healthy_app_count = 0;
int total_unhealthy_app_count = 0;
int total_write_unhealthy_app_count = 0;
int total_read_unhealthy_app_count = 0;
if (detailed && available_app_count > 0) {
dsn::utils::table_printer tp_health("healthy_info");
tp_health.add_title("app_id");
tp_health.add_column("app_name");
tp_health.add_column("partition_count");
tp_health.add_column("fully_healthy");
tp_health.add_column("unhealthy");
tp_health.add_column("write_unhealthy");
tp_health.add_column("read_unhealthy");
for (const auto &info : apps) {
if (info.status != app_status::AS_AVAILABLE) {
continue;
}
int32_t app_id = 0;
int32_t partition_count = 0;
std::vector<partition_configuration> pcs;
const auto &err = list_app(info.app_name, app_id, partition_count, pcs);
if (err != ERR_OK) {
LOG_ERROR("list app({}) failed, err={}", info.app_name, err);
return error_s::make(err);
}
CHECK_EQ(info.app_id, app_id);
CHECK_EQ(info.partition_count, partition_count);
int fully_healthy = 0;
int write_unhealthy = 0;
int read_unhealthy = 0;
for (const auto &pc : pcs) {
int replica_count = 0;
if (pc.hp_primary) {
replica_count++;
}
replica_count += pc.hp_secondaries.size();
if (pc.hp_primary) {
if (replica_count >= pc.max_replica_count) {
fully_healthy++;
} else if (replica_count < 2) {
write_unhealthy++;
}
} else {
write_unhealthy++;
read_unhealthy++;
}
}
tp_health.add_row(info.app_id);
tp_health.append_data(info.app_name);
tp_health.append_data(info.partition_count);
tp_health.append_data(fully_healthy);
tp_health.append_data(info.partition_count - fully_healthy);
tp_health.append_data(write_unhealthy);
tp_health.append_data(read_unhealthy);
if (fully_healthy == info.partition_count) {
++total_fully_healthy_app_count;
} else {
++total_unhealthy_app_count;
}
if (write_unhealthy > 0) {
++total_write_unhealthy_app_count;
}
if (read_unhealthy > 0) {
++total_read_unhealthy_app_count;
}
}
multi_printer.add(std::move(tp_health));
}
dsn::utils::table_printer tp_count("summary");
tp_count.add_row_name_and_data("total_app_count", available_app_count);
if (detailed && available_app_count > 0) {
tp_count.add_row_name_and_data("fully_healthy_app_count", total_fully_healthy_app_count);
tp_count.add_row_name_and_data("unhealthy_app_count", total_unhealthy_app_count);
tp_count.add_row_name_and_data("write_unhealthy_app_count",
total_write_unhealthy_app_count);
tp_count.add_row_name_and_data("read_unhealthy_app_count", total_read_unhealthy_app_count);
}
multi_printer.add(std::move(tp_count));
dsn::utils::output(output_file, json, multi_printer);
return error_s::ok();
}