`client_max_retries_on_remount_failure` and move it from mds.yaml.in to
mds-client.yaml.in because this option was only used by MDS client from its
birth.
+* The `perf dump` and `perf schema` commands are deprecated in favor of new
+ `counter dump` and `counter schema` commands. These new commands add support
+ for labeled perf counters and also emit existing unlabeled perf counters. Some
+ unlabeled perf counters may become labeled in future releases
+ and as such will no longer be emitted by the `perf dump` and `perf schema`
+ commands.
>=17.2.1
}
}
+Labeled Perf Counters
+---------------------
+
+A Ceph daemon has the ability to emit a set of perf counter instances with varying labels. These counters are intended for visualizing specific metrics in 3rd party tools like Prometheus and Grafana.
+
+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,
+ },
+ }
+ }
+
+All labeled and unlabeled perf counters can be viewed with ``ceph daemon {daemon id} counter dump``.
+
+All labeled and unlabeled perf counter's schema can be viewed with ``ceph daemon {daemon id} counter schema``.
+
+In the above example the second counter without labels is a counter that would also be shown in ``ceph daemon {daemon id} perf dump``.
+
+Since the ``counter dump`` and ``counter schema`` commands can be used to view both types of counters it is not recommended to use the ``perf dump`` and ``perf schema`` commands which are retained for backwards compatibility and continue to emit only non-labeled counters.
+
+Some perf counters that are emitted via ``perf dump`` and ``perf schema`` may become labeled in future releases and as such will no longer be emitted by ``perf dump`` and ``perf schema`` respectively.
std::string counter;
cmd_getval(cmdmap, "logger", logger);
cmd_getval(cmdmap, "counter", counter);
- _perf_counters_collection->dump_formatted(f, false, logger, counter);
+ _perf_counters_collection->dump_formatted(f, false, false, logger, counter);
}
else if (command == "perfcounters_schema" || command == "2" ||
command == "perf schema") {
- _perf_counters_collection->dump_formatted(f, true);
+ _perf_counters_collection->dump_formatted(f, true, false);
+ }
+ else if (command == "counter dump") {
+ _perf_counters_collection->dump_formatted(f, false, true);
+ }
+ else if (command == "counter schema") {
+ _perf_counters_collection->dump_formatted(f, true, true);
}
else if (command == "perf histogram dump") {
std::string logger;
_admin_socket->register_command("leak_some_memory", _admin_hook, "");
_admin_socket->register_command("perfcounters_dump", _admin_hook, "");
_admin_socket->register_command("1", _admin_hook, "");
- _admin_socket->register_command("perf dump name=logger,type=CephString,req=false name=counter,type=CephString,req=false", _admin_hook, "dump perfcounters value");
+ _admin_socket->register_command("perf dump name=logger,type=CephString,req=false name=counter,type=CephString,req=false", _admin_hook, "dump non-labeled counters and their values");
_admin_socket->register_command("perfcounters_schema", _admin_hook, "");
_admin_socket->register_command("perf histogram dump name=logger,type=CephString,req=false name=counter,type=CephString,req=false", _admin_hook, "dump perf histogram values");
_admin_socket->register_command("2", _admin_hook, "");
- _admin_socket->register_command("perf schema", _admin_hook, "dump perfcounters schema");
+ _admin_socket->register_command("perf schema", _admin_hook, "dump non-labeled counters schemas");
+ _admin_socket->register_command("counter dump", _admin_hook, "dump all labeled and non-labeled counters and their values");
+ _admin_socket->register_command("counter schema", _admin_hook, "dump all labeled and non-labeled counters schemas");
_admin_socket->register_command("perf histogram schema", _admin_hook, "dump perf histogram schema");
_admin_socket->register_command("perf reset name=var,type=CephString", _admin_hook, "perf reset <name>: perf reset all or one perfcounter name");
_admin_socket->register_command("config show", _admin_hook, "dump current config settings");
*/
#include "common/perf_counters.h"
+#include "common/perf_counters_key.h"
#include "common/dout.h"
#include "common/valgrind.h"
#include "include/common_fwd.h"
Formatter *f,
bool schema,
bool histograms,
+ bool dump_labeled,
const std::string &logger,
const std::string &counter) const
{
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, counter);
+ (*l)->dump_formatted_generic(f, schema, histograms, dump_labeled, counter);
}
}
f->close_section();
}
void PerfCounters::dump_formatted_generic(Formatter *f, bool schema,
- bool histograms, const std::string &counter) const
+ bool histograms, bool dump_labeled, const std::string &counter) const
{
- f->open_object_section(m_name.c_str());
+ 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("labels");
+ for (auto label : ceph::perf_counters::key_labels(m_name)) {
+ // don't dump labels with empty label names
+ if (!label.first.empty()) {
+ f->dump_string(label.first, label.second);
+ }
+ }
+ f->close_section(); // labels
+ f->open_object_section("counters");
+ } else {
+ auto labels = ceph::perf_counters::key_labels(m_name);
+ // do not dump counters when counter instance is labeled and dump_labeled is not set
+ if (labels.begin() != labels.end()) {
+ return;
+ }
+
+ f->open_object_section(m_name.c_str());
+ }
for (perf_counter_data_vec_t::const_iterator d = m_data.begin();
d != m_data.end(); ++d) {
}
}
}
+ if (dump_labeled) {
+ f->close_section(); // counters
+ }
f->close_section();
}
void hinc(int idx, int64_t x, int64_t y);
void reset();
- void dump_formatted(ceph::Formatter *f, bool schema,
+ void dump_formatted(ceph::Formatter *f, bool schema, bool dump_labeled,
const std::string &counter = "") const {
- dump_formatted_generic(f, schema, false, counter);
+ dump_formatted_generic(f, schema, false, dump_labeled, counter);
}
void dump_formatted_histograms(ceph::Formatter *f, bool schema,
const std::string &counter = "") const {
- dump_formatted_generic(f, schema, true, counter);
+ dump_formatted_generic(f, schema, true, false, counter);
}
std::pair<uint64_t, uint64_t> get_tavg_ns(int idx) const;
PerfCounters(const PerfCounters &rhs);
PerfCounters& operator=(const PerfCounters &rhs);
void dump_formatted_generic(ceph::Formatter *f, bool schema, bool histograms,
+ bool dump_labeled,
const std::string &counter = "") const;
typedef std::vector<perf_counter_data_any_d> perf_counter_data_vec_t;
void clear();
bool reset(const std::string &name);
- void dump_formatted(ceph::Formatter *f, bool schema,
+ void dump_formatted(ceph::Formatter *f, bool schema, bool dump_labeled,
const std::string &logger = "",
const std::string &counter = "") const {
- dump_formatted_generic(f, schema, false, logger, counter);
+ dump_formatted_generic(f, schema, false, dump_labeled, logger, counter);
}
void dump_formatted_histograms(ceph::Formatter *f, bool schema,
const std::string &logger = "",
const std::string &counter = "") const {
- dump_formatted_generic(f, schema, true, logger, counter);
+ dump_formatted_generic(f, schema, true, false, logger, counter);
}
// A reference to a perf_counter_data_any_d, with an accompanying
private:
void dump_formatted_generic(ceph::Formatter *f, bool schema, bool histograms,
+ bool dump_labeled,
const std::string &logger = "",
const std::string &counter = "") const;
return perf_impl.reset(name);
}
void PerfCountersCollection::dump_formatted(ceph::Formatter *f, bool schema,
+ bool dump_labeled,
const std::string &logger,
const std::string &counter)
{
std::lock_guard lck(m_lock);
- perf_impl.dump_formatted(f,schema,logger,counter);
+ perf_impl.dump_formatted(f, schema, dump_labeled, logger, counter);
}
void PerfCountersCollection::dump_formatted_histograms(ceph::Formatter *f, bool schema,
const std::string &logger,
void clear();
bool reset(const std::string &name);
- void dump_formatted(ceph::Formatter *f, bool schema,
+ void dump_formatted(ceph::Formatter *f, bool schema, bool dump_labeled,
const std::string &logger = "",
const std::string &counter = "");
void dump_formatted_histograms(ceph::Formatter *f, bool schema,
${PROJECT_SOURCE_DIR}/src/common/mempool.cc
${PROJECT_SOURCE_DIR}/src/common/options.cc
${PROJECT_SOURCE_DIR}/src/common/perf_counters.cc
+ ${PROJECT_SOURCE_DIR}/src/common/perf_counters_key.cc
${PROJECT_SOURCE_DIR}/src/common/perf_histogram.cc
${PROJECT_SOURCE_DIR}/src/common/page.cc
${PROJECT_SOURCE_DIR}/src/common/pick_address.cc
cmd_getval(cmdmap, "logger", logger);
cmd_getval(cmdmap, "counter", counter);
- crimson::common::local_perf_coll().dump_formatted(f.get(), false, logger, counter);
+ crimson::common::local_perf_coll().dump_formatted(f.get(), false, false, logger, counter);
return seastar::make_ready_future<tell_result_t>(std::move(f));
}
};
}
void PerfCountersCollection::dump_formatted(ceph::Formatter *f, bool schema,
+ bool dump_labeled,
const std::string &logger,
const std::string &counter)
{
- perf_collection->dump_formatted(f, schema, logger, counter);
+ perf_collection->dump_formatted(f, schema, dump_labeled, logger, counter);
}
PerfCountersCollection::ShardedPerfCountersCollection PerfCountersCollection::sharded_perf_coll;
PerfCountersCollection();
~PerfCountersCollection();
PerfCountersCollectionImpl* get_perf_collection();
- void dump_formatted(ceph::Formatter *f, bool schema,
+ void dump_formatted(ceph::Formatter *f, bool schema, bool dump_labeled,
const std::string &logger = "",
const std::string &counter = "");
};
f->close_section();
}
f->open_object_section("rocksdbstore_perf_counters");
- logger->dump_formatted(f,0);
+ logger->dump_formatted(f, false, false);
f->close_section();
}
if (cct->_conf->rocksdb_collect_memory_stats) {
auto&& appd = getdata(vfs);
JSONFormatter f(false);
f.open_object_section("ceph_perf");
- appd.logger->dump_formatted(&f, false);
- appd.striper_logger->dump_formatted(&f, false);
+ appd.logger->dump_formatted(&f, false, false);
+ appd.striper_logger->dump_formatted(&f, false, false);
f.close_section();
{
CachedStackStringStream css;
ss << "\"image\": \"" << m_image_ctx.name << "\",";
bl.append(ss);
bl.append("\"stats\": ");
- m_image_ctx.cct->get_perfcounters_collection()->dump_formatted(f, 0);
+ m_image_ctx.cct->get_perfcounters_collection()->dump_formatted(f, false, false);
f->flush(bl);
bl.append(",\n\"histograms\": ");
m_image_ctx.cct->get_perfcounters_collection()->dump_formatted_histograms(f, 0);
void BlueFS::dump_perf_counters(Formatter *f)
{
f->open_object_section("bluefs_perf_counters");
- logger->dump_formatted(f,0);
+ logger->dump_formatted(f, false, false);
f->close_section();
}
int flush_cache(std::ostream *os = NULL) override;
void dump_perf_counters(ceph::Formatter *f) override {
f->open_object_section("perf_counters");
- logger->dump_formatted(f, false);
+ logger->dump_formatted(f, false, false);
f->close_section();
}
}
void dump_perf_counters(ceph::Formatter *f) override {
f->open_object_section("perf_counters");
- logger->dump_formatted(f, false);
+ logger->dump_formatted(f, false, false);
f->close_section();
}
void get_db_statistics(ceph::Formatter *f) override {
Formatter* f;
f = Formatter::create("json-pretty");
- g_ceph_context->get_perfcounters_collection()->dump_formatted(f, false);
+ g_ceph_context->get_perfcounters_collection()->dump_formatted(f, false, false);
ostr << ">>>>>>>>>>>>> PERFCOUNTERS BEGIN <<<<<<<<<<<<" << std::endl;
f->flush(ostr);
ostr << ">>>>>>>>>>>>> PERFCOUNTERS END <<<<<<<<<<<<" << std::endl;
Formatter* f = Formatter::create(
"json-pretty", "json-pretty", "json-pretty");
f->open_object_section("perf_output");
- cct->get_perfcounters_collection()->dump_formatted(f, false);
+ cct->get_perfcounters_collection()->dump_formatted(f, false, false);
if (g_conf()->rocksdb_perf) {
f->open_object_section("rocksdb_perf");
os->get_db_statistics(f);
// 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"
"{\"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);
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"}});
+
+ PerfCounters* counters1 = setup_test_perfcounter4(counter_key1, g_ceph_context);
+ PerfCounters* counters2 = setup_test_perfcounter4(counter_key2, g_ceph_context);
+
+ counters1->inc(TEST_PERFCOUNTERS2_ELEMENT_FOO, 3);
+ counters1->dec(TEST_PERFCOUNTERS2_ELEMENT_FOO, 1);
+ counters2->set(TEST_PERFCOUNTERS2_ELEMENT_FOO, 4);
+
+ 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
+ }
+ },
+ "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"
+ }
+ }
+ },
+ "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();
+}
if (debug) {
ostringstream ostr;
Formatter* f = Formatter::create("json-pretty", "json-pretty", "json-pretty");
- cct->get_perfcounters_collection()->dump_formatted(f, false);
+ cct->get_perfcounters_collection()->dump_formatted(f, false, false);
ostr << "ceph-objectstore-tool ";
f->flush(ostr);
delete f;