]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common: filtering in `perf dump` 3499/head
authorJohn Spray <john.spray@redhat.com>
Tue, 27 Jan 2015 11:13:59 +0000 (11:13 +0000)
committerJohn Spray <john.spray@redhat.com>
Tue, 27 Jan 2015 11:17:10 +0000 (11:17 +0000)
So that we can get out a particular subsystem
or particular counter without dumping
everything.  Should make tests that watch perf
counters much less spammy!

`logger` and `counter` params are used with
an exact comparison here but the interface
should be amenable to extending to e.g. globbing
if we wanted to in the future.

Also tidy up some iterator while()s into for()s.

Signed-off-by: John Spray <john.spray@redhat.com>
src/common/ceph_context.cc
src/common/perf_counters.cc
src/common/perf_counters.h

index bec006bfdf5485e01b7838fed0edf3673237495b..7f1adb091f4d58a5ecde3cd177194c385d898275 100644 (file)
@@ -236,7 +236,11 @@ void CephContext::do_command(std::string command, cmdmap_t& cmdmap,
                         << ss.str() << dendl;
   if (command == "perfcounters_dump" || command == "1" ||
       command == "perf dump") {
-    _perf_counters_collection->dump_formatted(f, false);
+    std::string logger;
+    std::string counter;
+    cmd_getval(this, cmdmap, "logger", logger);
+    cmd_getval(this, cmdmap, "counter", counter);
+    _perf_counters_collection->dump_formatted(f, false, logger, counter);
   }
   else if (command == "perfcounters_schema" || command == "2" ||
     command == "perf schema") {
@@ -379,7 +383,7 @@ CephContext::CephContext(uint32_t module_type_)
   _admin_hook = new CephContextHook(this);
   _admin_socket->register_command("perfcounters_dump", "perfcounters_dump", _admin_hook, "");
   _admin_socket->register_command("1", "1", _admin_hook, "");
-  _admin_socket->register_command("perf dump", "perf dump", _admin_hook, "dump perfcounters value");
+  _admin_socket->register_command("perf dump", "perf dump name=logger,type=CephString,req=false name=counter,type=CephString,req=false", _admin_hook, "dump perfcounters value");
   _admin_socket->register_command("perfcounters_schema", "perfcounters_schema", _admin_hook, "");
   _admin_socket->register_command("2", "2", _admin_hook, "");
   _admin_socket->register_command("perf schema", "perf schema", _admin_hook, "dump perfcounters schema");
index 3824bea95ff38759086254526ddfba47a815eb46..61242727f3bc90f295b3044f9ad67b55ca765fcb 100644 (file)
@@ -102,17 +102,30 @@ bool PerfCountersCollection::reset(const std::string &name)
 }
 
 
-void PerfCountersCollection::dump_formatted(Formatter *f, bool schema)
+/**
+ * Serialize current values of performance counters.  Optionally
+ * output the schema instead, or filter output to a particular
+ * PerfCounters or particular named counter.
+ *
+ * @param logger name of subsystem logger, e.g. "mds_cache", may be empty
+ * @param counter name of counter within subsystem, e.g. "num_strays",
+ *                may be empty.
+ * @param schema if true, output schema instead of current data.
+ */
+void PerfCountersCollection::dump_formatted(
+    Formatter *f,
+    bool schema,
+    const std::string &logger,
+    const std::string &counter)
 {
   Mutex::Locker lck(m_lock);
   f->open_object_section("perfcounter_collection");
-  perf_counters_set_t::iterator l = m_loggers.begin();
-  perf_counters_set_t::iterator l_end = m_loggers.end();
-  if (l != l_end) {
-    while (true) {
-      (*l)->dump_formatted(f, schema);
-      if (++l == l_end)
-       break;
+  
+  for (perf_counters_set_t::iterator l = m_loggers.begin();
+       l != m_loggers.end(); ++l) {
+    // Optionally filter on logger name, pass through counter filter
+    if (logger.empty() || (*l)->get_name() == logger) {
+      (*l)->dump_formatted(f, schema, counter);
     }
   }
   f->close_section();
@@ -264,16 +277,18 @@ void PerfCounters::reset()
   }
 }
 
-void PerfCounters::dump_formatted(Formatter *f, bool schema)
+void PerfCounters::dump_formatted(Formatter *f, bool schema,
+    const std::string &counter)
 {
   f->open_object_section(m_name.c_str());
-  perf_counter_data_vec_t::const_iterator d = m_data.begin();
-  perf_counter_data_vec_t::const_iterator d_end = m_data.end();
-  if (d == d_end) {
-    f->close_section();
-    return;
-  }
-  while (true) {
+  
+  for (perf_counter_data_vec_t::const_iterator d = m_data.begin();
+       d != m_data.end(); ++d) {
+    if (!counter.empty() && counter != d->name) {
+      // Optionally filter on counter name
+      continue;
+    }
+
     if (schema) {
       f->open_object_section(d->name);
       f->dump_int("type", d->type);
@@ -307,9 +322,6 @@ void PerfCounters::dump_formatted(Formatter *f, bool schema)
        }
       }
     }
-
-    if (++d == d_end)
-      break;
   }
   f->close_section();
 }
index 24b505dc3a273289c7348e407b8103b09815fe36..8850138a23fa9feca6881b26a48d100abb363496 100644 (file)
@@ -95,7 +95,8 @@ public:
   utime_t tget(int idx) const;
 
   void reset();
-  void dump_formatted(ceph::Formatter *f, bool schema);
+  void dump_formatted(ceph::Formatter *f, bool schema,
+      const std::string &counter = "");
   pair<uint64_t, uint64_t> get_tavg_ms(int idx) const;
 
   const std::string& get_name() const;
@@ -203,7 +204,11 @@ public:
   void remove(class PerfCounters *l);
   void clear();
   bool reset(const std::string &name);
-  void dump_formatted(ceph::Formatter *f, bool schema);
+  void dump_formatted(
+      ceph::Formatter *f,
+      bool schema,
+      const std::string &logger = "",
+      const std::string &counter = "");
 private:
   CephContext *m_cct;