From d9f409cd08c1a464737beb3cc21757801bd9aed9 Mon Sep 17 00:00:00 2001 From: qinzuoyan Date: Sun, 16 Jun 2019 20:40:44 +0800 Subject: [PATCH] perf-counter: add remote command to get perf-counters by substr/prefix/postfix --- include/dsn/perf_counter/perf_counters.h | 9 ++- src/core/perf_counter/perf_counters.cpp | 74 +++++++++++++++++++++++- 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/include/dsn/perf_counter/perf_counters.h b/include/dsn/perf_counter/perf_counters.h index ca298c1459..2b43087750 100644 --- a/include/dsn/perf_counter/perf_counters.h +++ b/include/dsn/perf_counter/perf_counters.h @@ -119,11 +119,18 @@ class perf_counters : public utils::singleton const snapshot_iterator &v, std::vector *found) const; - // this function collects all counters to perf_counter_info which matches + // this function collects all counters to perf_counter_info which match // any of the regular expressions in args and returns the json representation // of perf_counter_info std::string list_snapshot_by_regexp(const std::vector &args) const; + // this function collects all counters to perf_counter_info which satisfy + // any of the filters generated by args and returns the json representation + // of perf_counter_info + std::string list_snapshot_by_literal( + const std::vector &args, + std::function filter) const; + private: // full_name = perf_counter::build_full_name(...); perf_counter *new_counter(const char *app, diff --git a/src/core/perf_counter/perf_counters.cpp b/src/core/perf_counter/perf_counters.cpp index ba21e8c52c..cc74c3dd45 100644 --- a/src/core/perf_counter/perf_counters.cpp +++ b/src/core/perf_counter/perf_counters.cpp @@ -47,11 +47,45 @@ perf_counters::perf_counters() { command_manager::instance().register_command( {"perf-counters"}, - "perf-counters - query perf counters, supporting filter by POSIX basic regular expressions", - "perf-counters [name-filter]...", + "perf-counters - query perf counters, filtered by OR of POSIX basic regular expressions", + "perf-counters [regexp]...", [](const std::vector &args) { return perf_counters::instance().list_snapshot_by_regexp(args); }); + command_manager::instance().register_command( + {"perf-counters-by-substr"}, + "perf-counters-by-substr - query perf counters, filtered by OR of substrs", + "perf-counters-by-substr [substr]...", + [](const std::vector &args) { + return perf_counters::instance().list_snapshot_by_literal( + args, [](const std::string &arg, const counter_snapshot &cs) { + return cs.name.find(arg) != std::string::npos; + }); + }); + command_manager::instance().register_command( + {"perf-counters-by-prefix"}, + "perf-counters-by-prefix - query perf counters, filtered by OR of prefix strings", + "perf-counters-by-prefix [prefix]...", + [](const std::vector &args) { + return perf_counters::instance().list_snapshot_by_literal( + args, [](const std::string &arg, const counter_snapshot &cs) { + return cs.name.size() >= arg.size() && + ::memcmp(cs.name.c_str(), arg.c_str(), arg.size()) == 0; + }); + }); + command_manager::instance().register_command( + {"perf-counters-by-postfix"}, + "perf-counters-by-postfix - query perf counters, filtered by OR of postfix strings", + "perf-counters-by-postfix [postfix]...", + [](const std::vector &args) { + return perf_counters::instance().list_snapshot_by_literal( + args, [](const std::string &arg, const counter_snapshot &cs) { + return cs.name.size() >= arg.size() && + ::memcmp(cs.name.c_str() + cs.name.size() - arg.size(), + arg.c_str(), + arg.size()) == 0; + }); + }); } perf_counters::~perf_counters() = default; @@ -201,6 +235,42 @@ std::string perf_counters::list_snapshot_by_regexp(const std::vector &args, + std::function filter) const +{ + perf_counter_info info; + + snapshot_iterator visitor = [&args, &info, &filter](const counter_snapshot &cs) { + bool matched = false; + if (args.empty()) { + matched = true; + } else { + for (auto &arg : args) { + if (filter(arg, cs)) { + matched = true; + break; + } + } + } + + if (matched) { + info.counters.emplace_back(cs.name.c_str(), cs.type, cs.value); + } + }; + iterate_snapshot(visitor); + info.result = "OK"; + + std::stringstream ss; + info.timestamp = _timestamp; + char buf[20]; + utils::time_ms_to_date_time(info.timestamp * 1000, buf, sizeof(buf)); + info.timestamp_str = buf; + info.encode_json_state(ss); + return ss.str(); +} + void perf_counters::take_snapshot() { builtin_counters::instance().update_counters();