diff --git a/src/shell/command_helper.h b/src/shell/command_helper.h index bf6e10f99f..e67cee1d97 100644 --- a/src/shell/command_helper.h +++ b/src/shell/command_helper.h @@ -657,6 +657,70 @@ inline bool decode_node_perf_counter_info(const dsn::rpc_address &node_addr, return true; } +// rows: key-app name, value-perf counters for each partition +inline bool get_app_partition_stat(shell_context *sc, + std::map> &rows) +{ + // get apps and nodes + std::vector<::dsn::app_info> apps; + std::vector nodes; + if (!get_apps_and_nodes(sc, apps, nodes)) { + return false; + } + + // get app_id --> app_name + std::map app_id_name; + for (::dsn::app_info &app : apps) { + app_id_name[app.app_id] = app.app_name; + rows[app.app_name].resize(app.partition_count); + } + + // get app_id --> partitions + std::map> app_partitions; + if (!get_app_partitions(sc, apps, app_partitions)) { + return false; + } + + // get all of the perf counters with format ".*@.*" + ::dsn::command command; + command.cmd = "perf-counters"; + char tmp[256]; + sprintf(tmp, ".*@.*"); + command.arguments.emplace_back(tmp); + std::vector> results; + call_remote_command(sc, nodes, command, results); + + for (int i = 0; i < nodes.size(); ++i) { + // decode info of perf-counters on node i + dsn::perf_counter_info info; + if (!decode_node_perf_counter_info(nodes[i].address, results[i], info)) { + return false; + } + + for (dsn::perf_counter_metric &m : info.counters) { + // get app_id/partition_id/counter_name from the name of perf-counter + int32_t app_id_x, partition_index_x; + std::string counter_name; + if (!parse_app_pegasus_perf_counter_name( + m.name, app_id_x, partition_index_x, counter_name)) { + continue; + } + + // only on primary partition will be counted + auto find = app_partitions.find(app_id_x); + if (find != app_partitions.end() && + find->second[partition_index_x].primary == nodes[i].address) { + const std::string &app_name = app_id_name[app_id_x]; + row_data &row = rows[app_name][partition_index_x]; + row.row_name = std::to_string(partition_index_x); + row.app_id = app_id_x; + update_app_pegasus_perf_counter(row, counter_name, m.value); + } + } + } + return true; +} + inline bool get_app_stat(shell_context *sc, const std::string &app_name, std::vector &rows) {