diff options
author | Joao Eduardo Luis <joao.luis@inktank.com> | 2013-03-01 16:32:24 +0000 |
---|---|---|
committer | Joao Eduardo Luis <joao.luis@inktank.com> | 2013-03-04 11:37:17 +0000 |
commit | de6d0a222b6718306b49b73de4e46e32abe4d6ef (patch) | |
tree | 1260c033febb27e77202f5794f29f5b638096cc3 | |
parent | caa0af25192704ee7743097df0c441bd26b9314c (diff) | |
download | ceph-de6d0a222b6718306b49b73de4e46e32abe4d6ef.tar.gz |
mon: Monitor: 'ceph df'
Fixes: #3484
Signed-off-by: Joao Eduardo Luis <joao.luis@inktank.com>
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/mon/Monitor.cc | 25 | ||||
-rw-r--r-- | src/mon/PGMonitor.cc | 154 | ||||
-rw-r--r-- | src/mon/PGMonitor.h | 7 |
4 files changed, 186 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 9daf3f22182..441000df963 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -69,7 +69,7 @@ LIBOS_LDA += -lleveldb -lsnappy LEVELDB_INCLUDE = # monitor -ceph_mon_SOURCES = ceph_mon.cc +ceph_mon_SOURCES = ceph_mon.cc common/TextTable.cc ceph_mon_LDFLAGS = $(AM_LDFLAGS) ceph_mon_LDADD = libmon.a $(LIBOS_LDA) $(LIBGLOBAL_LDA) ceph_mon_CXXFLAGS = ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS} $(LEVELDB_INCLUDE) diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 60a022bde25..f719bfe6ba6 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -2440,7 +2440,8 @@ void Monitor::handle_command(MMonCommand *m) rs = "must supply options to be parsed in a single string"; r = -EINVAL; } - } else if ((m->cmd[0] == "status") || (m->cmd[0] == "health")) { + } else if ((m->cmd[0] == "status") || (m->cmd[0] == "health") + || (m->cmd[0] == "df")) { if (!access_r) { r = -EACCES; rs = "access denied"; @@ -2493,6 +2494,28 @@ void Monitor::handle_command(MMonCommand *m) } else { ss << health_str; } + } else if (string(args[0]) == "df") { + if (args.size() > 1) { + if (string(args[1]) != "detail") { + r = -EINVAL; + rs = "usage: df [detail]"; + goto out; + } + } + bool verbose = (args.size() > 1); + if (jf) + jf->open_object_section("stats"); + + pgmon()->dump_fs_stats(ss, jf, verbose); + if (!jf) + ss << '\n'; + pgmon()->dump_pool_stats(ss, jf, verbose); + + if (jf) { + jf->close_section(); + jf->flush(ss); + ss << '\n'; + } } else { assert(0 == "We should never get here!"); return; diff --git a/src/mon/PGMonitor.cc b/src/mon/PGMonitor.cc index 8245ed6ae6e..cc23bffef25 100644 --- a/src/mon/PGMonitor.cc +++ b/src/mon/PGMonitor.cc @@ -34,6 +34,9 @@ #include "common/Formatter.h" #include "common/ceph_argparse.h" #include "common/perf_counters.h" +#include "common/TextTable.h" + +#include "include/stringify.h" #include "osd/osd_types.h" @@ -894,6 +897,157 @@ bool PGMonitor::check_down_pgs() return ret; } +inline string percentify(const float& a) { + stringstream ss; + if (a < 0.01) + ss << "0"; + else + ss << std::fixed << std::setprecision(2) << a; + return ss.str(); +} + +//void PGMonitor::dump_object_stat_sum(stringstream& ss, Formatter *f, +void PGMonitor::dump_object_stat_sum(TextTable &tbl, Formatter *f, + object_stat_sum_t &sum, bool verbose) +{ + if (f) { + f->dump_int("kb_used", SHIFT_ROUND_UP(sum.num_bytes, 10)); + f->dump_int("bytes_used", sum.num_bytes); + f->dump_int("objects", sum.num_objects); + if (verbose) { + f->dump_int("rd", sum.num_rd); + f->dump_int("rd_kb", sum.num_rd_kb); + f->dump_int("wr", sum.num_wr); + f->dump_int("wr_kb", sum.num_wr_kb); + } + } else { + tbl << stringify(si_t(sum.num_bytes)); + int64_t kb_used = SHIFT_ROUND_UP(sum.num_bytes, 10); + tbl << percentify(((float)kb_used / pg_map.osd_sum.kb)*100); + tbl << sum.num_objects; + if (verbose) { + tbl << stringify(si_t(sum.num_rd)) + << stringify(si_t(sum.num_wr)); + } + } +} + +void PGMonitor::dump_pool_stats(stringstream &ss, Formatter *f, bool verbose) +{ + TextTable tbl; + + if (f) { + f->open_array_section("pools"); + } else { + tbl.define_column("NAME", TextTable::LEFT, TextTable::LEFT); + tbl.define_column("ID", TextTable::LEFT, TextTable::LEFT); + if (verbose) + tbl.define_column("CATEGORY", TextTable::LEFT, TextTable::LEFT); + tbl.define_column("USED", TextTable::LEFT, TextTable::LEFT); + tbl.define_column("\%USED", TextTable::LEFT, TextTable::LEFT); + tbl.define_column("OBJECTS", TextTable::LEFT, TextTable::LEFT); + if (verbose) { + tbl.define_column("READ", TextTable::LEFT, TextTable::LEFT); + tbl.define_column("WRITE", TextTable::LEFT, TextTable::LEFT); + } + } + + OSDMap &osdmap = mon->osdmon()->osdmap; + for (map<int64_t,pg_pool_t>::const_iterator p = osdmap.get_pools().begin(); + p != osdmap.get_pools().end(); ++p) { + int64_t pool_id = p->first; + if ((pool_id < 0) || (pg_map.pg_pool_sum.count(pool_id) == 0)) + continue; + string pool_name = osdmap.get_pool_name(pool_id); + pool_stat_t &stat = pg_map.pg_pool_sum[pool_id]; + + if (f) { + f->open_object_section("pool"); + f->dump_string("name", pool_name); + f->dump_int("id", pool_id); + f->open_object_section("stats"); + } else { + tbl << pool_name + << pool_id; + if (verbose) + tbl << "-"; + } + dump_object_stat_sum(tbl, f, stat.stats.sum, verbose); + if (f) + f->close_section(); // stats + else + tbl << TextTable::endrow; + + if (verbose) { + if (f) + f->open_array_section("categories"); + + for (map<string,object_stat_sum_t>::iterator it = stat.stats.cat_sum.begin(); + it != stat.stats.cat_sum.end(); ++it) { + if (f) { + f->open_object_section(it->first.c_str()); + } else { + tbl << "" + << "" + << it->first; + } + dump_object_stat_sum(tbl, f, it->second, verbose); + if (f) + f->close_section(); // category name + else + tbl << TextTable::endrow; + } + if (f) + f->close_section(); // categories + } + if (f) + f->close_section(); // pool + } + if (f) + f->close_section(); + else { + ss << "POOLS:\n"; + tbl.set_indent(4); + ss << tbl; + } +} + +void PGMonitor::dump_fs_stats(stringstream &ss, Formatter *f, bool verbose) +{ + if (f) { + f->open_object_section("stats"); + f->dump_int("total_space", pg_map.osd_sum.kb); + f->dump_int("total_used", pg_map.osd_sum.kb_used); + f->dump_int("total_avail", pg_map.osd_sum.kb_avail); + if (verbose) { + f->dump_int("total_objects", pg_map.pg_sum.stats.sum.num_objects); + } + f->close_section(); + } else { + TextTable tbl; + tbl.define_column("SIZE", TextTable::LEFT, TextTable::LEFT); + tbl.define_column("AVAIL", TextTable::LEFT, TextTable::LEFT); + tbl.define_column("RAW USED", TextTable::LEFT, TextTable::LEFT); + tbl.define_column("\%RAW USED", TextTable::LEFT, TextTable::LEFT); + if (verbose) { + tbl.define_column("OBJECTS", TextTable::LEFT, TextTable::LEFT); + } + tbl << stringify(si_t(pg_map.osd_sum.kb)) + << stringify(si_t(pg_map.osd_sum.kb_avail)) + << stringify(si_t(pg_map.osd_sum.kb_used)); + tbl << percentify(((float)pg_map.osd_sum.kb_used / pg_map.osd_sum.kb)*100); + if (verbose) { + tbl << stringify(si_t(pg_map.pg_sum.stats.sum.num_objects)); + } + tbl << TextTable::endrow; + + ss << "GLOBAL:\n"; + tbl.set_indent(4); + ss << tbl; + } +} + + void PGMonitor::dump_info(Formatter *f) { f->open_object_section("pgmap"); diff --git a/src/mon/PGMonitor.h b/src/mon/PGMonitor.h index 13d75f813a5..de78e984ae9 100644 --- a/src/mon/PGMonitor.h +++ b/src/mon/PGMonitor.h @@ -39,6 +39,7 @@ class MMonCommand; class MGetPoolStats; class RatioMonitor; +class TextTable; class PGMonitor : public PaxosService { public: @@ -129,6 +130,9 @@ private: bufferlist& rdata, vector<const char*>& args) const; + void dump_object_stat_sum(TextTable &tbl, Formatter *f, + object_stat_sum_t &sum, bool verbose); + public: PGMonitor(Monitor *mn, Paxos *p, const string& service_name) : PaxosService(mn, p, service_name), need_check_down_pgs(false) { } @@ -145,6 +149,9 @@ public: void check_osd_map(epoch_t epoch); + void dump_pool_stats(stringstream &ss, Formatter *f, bool verbose); + void dump_fs_stats(stringstream &ss, Formatter *f, bool verbose); + void dump_info(Formatter *f); void get_health(list<pair<health_status_t,string> >& summary, |