]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: Monitor: 'ceph df'
authorJoao Eduardo Luis <joao.luis@inktank.com>
Fri, 1 Mar 2013 16:32:24 +0000 (16:32 +0000)
committerJoao Eduardo Luis <joao.luis@inktank.com>
Mon, 4 Mar 2013 11:37:17 +0000 (11:37 +0000)
Fixes: #3484
Signed-off-by: Joao Eduardo Luis <joao.luis@inktank.com>
src/Makefile.am
src/mon/Monitor.cc
src/mon/PGMonitor.cc
src/mon/PGMonitor.h

index 9daf3f22182eb4a117d7ec13f75b8c15d95dfda5..441000df9639bfc413ff85eed46e8b61785e429f 100644 (file)
@@ -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)
index 60a022bde2563a22557df61e5614c38af13bb730..f719bfe6ba6b5c0dca870a835e991b2735169d4e 100644 (file)
@@ -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;
index 8245ed6ae6efdcad4d4f8a78e8530b989740ae9f..cc23bffef250501e734369f7c9c8889f7cb1712d 100644 (file)
@@ -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");
index 13d75f813a52ad8b75dee8dcd483e1d1c4d5dbf2..de78e984ae9285a1b8cc22e366215ec9dfae4103 100644 (file)
@@ -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,