From e6918187568dbd01842d8d1d2c808ce16a894239 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 21 Apr 2024 13:54:28 +0200 Subject: Adding upstream version 18.2.2. Signed-off-by: Daniel Baumann --- src/test/perf_counters.cc | 692 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 692 insertions(+) create mode 100644 src/test/perf_counters.cc (limited to 'src/test/perf_counters.cc') diff --git a/src/test/perf_counters.cc b/src/test/perf_counters.cc new file mode 100644 index 000000000..7ab9561bc --- /dev/null +++ b/src/test/perf_counters.cc @@ -0,0 +1,692 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ +#include "include/int_types.h" +#include "include/types.h" // FIXME: ordering shouldn't be important, but right + // now, this include has to come before the others. + + +#include "common/perf_counters_key.h" +#include "common/perf_counters_collection.h" +#include "common/admin_socket_client.h" +#include "common/ceph_context.h" +#include "common/config.h" +#include "common/errno.h" +#include "common/safe_io.h" + +#include "common/code_environment.h" +#include "global/global_context.h" +#include "global/global_init.h" +#include "include/msgr.h" // for CEPH_ENTITY_TYPE_CLIENT +#include "gtest/gtest.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common/common_init.h" + +using namespace std; + +int main(int argc, char **argv) { + map defaults = { + { "admin_socket", get_rand_socket_path() } + }; + std::vector args; + auto cct = global_init(&defaults, args, CEPH_ENTITY_TYPE_CLIENT, + CODE_ENVIRONMENT_UTILITY, + CINIT_FLAG_NO_DEFAULT_CONFIG_FILE| + CINIT_FLAG_NO_CCT_PERF_COUNTERS); + common_init_finish(g_ceph_context); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +TEST(PerfCounters, SimpleTest) { + AdminSocketClient client(get_rand_socket_path()); + 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 { + TEST_PERFCOUNTERS1_ELEMENT_FIRST = 200, + TEST_PERFCOUNTERS1_ELEMENT_1, + TEST_PERFCOUNTERS1_ELEMENT_2, + TEST_PERFCOUNTERS1_ELEMENT_3, + TEST_PERFCOUNTERS1_ELEMENT_LAST, +}; + +std::string sd(const char *c) +{ + std::string ret(c); + std::string::size_type sz = ret.size(); + for (std::string::size_type i = 0; i < sz; ++i) { + if (ret[i] == '\'') { + ret[i] = '\"'; + } + } + return ret; +} + +static PerfCounters* setup_test_perfcounters1(CephContext *cct) +{ + PerfCountersBuilder bld(cct, "test_perfcounter_1", + TEST_PERFCOUNTERS1_ELEMENT_FIRST, TEST_PERFCOUNTERS1_ELEMENT_LAST); + bld.add_u64(TEST_PERFCOUNTERS1_ELEMENT_1, "element1"); + bld.add_time(TEST_PERFCOUNTERS1_ELEMENT_2, "element2"); + bld.add_time_avg(TEST_PERFCOUNTERS1_ELEMENT_3, "element3"); + return bld.create_perf_counters(); +} + +TEST(PerfCounters, SinglePerfCounters) { + PerfCountersCollection *coll = g_ceph_context->get_perfcounters_collection(); + PerfCounters* fake_pf = setup_test_perfcounters1(g_ceph_context); + coll->add(fake_pf); + AdminSocketClient client(get_rand_socket_path()); + std::string msg; + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":0," + "\"element2\":0.000000000,\"element3\":{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}}}"), msg); + fake_pf->inc(TEST_PERFCOUNTERS1_ELEMENT_1); + fake_pf->tset(TEST_PERFCOUNTERS1_ELEMENT_2, utime_t(0, 500000000)); + fake_pf->tinc(TEST_PERFCOUNTERS1_ELEMENT_3, utime_t(100, 0)); + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":1," + "\"element2\":0.500000000,\"element3\":{\"avgcount\":1,\"sum\":100.000000000,\"avgtime\":100.000000000}}}"), msg); + fake_pf->tinc(TEST_PERFCOUNTERS1_ELEMENT_3, utime_t()); + fake_pf->tinc(TEST_PERFCOUNTERS1_ELEMENT_3, utime_t(20,0)); + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":1,\"element2\":0.500000000," + "\"element3\":{\"avgcount\":3,\"sum\":120.000000000,\"avgtime\":40.000000000}}}"), msg); + + fake_pf->reset(); + msg.clear(); + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":1," + "\"element2\":0.000000000,\"element3\":{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}}}"), msg); + +} + +enum { + TEST_PERFCOUNTERS2_ELEMENT_FIRST = 400, + TEST_PERFCOUNTERS2_ELEMENT_FOO, + TEST_PERFCOUNTERS2_ELEMENT_BAR, + TEST_PERFCOUNTERS2_ELEMENT_LAST, +}; + +static PerfCounters* setup_test_perfcounter2(CephContext *cct) +{ + PerfCountersBuilder bld(cct, "test_perfcounter_2", + TEST_PERFCOUNTERS2_ELEMENT_FIRST, TEST_PERFCOUNTERS2_ELEMENT_LAST); + bld.add_u64(TEST_PERFCOUNTERS2_ELEMENT_FOO, "foo"); + bld.add_time(TEST_PERFCOUNTERS2_ELEMENT_BAR, "bar"); + return bld.create_perf_counters(); +} + +TEST(PerfCounters, MultiplePerfCounters) { + PerfCountersCollection *coll = g_ceph_context->get_perfcounters_collection(); + coll->clear(); + PerfCounters* fake_pf1 = setup_test_perfcounters1(g_ceph_context); + PerfCounters* fake_pf2 = setup_test_perfcounter2(g_ceph_context); + coll->add(fake_pf1); + coll->add(fake_pf2); + AdminSocketClient client(get_rand_socket_path()); + std::string msg; + + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":0,\"element2\":0.000000000,\"element3\":" + "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg); + + fake_pf1->inc(TEST_PERFCOUNTERS1_ELEMENT_1); + fake_pf1->inc(TEST_PERFCOUNTERS1_ELEMENT_1, 5); + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":6,\"element2\":0.000000000,\"element3\":" + "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg); + + coll->reset(string("test_perfcounter_1")); + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":6,\"element2\":0.000000000,\"element3\":" + "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg); + + fake_pf1->inc(TEST_PERFCOUNTERS1_ELEMENT_1); + fake_pf1->inc(TEST_PERFCOUNTERS1_ELEMENT_1, 6); + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":13,\"element2\":0.000000000,\"element3\":" + "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg); + + coll->reset(string("all")); + msg.clear(); + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":13,\"element2\":0.000000000,\"element3\":" + "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg); + + coll->remove(fake_pf2); + delete fake_pf2; + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":13,\"element2\":0.000000000," + "\"element3\":{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}}}"), msg); + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf schema\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":{\"type\":2,\"metric_type\":\"gauge\",\"value_type\":\"integer\",\"description\":\"\",\"nick\":\"\",\"priority\":0,\"units\":\"none\"},\"element2\":{\"type\":1,\"metric_type\":\"gauge\",\"value_type\":\"real\",\"description\":\"\",\"nick\":\"\",\"priority\":0,\"units\":\"none\"},\"element3\":{\"type\":5,\"metric_type\":\"gauge\",\"value_type\":\"real-integer-pair\",\"description\":\"\",\"nick\":\"\",\"priority\":0,\"units\":\"none\"}}}"), msg); + coll->clear(); + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg)); + ASSERT_EQ("{}", msg); +} + +TEST(PerfCounters, ResetPerfCounters) { + AdminSocketClient client(get_rand_socket_path()); + std::string msg; + PerfCountersCollection *coll = g_ceph_context->get_perfcounters_collection(); + coll->clear(); + PerfCounters* fake_pf1 = setup_test_perfcounters1(g_ceph_context); + coll->add(fake_pf1); + + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf reset\", \"var\": \"all\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"success\":\"perf reset all\"}"), msg); + + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf reset\", \"var\": \"test_perfcounter_1\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"success\":\"perf reset test_perfcounter_1\"}"), msg); + + coll->clear(); + ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf reset\", \"var\": \"test_perfcounter_1\", \"format\": \"json\" }", &msg)); + ASSERT_EQ(sd("{\"error\":\"Not find: test_perfcounter_1\"}"), msg); +} + +enum { + TEST_PERFCOUNTERS3_ELEMENT_FIRST = 400, + TEST_PERFCOUNTERS3_ELEMENT_READ, + TEST_PERFCOUNTERS3_ELEMENT_LAST, +}; + +static std::shared_ptr setup_test_perfcounter3(CephContext* cct) { + PerfCountersBuilder bld(cct, "test_percounter_3", + TEST_PERFCOUNTERS3_ELEMENT_FIRST, TEST_PERFCOUNTERS3_ELEMENT_LAST); + bld.add_time_avg(TEST_PERFCOUNTERS3_ELEMENT_READ, "read_avg"); + std::shared_ptr p(bld.create_perf_counters()); + return p; +} + +static void counters_inc_test(std::shared_ptr fake_pf) { + int i = 100000; + utime_t t; + + // set to 1 nsec + t.set_from_double(0.000000001); + while (i--) { + // increase by one, make sure data.u64 equal to data.avgcount + fake_pf->tinc(TEST_PERFCOUNTERS3_ELEMENT_READ, t); + } +} + +static void counters_readavg_test(std::shared_ptr fake_pf) { + int i = 100000; + + while (i--) { + std::pair dat = fake_pf->get_tavg_ns(TEST_PERFCOUNTERS3_ELEMENT_READ); + // sum and count should be identical as we increment TEST_PERCOUNTERS_ELEMENT_READ by 1 nsec eveytime + ASSERT_EQ(dat.first, dat.second); + } +} + +TEST(PerfCounters, read_avg) { + std::shared_ptr fake_pf = setup_test_perfcounter3(g_ceph_context); + + std::thread t1(counters_inc_test, fake_pf); + std::thread t2(counters_readavg_test, fake_pf); + t2.join(); + t1.join(); +} + +static PerfCounters* setup_test_perfcounter4(std::string name, CephContext *cct) +{ + PerfCountersBuilder bld(cct, name, + TEST_PERFCOUNTERS2_ELEMENT_FIRST, TEST_PERFCOUNTERS2_ELEMENT_LAST); + bld.add_u64(TEST_PERFCOUNTERS2_ELEMENT_FOO, "foo"); + bld.add_time(TEST_PERFCOUNTERS2_ELEMENT_BAR, "bar"); + + PerfCounters* counters = bld.create_perf_counters(); + cct->get_perfcounters_collection()->add(counters); + return counters; +} + +TEST(PerfCounters, TestLabeledCountersOnly) { + constexpr std::string_view empty_dump_format_raw = R"({} +)"; + 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" + }, + "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 + } + } + ] +} +)", message); + + // make sure labeled counters are not in normal perf dump + ASSERT_EQ("", client.do_request(R"({ "prefix": "perf dump", "format": "raw" })", &message)); + ASSERT_EQ(empty_dump_format_raw, message); + + ASSERT_EQ("", client.do_request(R"({ "prefix": "counter schema", "format": "raw" })", &message)); + ASSERT_EQ(R"({ + "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" + } + } + }, + { + "labels": { + "label1": "val3" + }, + "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" + }, + "bar": { + "type": 1, + "metric_type": "gauge", + "value_type": "real", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + } + } + } + ] +} +)", message); + + // make sure labeled counters are not in normal perf schema + ASSERT_EQ("", client.do_request(R"({ "prefix": "perf schema", "format": "raw" })", &message)); + ASSERT_EQ(empty_dump_format_raw, message); + + g_ceph_context->get_perfcounters_collection()->clear(); +} + +TEST(PerfCounters, TestLabelStrings) { + AdminSocketClient client(get_rand_socket_path()); + std::string message; + + // test empty val in a label pair will get the label pair added but empty key will not + std::string counter_key1 = ceph::perf_counters::key_create("good_ctrs", {{"label3", "val4"}, {"label1", ""}}); + PerfCounters* counters1 = setup_test_perfcounter4(counter_key1, g_ceph_context); + + std::string counter_key2 = ceph::perf_counters::key_create("bad_ctrs", {{"", "val4"}, {"label1", "val1"}}); + PerfCounters* counters2 = setup_test_perfcounter4(counter_key2, g_ceph_context); + + counters1->set(TEST_PERFCOUNTERS2_ELEMENT_FOO, 2); + counters2->set(TEST_PERFCOUNTERS2_ELEMENT_FOO, 4); + + // test empty keys in each of the label pairs will get only the labels section added + std::string counter_key3 = ceph::perf_counters::key_create("bad_ctrs2", {{"", "val2"}, {"", "val33"}}); + PerfCounters* counters3 = setup_test_perfcounter4(counter_key3, g_ceph_context); + counters3->set(TEST_PERFCOUNTERS2_ELEMENT_FOO, 6); + + // a key with a somehow odd number of entries after the the key name will omit final unfinished label pair + std::string counter_key4 = "too_many_delimiters"; + counter_key4 += '\0'; + counter_key4 += "label1"; + counter_key4 += '\0'; + counter_key4 += "val1"; + counter_key4 += '\0'; + counter_key4 += "label2"; + counter_key4 += '\0'; + PerfCounters* counters4 = setup_test_perfcounter4(counter_key4, g_ceph_context); + counters4->set(TEST_PERFCOUNTERS2_ELEMENT_FOO, 8); + + // test unlabeled perf counters are in the counter dump with labels and counters sections + std::string counter_key5 = "only_key"; + PerfCounters* no_label_counters = setup_test_perfcounter4(counter_key5, g_ceph_context); + no_label_counters->set(TEST_PERFCOUNTERS2_ELEMENT_FOO, 4); + + 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_ctrs2": [ + { + "labels": {}, + "counters": { + "foo": 6, + "bar": 0.000000000 + } + } + ], + "good_ctrs": [ + { + "labels": { + "label1": "", + "label3": "val4" + }, + "counters": { + "foo": 2, + "bar": 0.000000000 + } + } + ], + "only_key": [ + { + "labels": {}, + "counters": { + "foo": 4, + "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" + }, + "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" + }, + "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" + }, + "bar": { + "type": 1, + "metric_type": "gauge", + "value_type": "real", + "description": "", + "nick": "", + "priority": 0, + "units": "none" + } + } + } + ] +} +)", message); + + // test unlabeled perf counters are in the perf dump without the labels and counters section + ASSERT_EQ("", client.do_request(R"({ "prefix": "perf dump", "format": "raw" })", &message)); + ASSERT_EQ(R"({ + "only_key": { + "foo": 4, + "bar": 0.000000000 + } +} +)", message); + + // test unlabeled perf counters are in the perf schema without the labels and counters section + ASSERT_EQ("", client.do_request(R"({ "prefix": "perf schema", "format": "raw" })", &message)); + ASSERT_EQ(R"({ + "only_key": { + "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); + + g_ceph_context->get_perfcounters_collection()->clear(); +} -- cgit v1.2.3