From: Ali Maredia Date: Thu, 1 Jun 2023 20:18:26 +0000 (-0400) Subject: common: `counter dump` command revision X-Git-Tag: v18.1.3~12^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=f6304a079a751dda164ab3afa88a22ae41cfd123;p=ceph.git common: `counter dump` command revision `counter dump` now emits an array of pairs for each individual key. Commit includes revisions to perf counters unit test. Fixes: https://tracker.ceph.com/issues/61587 Signed-off-by: Ali Maredia (cherry picked from commit 78a148869389aa8df57596698c319de807535df8) --- diff --git a/doc/dev/perf_counters.rst b/doc/dev/perf_counters.rst index b71939282eb55..a64d14d33bd0e 100644 --- a/doc/dev/perf_counters.rst +++ b/doc/dev/perf_counters.rst @@ -208,31 +208,32 @@ A Ceph daemon has the ability to emit a set of perf counter instances with varyi For example, the below counters show the number of put requests for different users on different buckets:: { - "rgw": { - "labels": { - "Bucket: "bkt1", - "User: "user1", - }, - "counters": { - "put": 1, - }, - }, - "rgw": { - "labels": { - }, - "counters": { - "put": 4, - }, - }, - "rgw": { - "labels": { - "Bucket: "bkt1", - "User: "user2", - }, - "counters": { - "put": 3, - }, - } + "rgw": [ + { + "labels": { + "Bucket: "bkt1", + "User: "user1", + }, + "counters": { + "put": 1, + }, + }, + { + "labels": {}, + "counters": { + "put": 4, + }, + }, + { + "labels": { + "Bucket: "bkt1", + "User: "user2", + }, + "counters": { + "put": 3, + }, + }, + ] } All labeled and unlabeled perf counters can be viewed with ``ceph daemon {daemon id} counter dump``. diff --git a/src/common/perf_counters.cc b/src/common/perf_counters.cc index 134c8efe78984..b5e361b505cd3 100644 --- a/src/common/perf_counters.cc +++ b/src/common/perf_counters.cc @@ -136,11 +136,32 @@ void PerfCountersCollectionImpl::dump_formatted_generic( { f->open_object_section("perfcounter_collection"); - for (perf_counters_set_t::iterator l = m_loggers.begin(); - l != m_loggers.end(); ++l) { - // Optionally filter on logger name, pass through counter filter - if (logger.empty() || (*l)->get_name() == logger) { - (*l)->dump_formatted_generic(f, schema, histograms, dump_labeled, counter); + if (dump_labeled) { + std::string prev_key_name; + for (auto l = m_loggers.begin(); l != m_loggers.end(); ++l) { + std::string_view key_name = ceph::perf_counters::key_name((*l)->get_name()); + if (key_name != prev_key_name) { + // close previous set of counters before dumping new one + if (!prev_key_name.empty()) { + f->close_section(); // array section + } + prev_key_name = key_name; + + f->open_array_section(key_name); + (*l)->dump_formatted_generic(f, schema, histograms, true, ""); + } else { + (*l)->dump_formatted_generic(f, schema, histograms, true, ""); + } + } + if (!m_loggers.empty()) { + f->close_section(); // final array section + } + } else { + for (auto l = m_loggers.begin(); l != m_loggers.end(); ++l) { + // Optionally filter on logger name, pass through counter filter + if (logger.empty() || (*l)->get_name() == logger) { + (*l)->dump_formatted_generic(f, schema, histograms, false, counter); + } } } f->close_section(); @@ -359,9 +380,7 @@ void PerfCounters::dump_formatted_generic(Formatter *f, bool schema, bool histograms, bool dump_labeled, const std::string &counter) const { if (dump_labeled) { - std::string_view perf_counter_name = ceph::perf_counters::key_name(m_name); - f->open_object_section(perf_counter_name); - + f->open_object_section(""); // should be enclosed by array f->open_object_section("labels"); for (auto label : ceph::perf_counters::key_labels(m_name)) { // don't dump labels with empty label names diff --git a/src/test/perf_counters.cc b/src/test/perf_counters.cc index 31b10fff1679a..7ab9561bc19b2 100644 --- a/src/test/perf_counters.cc +++ b/src/test/perf_counters.cc @@ -68,6 +68,8 @@ TEST(PerfCounters, SimpleTest) { std::string message; ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\" }", &message)); ASSERT_EQ("{}\n", message); + ASSERT_EQ("", client.do_request("{ \"prefix\": \"counter dump\" }", &message)); + ASSERT_EQ("{}\n", message); } enum { @@ -275,36 +277,52 @@ TEST(PerfCounters, TestLabeledCountersOnly) { )"; std::string counter_key1 = ceph::perf_counters::key_create("name1", {{"label1", "val1"}}); std::string counter_key2 = ceph::perf_counters::key_create("name2", {{"label2", "val2"}}); + std::string counter_key3 = ceph::perf_counters::key_create("name1", {{"label1", "val3"}}); PerfCounters* counters1 = setup_test_perfcounter4(counter_key1, g_ceph_context); PerfCounters* counters2 = setup_test_perfcounter4(counter_key2, g_ceph_context); + PerfCounters* counters3 = setup_test_perfcounter4(counter_key3, g_ceph_context); counters1->inc(TEST_PERFCOUNTERS2_ELEMENT_FOO, 3); counters1->dec(TEST_PERFCOUNTERS2_ELEMENT_FOO, 1); counters2->set(TEST_PERFCOUNTERS2_ELEMENT_FOO, 4); + counters3->inc(TEST_PERFCOUNTERS2_ELEMENT_FOO, 3); AdminSocketClient client(get_rand_socket_path()); std::string message; ASSERT_EQ("", client.do_request(R"({ "prefix": "counter dump", "format": "raw" })", &message)); ASSERT_EQ(R"({ - "name1": { - "labels": { - "label1": "val1" + "name1": [ + { + "labels": { + "label1": "val1" + }, + "counters": { + "foo": 2, + "bar": 0.000000000 + } }, - "counters": { - "foo": 2, - "bar": 0.000000000 + { + "labels": { + "label1": "val3" + }, + "counters": { + "foo": 3, + "bar": 0.000000000 + } } - }, - "name2": { - "labels": { - "label2": "val2" - }, - "counters": { - "foo": 4, - "bar": 0.000000000 + ], + "name2": [ + { + "labels": { + "label2": "val2" + }, + "counters": { + "foo": 4, + "bar": 0.000000000 + } } - } + ] } )", message); @@ -314,56 +332,85 @@ TEST(PerfCounters, TestLabeledCountersOnly) { ASSERT_EQ("", client.do_request(R"({ "prefix": "counter schema", "format": "raw" })", &message)); ASSERT_EQ(R"({ - "name1": { - "labels": { - "label1": "val1" + "name1": [ + { + "labels": { + "label1": "val1" + }, + "counters": { + "foo": { + "type": 2, + "metric_type": "gauge", + "value_type": "integer", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + }, + "bar": { + "type": 1, + "metric_type": "gauge", + "value_type": "real", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + } + } }, - "counters": { - "foo": { - "type": 2, - "metric_type": "gauge", - "value_type": "integer", - "description": "", - "nick": "", - "priority": 0, - "units": "none" + { + "labels": { + "label1": "val3" }, - "bar": { - "type": 1, - "metric_type": "gauge", - "value_type": "real", - "description": "", - "nick": "", - "priority": 0, - "units": "none" + "counters": { + "foo": { + "type": 2, + "metric_type": "gauge", + "value_type": "integer", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + }, + "bar": { + "type": 1, + "metric_type": "gauge", + "value_type": "real", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + } } } - }, - "name2": { - "labels": { - "label2": "val2" - }, - "counters": { - "foo": { - "type": 2, - "metric_type": "gauge", - "value_type": "integer", - "description": "", - "nick": "", - "priority": 0, - "units": "none" + ], + "name2": [ + { + "labels": { + "label2": "val2" }, - "bar": { - "type": 1, - "metric_type": "gauge", - "value_type": "real", - "description": "", - "nick": "", - "priority": 0, - "units": "none" + "counters": { + "foo": { + "type": 2, + "metric_type": "gauge", + "value_type": "integer", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + }, + "bar": { + "type": 1, + "metric_type": "gauge", + "value_type": "real", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + } } } - } + ] } )", message); @@ -412,176 +459,196 @@ TEST(PerfCounters, TestLabelStrings) { ASSERT_EQ("", client.do_request(R"({ "prefix": "counter dump", "format": "raw" })", &message)); ASSERT_EQ(R"({ - "bad_ctrs": { - "labels": { - "label1": "val1" - }, - "counters": { - "foo": 4, - "bar": 0.000000000 + "bad_ctrs": [ + { + "labels": { + "label1": "val1" + }, + "counters": { + "foo": 4, + "bar": 0.000000000 + } } - }, - "bad_ctrs2": { - "labels": {}, - "counters": { - "foo": 6, - "bar": 0.000000000 + ], + "bad_ctrs2": [ + { + "labels": {}, + "counters": { + "foo": 6, + "bar": 0.000000000 + } } - }, - "good_ctrs": { - "labels": { - "label1": "", - "label3": "val4" - }, - "counters": { - "foo": 2, - "bar": 0.000000000 + ], + "good_ctrs": [ + { + "labels": { + "label1": "", + "label3": "val4" + }, + "counters": { + "foo": 2, + "bar": 0.000000000 + } } - }, - "only_key": { - "labels": {}, - "counters": { - "foo": 4, - "bar": 0.000000000 + ], + "only_key": [ + { + "labels": {}, + "counters": { + "foo": 4, + "bar": 0.000000000 + } } - }, - "too_many_delimiters": { - "labels": { - "label1": "val1" - }, - "counters": { - "foo": 8, - "bar": 0.000000000 + ], + "too_many_delimiters": [ + { + "labels": { + "label1": "val1" + }, + "counters": { + "foo": 8, + "bar": 0.000000000 + } } - } + ] } )", message); // test unlabeled perf counters are in the schema dump with labels and counters sections ASSERT_EQ("", client.do_request(R"({ "prefix": "counter schema", "format": "raw" })", &message)); ASSERT_EQ(R"({ - "bad_ctrs": { - "labels": { - "label1": "val1" - }, - "counters": { - "foo": { - "type": 2, - "metric_type": "gauge", - "value_type": "integer", - "description": "", - "nick": "", - "priority": 0, - "units": "none" + "bad_ctrs": [ + { + "labels": { + "label1": "val1" }, - "bar": { - "type": 1, - "metric_type": "gauge", - "value_type": "real", - "description": "", - "nick": "", - "priority": 0, - "units": "none" + "counters": { + "foo": { + "type": 2, + "metric_type": "gauge", + "value_type": "integer", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + }, + "bar": { + "type": 1, + "metric_type": "gauge", + "value_type": "real", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + } } } - }, - "bad_ctrs2": { - "labels": {}, - "counters": { - "foo": { - "type": 2, - "metric_type": "gauge", - "value_type": "integer", - "description": "", - "nick": "", - "priority": 0, - "units": "none" - }, - "bar": { - "type": 1, - "metric_type": "gauge", - "value_type": "real", - "description": "", - "nick": "", - "priority": 0, - "units": "none" + ], + "bad_ctrs2": [ + { + "labels": {}, + "counters": { + "foo": { + "type": 2, + "metric_type": "gauge", + "value_type": "integer", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + }, + "bar": { + "type": 1, + "metric_type": "gauge", + "value_type": "real", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + } } } - }, - "good_ctrs": { - "labels": { - "label1": "", - "label3": "val4" - }, - "counters": { - "foo": { - "type": 2, - "metric_type": "gauge", - "value_type": "integer", - "description": "", - "nick": "", - "priority": 0, - "units": "none" + ], + "good_ctrs": [ + { + "labels": { + "label1": "", + "label3": "val4" }, - "bar": { - "type": 1, - "metric_type": "gauge", - "value_type": "real", - "description": "", - "nick": "", - "priority": 0, - "units": "none" + "counters": { + "foo": { + "type": 2, + "metric_type": "gauge", + "value_type": "integer", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + }, + "bar": { + "type": 1, + "metric_type": "gauge", + "value_type": "real", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + } } } - }, - "only_key": { - "labels": {}, - "counters": { - "foo": { - "type": 2, - "metric_type": "gauge", - "value_type": "integer", - "description": "", - "nick": "", - "priority": 0, - "units": "none" - }, - "bar": { - "type": 1, - "metric_type": "gauge", - "value_type": "real", - "description": "", - "nick": "", - "priority": 0, - "units": "none" + ], + "only_key": [ + { + "labels": {}, + "counters": { + "foo": { + "type": 2, + "metric_type": "gauge", + "value_type": "integer", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + }, + "bar": { + "type": 1, + "metric_type": "gauge", + "value_type": "real", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + } } } - }, - "too_many_delimiters": { - "labels": { - "label1": "val1" - }, - "counters": { - "foo": { - "type": 2, - "metric_type": "gauge", - "value_type": "integer", - "description": "", - "nick": "", - "priority": 0, - "units": "none" + ], + "too_many_delimiters": [ + { + "labels": { + "label1": "val1" }, - "bar": { - "type": 1, - "metric_type": "gauge", - "value_type": "real", - "description": "", - "nick": "", - "priority": 0, - "units": "none" + "counters": { + "foo": { + "type": 2, + "metric_type": "gauge", + "value_type": "integer", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + }, + "bar": { + "type": 1, + "metric_type": "gauge", + "value_type": "real", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + } } } - } + ] } )", message);