From 9f5cae447bd46e57c6fbb23e4b907fd91bbb80fe Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 12 Jul 2013 11:36:18 -0700 Subject: [PATCH] mon: structure 'ceph status' json output Return the summary info in a structured for instead of just mimicing the legacy plaintext format. Signed-off-by: Sage Weil Reviewed-by: Joao Eduardo Luis --- src/mds/MDSMap.cc | 57 ++++++++++++++---- src/mds/MDSMap.h | 4 +- src/mon/Monitor.cc | 29 ++++++--- src/mon/PGMap.cc | 140 +++++++++++++++++++++++++++++-------------- src/mon/PGMap.h | 7 +-- src/mon/PGMonitor.cc | 2 +- src/osd/OSDMap.cc | 1 - 7 files changed, 168 insertions(+), 72 deletions(-) diff --git a/src/mds/MDSMap.cc b/src/mds/MDSMap.cc index 867c168f1ab72..1646a134ad58e 100644 --- a/src/mds/MDSMap.cc +++ b/src/mds/MDSMap.cc @@ -202,11 +202,22 @@ void MDSMap::print(ostream& out) -void MDSMap::print_summary(ostream& out) +void MDSMap::print_summary(Formatter *f, ostream *out) { map by_rank; map by_state; + if (f) { + f->dump_unsigned("epoch", get_epoch()); + f->dump_unsigned("up", up.size()); + f->dump_unsigned("in", in.size()); + f->dump_unsigned("max", max_mds); + } else { + *out << "e" << get_epoch() << ": " << up.size() << "/" << in.size() << "/" << max_mds << " up"; + } + + if (f) + f->open_array_section("by_rank"); for (map::iterator p = mds_info.begin(); p != mds_info.end(); ++p) { @@ -214,22 +225,42 @@ void MDSMap::print_summary(ostream& out) if (p->second.laggy()) s += "(laggy or crashed)"; - if (p->second.rank >= 0) - by_rank[p->second.rank] = p->second.name + "=" + s; - else + if (p->second.rank >= 0) { + if (f) { + f->open_object_section("mds"); + f->dump_unsigned("rank", p->second.rank); + f->dump_string("name", p->second.name); + f->dump_string("status", s); + f->close_section(); + } else { + by_rank[p->second.rank] = p->second.name + "=" + s; + } + } else { by_state[s]++; + } + } + if (f) { + f->close_section(); + } else { + if (!by_rank.empty()) + *out << " " << by_rank; } - out << "e" << get_epoch() << ": " << up.size() << "/" << in.size() << "/" << max_mds << " up"; - - if (!by_rank.empty()) - out << " " << by_rank; + for (map::reverse_iterator p = by_state.rbegin(); p != by_state.rend(); ++p) { + if (f) { + f->dump_unsigned(p->first.c_str(), p->second); + } else { + *out << ", " << p->second << " " << p->first; + } + } - for (map::reverse_iterator p = by_state.rbegin(); p != by_state.rend(); ++p) - out << ", " << p->second << " " << p->first; - - if (!failed.empty()) - out << ", " << failed.size() << " failed"; + if (!failed.empty()) { + if (f) { + f->dump_unsigned("failed", failed.size()); + } else { + *out << ", " << failed.size() << " failed"; + } + } //if (stopped.size()) //out << ", " << stopped.size() << " stopped"; } diff --git a/src/mds/MDSMap.h b/src/mds/MDSMap.h index 3e2f67e01de38..5bfc7cc20d5a8 100644 --- a/src/mds/MDSMap.h +++ b/src/mds/MDSMap.h @@ -529,7 +529,7 @@ public: void print(ostream& out); - void print_summary(ostream& out); + void print_summary(Formatter *f, ostream *out); void dump(Formatter *f) const; static void generate_test_instances(list& ls); @@ -538,7 +538,7 @@ WRITE_CLASS_ENCODER_FEATURES(MDSMap::mds_info_t) WRITE_CLASS_ENCODER_FEATURES(MDSMap) inline ostream& operator<<(ostream& out, MDSMap& m) { - m.print_summary(out); + m.print_summary(NULL, &out); return out; } diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index a2699757a3200..86e8cc752c78a 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -1794,13 +1794,28 @@ void Monitor::get_status(stringstream &ss, Formatter *f) if (f) { f->dump_stream("fsid") << monmap->get_fsid(); - f->dump_stream("monmap") << *monmap; - f->dump_stream("election_epoch") << get_epoch(); - f->dump_stream("quorum") << get_quorum(); - f->dump_stream("quorum_names") << get_quorum_names(); - f->dump_stream("osdmap") << osdmon()->osdmap; - f->dump_stream("pgmap") << pgmon()->pg_map; - f->dump_stream("mdsmap") << mdsmon()->mdsmap; + f->dump_unsigned("election_epoch", get_epoch()); + { + f->open_array_section("quorum"); + for (set::iterator p = quorum.begin(); p != quorum.end(); ++p) + f->dump_int("rank", *p); + f->close_section(); + f->open_array_section("quorum_names"); + for (set::iterator p = quorum.begin(); p != quorum.end(); ++p) + f->dump_string("id", monmap->get_name(*p)); + f->close_section(); + } + f->open_object_section("monmap"); + monmap->dump(f); + f->close_section(); + f->open_object_section("osdmap"); + osdmon()->osdmap.print_summary(f, cout); + f->close_section(); + f->open_object_section("pgmap"); + pgmon()->pg_map.print_summary(f, NULL); + f->close_section(); + f->open_object_section("mdsmap"); + mdsmon()->mdsmap.print_summary(f, NULL); f->close_section(); } else { ss << " cluster " << monmap->get_fsid() << "\n"; diff --git a/src/mon/PGMap.cc b/src/mon/PGMap.cc index f477bc9ee65ba..dfb6b1acfd35f 100644 --- a/src/mon/PGMap.cc +++ b/src/mon/PGMap.cc @@ -695,48 +695,58 @@ void PGMap::dump_stuck_plain(ostream& ss, PGMap::StuckPG type, utime_t cutoff) c dump_pg_stats_plain(ss, stuck_pg_stats); } -void PGMap::state_summary(ostream& ss) const -{ - for (hash_map::const_iterator p = num_pg_by_state.begin(); - p != num_pg_by_state.end(); - ++p) { - if (p != num_pg_by_state.begin()) - ss << ", "; - ss << p->second << " " << pg_state_string(p->first); - } -} - -void PGMap::recovery_summary(ostream& out) const +void PGMap::recovery_summary(Formatter *f, ostream *out) const { bool first = true; if (pg_sum.stats.sum.num_objects_degraded) { double pc = (double)pg_sum.stats.sum.num_objects_degraded / (double)pg_sum.stats.sum.num_object_copies * (double)100.0; char b[20]; snprintf(b, sizeof(b), "%.3lf", pc); - out << pg_sum.stats.sum.num_objects_degraded - << "/" << pg_sum.stats.sum.num_object_copies << " degraded (" << b << "%)"; + if (f) { + f->dump_unsigned("degraded_objects", pg_sum.stats.sum.num_objects_degraded); + f->dump_unsigned("degraded_total", pg_sum.stats.sum.num_object_copies); + f->dump_string("degrated_ratio", b); + } else { + *out << pg_sum.stats.sum.num_objects_degraded + << "/" << pg_sum.stats.sum.num_object_copies << " degraded (" << b << "%)"; + } first = false; } if (pg_sum.stats.sum.num_objects_unfound) { double pc = (double)pg_sum.stats.sum.num_objects_unfound / (double)pg_sum.stats.sum.num_objects * (double)100.0; char b[20]; snprintf(b, sizeof(b), "%.3lf", pc); - if (!first) - out << "; "; - out << pg_sum.stats.sum.num_objects_unfound - << "/" << pg_sum.stats.sum.num_objects << " unfound (" << b << "%)"; + if (f) { + f->dump_unsigned("unfound_objects", pg_sum.stats.sum.num_objects_unfound); + f->dump_unsigned("unfound_total", pg_sum.stats.sum.num_objects); + f->dump_string("unfound_ratio", b); + } else { + if (!first) + *out << "; "; + *out << pg_sum.stats.sum.num_objects_unfound + << "/" << pg_sum.stats.sum.num_objects << " unfound (" << b << "%)"; + } first = false; } if (pg_sum_delta.stats.sum.num_objects_recovered || pg_sum_delta.stats.sum.num_bytes_recovered || pg_sum_delta.stats.sum.num_keys_recovered) { - if (!first) - out << "; "; - out << " recovering " - << si_t(pg_sum_delta.stats.sum.num_objects_recovered / (double)stamp_delta) << " o/s, " - << si_t(pg_sum_delta.stats.sum.num_bytes_recovered / (double)stamp_delta) << "B/s"; - if (pg_sum_delta.stats.sum.num_keys_recovered) - out << ", " << si_t(pg_sum_delta.stats.sum.num_keys_recovered / (double)stamp_delta) << " key/s"; + uint64_t objps = pg_sum_delta.stats.sum.num_objects_recovered / (double)stamp_delta; + uint64_t bps = pg_sum_delta.stats.sum.num_bytes_recovered / (double)stamp_delta; + uint64_t kps = pg_sum_delta.stats.sum.num_keys_recovered / (double)stamp_delta; + if (f) { + f->dump_unsigned("recovering_objects_per_sec", objps); + f->dump_unsigned("recovering_bytes_per_sec", bps); + f->dump_unsigned("recovering_keys_per_sec", kps); + } else { + if (!first) + *out << "; "; + *out << " recovering " + << si_t(objps) << " o/s, " + << si_t(bps) << "B/s"; + if (pg_sum_delta.stats.sum.num_keys_recovered) + *out << ", " << si_t(kps) << " key/s"; + } } } @@ -768,33 +778,75 @@ void PGMap::clear_delta() stamp_delta = ceph_clock_now(g_ceph_context); } -void PGMap::print_summary(ostream& out) const +void PGMap::print_summary(Formatter *f, ostream *out) const { std::stringstream ss; - state_summary(ss); - string states = ss.str(); - out << "v" << version << ": " - << pg_stat.size() << " pgs: " - << states << "; " - << prettybyte_t(pg_sum.stats.sum.num_bytes) << " data, " - << kb_t(osd_sum.kb_used) << " used, " - << kb_t(osd_sum.kb_avail) << " / " - << kb_t(osd_sum.kb) << " avail"; + if (f) + f->open_object_section("pgs_by_state"); + for (hash_map::const_iterator p = num_pg_by_state.begin(); + p != num_pg_by_state.end(); + ++p) { + if (f) { + f->dump_unsigned(pg_state_string(p->first).c_str(), p->second); + } else { + if (p != num_pg_by_state.begin()) + ss << ", "; + ss << p->second << " " << pg_state_string(p->first); + } + } + if (f) + f->close_section(); + + if (f) { + f->dump_unsigned("version", version); + f->dump_unsigned("num_pgs", pg_stat.size()); + f->dump_unsigned("data_bytes", pg_sum.stats.sum.num_bytes); + f->dump_unsigned("bytes_used", osd_sum.kb_used * 4096ull); + f->dump_unsigned("bytes_avail", osd_sum.kb_avail * 4096ull); + f->dump_unsigned("bytes_total", osd_sum.kb * 4096ull); + } else { + string states = ss.str(); + *out << "v" << version << ": " + << pg_stat.size() << " pgs: " + << states << "; " + << prettybyte_t(pg_sum.stats.sum.num_bytes) << " data, " + << kb_t(osd_sum.kb_used) << " used, " + << kb_t(osd_sum.kb_avail) << " / " + << kb_t(osd_sum.kb) << " avail"; + } if (pg_sum_delta.stats.sum.num_rd || pg_sum_delta.stats.sum.num_wr) { - out << "; "; - if (pg_sum_delta.stats.sum.num_rd) - out << si_t((pg_sum_delta.stats.sum.num_rd_kb << 10) / (double)stamp_delta) << "B/s rd, "; - if (pg_sum_delta.stats.sum.num_wr) - out << si_t((pg_sum_delta.stats.sum.num_wr_kb << 10) / (double)stamp_delta) << "B/s wr, "; - out << si_t((pg_sum_delta.stats.sum.num_rd + pg_sum_delta.stats.sum.num_wr) / (double)stamp_delta) << "op/s"; + if (!f) + *out << "; "; + if (pg_sum_delta.stats.sum.num_rd) { + uint64_t rd = (pg_sum_delta.stats.sum.num_rd_kb << 10) / (double)stamp_delta; + if (f) { + f->dump_unsigned("read_bytes_sec", rd); + } else { + *out << si_t(rd) << "B/s rd, "; + } + } + if (pg_sum_delta.stats.sum.num_wr) { + uint64_t wr = (pg_sum_delta.stats.sum.num_wr_kb << 10) / (double)stamp_delta; + if (f) { + f->dump_unsigned("write_bytes_sec", wr); + } else { + *out << si_t(wr) << "B/s wr, "; + } + } + uint64_t iops = (pg_sum_delta.stats.sum.num_rd + pg_sum_delta.stats.sum.num_wr) / (double)stamp_delta; + if (f) { + f->dump_unsigned("op_per_sec", iops); + } else { + *out << si_t(iops) << "op/s"; + } } std::stringstream ssr; - recovery_summary(ssr); - if (ssr.str().length()) - out << "; " << ssr.str(); + recovery_summary(f, &ssr); + if (!f && ssr.str().length()) + *out << "; " << ssr.str(); } void PGMap::generate_test_instances(list& o) diff --git a/src/mon/PGMap.h b/src/mon/PGMap.h index d8cf1885a82d9..16c2f84b99e33 100644 --- a/src/mon/PGMap.h +++ b/src/mon/PGMap.h @@ -168,9 +168,8 @@ public: void dump(ostream& ss) const; - void state_summary(ostream& ss) const; - void recovery_summary(ostream& out) const; - void print_summary(ostream& out) const; + void recovery_summary(Formatter *f, ostream *out) const; + void print_summary(Formatter *f, ostream *out) const; epoch_t calc_min_last_epoch_clean() const; @@ -180,7 +179,7 @@ WRITE_CLASS_ENCODER_FEATURES(PGMap::Incremental) WRITE_CLASS_ENCODER_FEATURES(PGMap) inline ostream& operator<<(ostream& out, const PGMap& m) { - m.print_summary(out); + m.print_summary(NULL, &out); return out; } diff --git a/src/mon/PGMonitor.cc b/src/mon/PGMonitor.cc index 6fb0b78b03b59..365d836cebd0e 100644 --- a/src/mon/PGMonitor.cc +++ b/src/mon/PGMonitor.cc @@ -1764,7 +1764,7 @@ void PGMonitor::get_health(list >& summary, } stringstream rss; - pg_map.recovery_summary(rss); + pg_map.recovery_summary(NULL, &rss); if (!rss.str().empty()) { summary.push_back(make_pair(HEALTH_WARN, "recovery " + rss.str())); if (detail) diff --git a/src/osd/OSDMap.cc b/src/osd/OSDMap.cc index 330180debd846..1af820ad2b6be 100644 --- a/src/osd/OSDMap.cc +++ b/src/osd/OSDMap.cc @@ -1735,7 +1735,6 @@ void OSDMap::print_summary(Formatter *f, ostream& out) const f->dump_string("nearfull", test_flag(CEPH_OSDMAP_NEARFULL) ? "true" : "false"); f->close_section(); - f->flush(out); } else { out << "e" << get_epoch() << ": " << get_num_osds() << " osds: " -- 2.39.5