]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: collect client perf stats when query is enabled
authorMykola Golub <mgolub@suse.com>
Sun, 23 Sep 2018 17:33:14 +0000 (20:33 +0300)
committerMykola Golub <mgolub@suse.com>
Wed, 7 Nov 2018 19:25:25 +0000 (21:25 +0200)
Fixes: https://tracker.ceph.com/issues/36091
Signed-off-by: Mykola Golub <mgolub@suse.com>
21 files changed:
src/messages/MMgrConfigure.h
src/messages/MMgrReport.h
src/mgr/ActivePyModules.h
src/mgr/CMakeLists.txt
src/mgr/DaemonServer.cc
src/mgr/MgrClient.cc
src/mgr/MgrClient.h
src/mgr/OSDPerfMetricCollector.cc
src/mgr/OSDPerfMetricCollector.h
src/mgr/OSDPerfMetricQuery.cc [deleted file]
src/mgr/OSDPerfMetricQuery.h [deleted file]
src/mgr/OSDPerfMetricReport.h [deleted file]
src/mgr/OSDPerfMetricTypes.cc [new file with mode: 0644]
src/mgr/OSDPerfMetricTypes.h [new file with mode: 0644]
src/osd/CMakeLists.txt
src/osd/DynamicPerfStats.h [new file with mode: 0644]
src/osd/OSD.cc
src/osd/OSD.h
src/osd/PG.h
src/osd/PrimaryLogPG.cc
src/osd/PrimaryLogPG.h

index e0e7008078c058010aa30eeb9f654d91b79d67e3..e53a357ff2b23326b703b9750fe70f81a648d8f7 100644 (file)
@@ -16,7 +16,7 @@
 #define CEPH_MMGRCONFIGURE_H_
 
 #include "msg/Message.h"
-#include "mgr/OSDPerfMetricQuery.h"
+#include "mgr/OSDPerfMetricTypes.h"
 
 /**
  * This message is sent from ceph-mgr to MgrClient, instructing it
index 1fbcdcd04ec72c6733fde409b32cd2807e2fe506..82d1bd89e97d9e8721a563c399973235649f84b4 100644 (file)
@@ -18,7 +18,7 @@
 #include <boost/optional.hpp>
 
 #include "msg/Message.h"
-#include "mgr/OSDPerfMetricReport.h"
+#include "mgr/OSDPerfMetricTypes.h"
 
 #include "common/perf_counters.h"
 #include "mgr/DaemonHealthMetric.h"
@@ -107,7 +107,7 @@ public:
   // encode map<string,map<int32_t,string>> of current config
   bufferlist config_bl;
 
-  std::list<OSDPerfMetricReport>  osd_perf_metric_reports;
+  std::map<OSDPerfMetricQuery, OSDPerfMetricReport>  osd_perf_metric_reports;
 
   void decode_payload() override
   {
index 16f781e03a75867f20f0c8f7841232adfb3ef9f6..ae834039717db663519f8ca91b66f52564c6fdde 100644 (file)
 
 #include "DaemonState.h"
 #include "ClusterState.h"
-#include "OSDPerfMetricQuery.h"
+#include "OSDPerfMetricTypes.h"
 
 class health_check_map_t;
 class DaemonServer;
-struct OSDPerfMetricQuery;
 
 class ActivePyModules
 {
index f7fb4f9cb5a0aef875ee7bf4dc1dab80457d1c6a..f8b12747c6032af47594018f581d81fcfc0cfd8c 100644 (file)
@@ -12,7 +12,7 @@ set(mgr_srcs
   Gil.cc
   Mgr.cc
   MgrStandby.cc
-  OSDPerfMetricQuery.cc
+  OSDPerfMetricTypes.cc
   OSDPerfMetricCollector.cc
   PyFormatter.cc
   PyModule.cc
index 99ed41d7b0c4a72c57aead9222fa15cdc37f188c..0abc48ac41353168e3673e255d45263c31d618a9 100644 (file)
@@ -639,6 +639,10 @@ bool DaemonServer::handle_report(MMgrReport *m)
     py_modules.notify_all("perf_schema_update", oss.str());
   }
 
+  if (m->get_connection()->peer_is_osd()) {
+    osd_perf_metric_collector.process_reports(m->osd_perf_metric_reports);
+  }
+
   m->put();
   return true;
 }
index 4bddbe2a19ce65ba2f4cce9a2a86a6d1737aec1d..db5b586127b38cbf1175e37a4bed3949bfac28d9 100644 (file)
@@ -351,7 +351,7 @@ void MgrClient::_send_report()
                            &last_config_bl_version);
 
   if (get_perf_report_cb) {
-    //get_perf_report_cb(&report->perf_report)
+    get_perf_report_cb(&report->osd_perf_metric_reports);
   }
 
   session->con->send_message(report);
@@ -389,16 +389,16 @@ bool MgrClient::handle_mgr_configure(MMgrConfigure *m)
     stats_threshold = m->stats_threshold;
   }
 
+  if (set_perf_queries_cb) {
+    set_perf_queries_cb(m->osd_perf_metric_queries);
+  }
+
   bool starting = (stats_period == 0) && (m->stats_period != 0);
   stats_period = m->stats_period;
   if (starting) {
     _send_stats();
   }
 
-  if (set_perf_queries_cb) {
-    set_perf_queries_cb(m->osd_perf_metric_queries);
-  }
-
   m->put();
   return true;
 }
index 5b561d26170d7cec1053d60d7a9a6f0450832d8f..72348ab23c53a48665559f7382847ede13dc0903 100644 (file)
 #include "mgr/DaemonHealthMetric.h"
 
 #include "messages/MMgrReport.h"
-#include "mgr/OSDPerfMetricQuery.h"
+#include "mgr/OSDPerfMetricTypes.h"
 
 #include "common/perf_counters.h"
 #include "common/Timer.h"
 #include "common/CommandTable.h"
 
-typedef int OSDPerfMetricReport; //Temporary
-
 class MMgrMap;
 class MMgrConfigure;
 class MMgrClose;
@@ -82,7 +80,8 @@ protected:
   // our reports (hook for use by OSD)
   std::function<MPGStats*()> pgstats_cb;
   std::function<void(const std::list<OSDPerfMetricQuery> &)> set_perf_queries_cb;
-  std::function<void(OSDPerfMetricReport *)> get_perf_report_cb;
+  std::function<void(std::map<OSDPerfMetricQuery,
+                              OSDPerfMetricReport> *)> get_perf_report_cb;
 
   // for service registration and beacon
   bool service_daemon = false;
@@ -121,15 +120,14 @@ public:
 
   void set_perf_metric_query_cb(
           std::function<void(const std::list<OSDPerfMetricQuery> &)> cb_set,
-          std::function<void(OSDPerfMetricReport *)> cb_get)
-
+          std::function<void(std::map<OSDPerfMetricQuery,
+                                      OSDPerfMetricReport> *)> cb_get)
   {
       std::lock_guard l(lock);
       set_perf_queries_cb = cb_set;
       get_perf_report_cb = cb_get;
   }
 
-
   void send_pgstats();
   void set_pgstats_cb(std::function<MPGStats*()>&& cb_)
   {
index 6c4354d7abed4036e5eef01c5d9f82408bba16b9..1d922d16ed781c1f9abd1700ce01f78231077765 100644 (file)
@@ -102,3 +102,29 @@ void OSDPerfMetricCollector::remove_all_queries() {
     listener.handle_query_updated();
   }
 }
+
+void OSDPerfMetricCollector::process_reports(
+    const std::map<OSDPerfMetricQuery, OSDPerfMetricReport> &reports) {
+
+  if (reports.empty()) {
+    return;
+  }
+
+  std::lock_guard locker(lock);
+
+  for (auto &it : reports) {
+    auto &report = it.second;
+    dout(10) << "report for " << it.first << " query: "
+             << report.group_packed_performance_counters.size() << " records"
+             << dendl;
+    for (auto &it : report.group_packed_performance_counters) {
+      auto &key = it.first;
+      auto bl_it = it.second.cbegin();
+      for (auto &d : report.performance_counter_descriptors) {
+        PerformanceCounter c;
+        d.unpack_counter(bl_it, &c);
+        dout(20) << "counter " << key << " " << d << ": " << c << dendl;
+      }
+    }
+  }
+}
index 8035da46fa080cc321ca4200ba7ba780d004b9a8..ca32df35ff29b64c5b7acaff059cc4344c4ab8bc 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "common/Mutex.h"
 
-#include "mgr/OSDPerfMetricQuery.h"
+#include "mgr/OSDPerfMetricTypes.h"
 
 #include <list>
 #include <set>
@@ -31,6 +31,9 @@ public:
   int remove_query(OSDPerfMetricQueryID query_id);
   void remove_all_queries();
 
+  void process_reports(
+      const std::map<OSDPerfMetricQuery, OSDPerfMetricReport> &reports);
+
 private:
   typedef std::map<OSDPerfMetricQuery, std::set<OSDPerfMetricQueryID>> Queries;
 
diff --git a/src/mgr/OSDPerfMetricQuery.cc b/src/mgr/OSDPerfMetricQuery.cc
deleted file mode 100644 (file)
index 9b13f69..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#include "OSDPerfMetricQuery.h"
-
-std::ostream& operator<<(std::ostream& os, const OSDPerfMetricQuery &query) {
-  return os << "simple";
-}
diff --git a/src/mgr/OSDPerfMetricQuery.h b/src/mgr/OSDPerfMetricQuery.h
deleted file mode 100644 (file)
index 7082972..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#ifndef OSD_PERF_METRIC_QUERY_H_
-#define OSD_PERF_METRIC_QUERY_H_
-
-#include "include/denc.h"
-
-typedef int OSDPerfMetricQueryID;
-
-struct OSDPerfMetricQuery
-{
-  bool operator<(const OSDPerfMetricQuery &other) const {
-    return false;
-  }
-
-  DENC(OSDPerfMetricQuery, v, p) {
-    DENC_START(1, 1, p);
-    DENC_FINISH(p);
-  }
-};
-WRITE_CLASS_DENC(OSDPerfMetricQuery)
-
-std::ostream& operator<<(std::ostream& os, const OSDPerfMetricQuery &query);
-
-#endif // OSD_PERF_METRIC_QUERY_H_
diff --git a/src/mgr/OSDPerfMetricReport.h b/src/mgr/OSDPerfMetricReport.h
deleted file mode 100644 (file)
index 8868c4b..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-#ifndef OSD_PERF_METRIC_REPORT_H_
-#define OSD_PERF_METRIC_REPORT_H_
-#include "include/denc.h"
-
-#include "common/perf_counters.h"
-
-struct PerformanceCounterDescriptor {
-  std::string name;
-  perfcounter_type_d type;
-};
-
-
-struct OSDPerfMetricReport {
-  std::vector<PerformanceCounterDescriptor> performance_counter_descriptors;
-  std::map<std::string, bufferlist> group_packed_performance_counters;
-
-  DENC(OSDPerfMetricReport, v, p) {
-      DENC_START(1, 1, p);
-//      denc(v.performance_counter_descriptors, p);
-      DENC_FINISH(p);
-  }
-};
-WRITE_CLASS_DENC(OSDPerfMetricReport)
-
-#endif // OSD_PERF_METRIC_REPORT_H_
diff --git a/src/mgr/OSDPerfMetricTypes.cc b/src/mgr/OSDPerfMetricTypes.cc
new file mode 100644 (file)
index 0000000..2177bed
--- /dev/null
@@ -0,0 +1,148 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "mgr/OSDPerfMetricTypes.h"
+#include "messages/MOSDOp.h"
+#include "osd/OpRequest.h"
+
+void PerformanceCounterDescriptor::update_counter(
+    const OpRequest& op, uint64_t inb, uint64_t outb, const utime_t &now,
+    PerformanceCounter *c) const {
+  switch(type) {
+  case PerformanceCounterType::WRITE_OPS:
+    if (op.may_write() || op.may_cache()) {
+      c->first++;
+    }
+    return;
+  case PerformanceCounterType::READ_OPS:
+    if (op.may_read()) {
+      c->first++;
+    }
+    return;
+  case PerformanceCounterType::WRITE_BYTES:
+    if (op.may_write() || op.may_cache()) {
+      c->first += inb;
+      c->second++;
+    }
+    return;
+  case PerformanceCounterType::READ_BYTES:
+    if (op.may_read()) {
+      c->first += outb;
+      c->second++;
+    }
+    return;
+  case PerformanceCounterType::WRITE_LATENCY:
+    if (op.may_write() || op.may_cache()) {
+      const MOSDOp* const m = static_cast<const MOSDOp*>(op.get_req());
+      c->first += (now - m->get_recv_stamp()).to_nsec();
+      c->second++;
+    }
+    return;
+  case PerformanceCounterType::READ_LATENCY:
+    if (op.may_read()) {
+      const MOSDOp* const m = static_cast<const MOSDOp*>(op.get_req());
+      c->first += (now - m->get_recv_stamp()).to_nsec();
+      c->second++;
+    }
+    return;
+  default:
+    ceph_abort_msg("unknown counter type");
+  }
+}
+
+void PerformanceCounterDescriptor::pack_counter(const PerformanceCounter &c,
+                                                bufferlist *bl) const {
+  using ceph::encode;
+  encode(c.first, *bl);
+  switch(type) {
+  case PerformanceCounterType::WRITE_OPS:
+  case PerformanceCounterType::READ_OPS:
+    break;
+  case PerformanceCounterType::WRITE_BYTES:
+  case PerformanceCounterType::READ_BYTES:
+  case PerformanceCounterType::WRITE_LATENCY:
+  case PerformanceCounterType::READ_LATENCY:
+    encode(c.second, *bl);
+    break;
+  default:
+    ceph_abort_msg("unknown counter type");
+  }
+}
+
+void PerformanceCounterDescriptor::unpack_counter(
+    bufferlist::const_iterator& bl, PerformanceCounter *c) const {
+  using ceph::decode;
+  decode(c->first, bl);
+  switch(type) {
+  case PerformanceCounterType::WRITE_OPS:
+  case PerformanceCounterType::READ_OPS:
+    break;
+  case PerformanceCounterType::WRITE_BYTES:
+  case PerformanceCounterType::READ_BYTES:
+  case PerformanceCounterType::WRITE_LATENCY:
+  case PerformanceCounterType::READ_LATENCY:
+    decode(c->second, bl);
+    break;
+  default:
+    ceph_abort_msg("unknown counter type");
+  }
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const PerformanceCounterDescriptor &d) {
+  switch(d.type) {
+  case PerformanceCounterType::WRITE_OPS:
+    return os << "write ops";
+  case PerformanceCounterType::READ_OPS:
+    return os << "read ops";
+  case PerformanceCounterType::WRITE_BYTES:
+    return os << "write bytes";
+  case PerformanceCounterType::READ_BYTES:
+    return os << "read bytes";
+  case PerformanceCounterType::WRITE_LATENCY:
+    return os << "write latency";
+  case PerformanceCounterType::READ_LATENCY:
+    return os << "read latency";
+  default:
+    return os << "unknown (" << d.type << ")";
+  }
+}
+
+bool OSDPerfMetricQuery::get_key(const OpRequest& op, std::string *key) const {
+  const MOSDOp* const m = static_cast<const MOSDOp*>(op.get_req());
+
+  *key = stringify(m->get_reqid().name);
+  return true;
+}
+
+void OSDPerfMetricQuery::update_counters(const OpRequest& op, uint64_t inb,
+                                         uint64_t outb, const utime_t &now,
+                                         PerformanceCounters *counters) const {
+  auto it = counters->begin();
+  for (auto &descriptor : performance_counter_descriptors) {
+    // TODO: optimize
+    if (it == counters->end()) {
+      counters->push_back(PerformanceCounter());
+      it = std::prev(counters->end());
+    }
+    descriptor.update_counter(op, inb, outb, now, &(*it));
+    it++;
+  }
+}
+
+void OSDPerfMetricQuery::pack_counters(const PerformanceCounters &counters,
+                                       bufferlist *bl) const {
+  auto it = counters.begin();
+  for (auto &descriptor : performance_counter_descriptors) {
+    if (it == counters.end()) {
+      descriptor.pack_counter(PerformanceCounter(), bl);
+    } else {
+      descriptor.pack_counter(*it, bl);
+      it++;
+    }
+  }
+}
+
+std::ostream& operator<<(std::ostream& os, const OSDPerfMetricQuery &query) {
+  return os << "simple";
+}
diff --git a/src/mgr/OSDPerfMetricTypes.h b/src/mgr/OSDPerfMetricTypes.h
new file mode 100644 (file)
index 0000000..bd7cf0e
--- /dev/null
@@ -0,0 +1,104 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef OSD_PERF_METRIC_H_
+#define OSD_PERF_METRIC_H_
+
+#include "include/denc.h"
+#include "include/stringify.h"
+
+#include <ostream>
+
+class OpRequest;
+class utime_t;
+
+typedef std::pair<uint64_t,uint64_t> PerformanceCounter;
+typedef std::vector<PerformanceCounter> PerformanceCounters;
+
+enum class PerformanceCounterType : uint8_t {
+  WRITE_OPS = 0,
+  READ_OPS = 1,
+  WRITE_BYTES = 2,
+  READ_BYTES = 3,
+  WRITE_LATENCY = 4,
+  READ_LATENCY = 5,
+};
+
+struct PerformanceCounterDescriptor {
+  PerformanceCounterType type = static_cast<PerformanceCounterType>(-1);
+
+  PerformanceCounterDescriptor() {
+  }
+
+  PerformanceCounterDescriptor(PerformanceCounterType type) : type(type) {
+  }
+
+  DENC(PerformanceCounterDescriptor, v, p) {
+    DENC_START(1, 1, p);
+    denc(v.type, p);
+    DENC_FINISH(p);
+  }
+
+  void update_counter(const OpRequest& op, uint64_t inb, uint64_t outb,
+                      const utime_t &now, PerformanceCounter *c) const;
+  void pack_counter(const PerformanceCounter &c, bufferlist *bl) const;
+  void unpack_counter(bufferlist::const_iterator& bl,
+                      PerformanceCounter *c) const;
+};
+WRITE_CLASS_DENC(PerformanceCounterDescriptor)
+
+std::ostream& operator<<(std::ostream& os,
+                         const PerformanceCounterDescriptor &d);
+
+typedef int OSDPerfMetricQueryID;
+
+struct OSDPerfMetricQuery {
+  bool operator<(const OSDPerfMetricQuery &other) const {
+    return false;
+  }
+
+  bool get_key(const OpRequest& op, std::string *key) const;
+
+  DENC(OSDPerfMetricQuery, v, p) {
+    DENC_START(1, 1, p);
+    denc(v.performance_counter_descriptors, p);
+    DENC_FINISH(p);
+  }
+
+  void get_performance_counter_descriptors(
+      std::vector<PerformanceCounterDescriptor> *descriptors) const {
+    *descriptors = performance_counter_descriptors;
+  }
+
+  void update_counters(const OpRequest& op, uint64_t inb, uint64_t outb,
+                       const utime_t &now, PerformanceCounters *counters) const;
+  void pack_counters(const PerformanceCounters &counters, bufferlist *bl) const;
+
+  std::vector<PerformanceCounterDescriptor> performance_counter_descriptors = {
+    {PerformanceCounterType::WRITE_OPS},
+    {PerformanceCounterType::READ_OPS},
+    {PerformanceCounterType::WRITE_BYTES},
+    {PerformanceCounterType::READ_BYTES},
+    {PerformanceCounterType::WRITE_LATENCY},
+    {PerformanceCounterType::READ_LATENCY},
+  };
+};
+WRITE_CLASS_DENC(OSDPerfMetricQuery)
+
+std::ostream& operator<<(std::ostream& os, const OSDPerfMetricQuery &query);
+
+struct OSDPerfMetricReport {
+  std::vector<PerformanceCounterDescriptor> performance_counter_descriptors;
+  std::map<std::string, bufferlist> group_packed_performance_counters;
+
+  DENC(OSDPerfMetricReport, v, p) {
+    DENC_START(1, 1, p);
+    denc(v.performance_counter_descriptors, p);
+    denc(v.group_packed_performance_counters, p);
+    DENC_FINISH(p);
+  }
+};
+WRITE_CLASS_DENC(OSDPerfMetricReport)
+
+#endif // OSD_PERF_METRIC_H_
+
index 13b63bdce6b67381f38e329597f69d88b824ef46..a1b16b598928abbe2252e0e707fc95f7a8ec947d 100644 (file)
@@ -35,6 +35,7 @@ set(osd_srcs
   OpQueueItem.cc
   ${CMAKE_SOURCE_DIR}/src/common/TrackedOp.cc
   ${CMAKE_SOURCE_DIR}/src/objclass/class_api.cc
+  ${CMAKE_SOURCE_DIR}/src/mgr/OSDPerfMetricTypes.cc
   ${osd_cyg_functions_src}
   ${osdc_osd_srcs})
 if(HAS_VTA)
diff --git a/src/osd/DynamicPerfStats.h b/src/osd/DynamicPerfStats.h
new file mode 100644 (file)
index 0000000..dd19a85
--- /dev/null
@@ -0,0 +1,64 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef DYNAMIC_PERF_STATS_H
+#define DYNAMIC_PERF_STATS_H
+
+#include "mgr/OSDPerfMetricTypes.h"
+
+class DynamicPerfStats {
+public:
+  DynamicPerfStats() {
+  }
+
+  DynamicPerfStats(const std::list<OSDPerfMetricQuery> &queries) {
+    for (auto &query : queries) {
+      data[query];
+    }
+  }
+
+  void set_queries(const std::list<OSDPerfMetricQuery> &queries) {
+    std::map<OSDPerfMetricQuery,
+             std::map<std::string, PerformanceCounters>> new_data;
+    for (auto &query : queries) {
+      std::swap(new_data[query], data[query]);
+    }
+    std::swap(data, new_data);
+  }
+
+  bool is_enabled() {
+    return !data.empty();
+  }
+
+  void add(const OpRequest& op, uint64_t inb, uint64_t outb,
+           const utime_t &now) {
+    for (auto &it : data) {
+      auto &query = it.first;
+      std::string key;
+      if (query.get_key(op, &key)) {
+        query.update_counters(op, inb, outb, now, &it.second[key]);
+      }
+    }
+  }
+
+  void add_to_reports(
+      std::map<OSDPerfMetricQuery, OSDPerfMetricReport> *reports) {
+    for (auto &it : data) {
+      auto &query = it.first;
+      auto &report = (*reports)[query];
+
+      query.get_performance_counter_descriptors(
+          &report.performance_counter_descriptors);
+
+      for (auto &it_counters : it.second) {
+        auto &bl = report.group_packed_performance_counters[it_counters.first];
+        query.pack_counters(it_counters.second, &bl);
+      }
+    }
+  }
+
+private:
+  std::map<OSDPerfMetricQuery, std::map<std::string, PerformanceCounters>> data;
+};
+
+#endif // DYNAMIC_PERF_STATS_H
index 87c3ec84f516e9711e148fff59e22a2692aaca04..aa60abfae033a5e507322cb91ec1edc6092e236d 100644 (file)
@@ -2792,9 +2792,12 @@ int OSD::init()
 
   mgrc.set_pgstats_cb([this](){ return collect_pg_stats(); });
   mgrc.set_perf_metric_query_cb(
-      [this](const std::list<OSDPerfMetricQuery> &queries){ set_perf_queries(queries);},
-      [this](OSDPerfMetricReport *report){ get_perf_report(report);
-    });
+      [this](const std::list<OSDPerfMetricQuery> &queries) {
+        set_perf_queries(queries);
+      },
+      [this](std::map<OSDPerfMetricQuery, OSDPerfMetricReport> *reports) {
+        get_perf_reports(reports);
+      });
   mgrc.init();
   client_messenger->add_dispatcher_head(&mgrc);
 
@@ -4246,6 +4249,11 @@ PGRef OSD::handle_pg_create_info(const OSDMapRef& osdmap,
     false,
     rctx.transaction);
 
+  if (pg->is_primary()) {
+    Mutex::Locker locker(m_perf_queries_lock);
+    pg->set_dynamic_perf_stats_queries(m_perf_queries);
+  }
+
   pg->handle_initialize(&rctx);
   pg->handle_activate_map(&rctx);
 
@@ -9760,9 +9768,38 @@ int OSD::init_op_flags(OpRequestRef& op)
 }
 
 void OSD::set_perf_queries(const std::list<OSDPerfMetricQuery> &queries) {
+  dout(10) << "setting " << queries.size() << " queries" << dendl;
+
+  {
+    Mutex::Locker locker(m_perf_queries_lock);
+    m_perf_queries = queries;
+  }
+
+  std::vector<PGRef> pgs;
+  _get_pgs(&pgs);
+  for (auto& pg : pgs) {
+    if (pg->is_primary()) {
+      pg->lock();
+      pg->set_dynamic_perf_stats_queries(queries);
+      pg->unlock();
+    }
+  }
 }
 
-void OSD::get_perf_report(OSDPerfMetricReport *report) {
+void OSD::get_perf_reports(
+    std::map<OSDPerfMetricQuery, OSDPerfMetricReport> *reports) {
+  std::vector<PGRef> pgs;
+  _get_pgs(&pgs);
+  DynamicPerfStats dps(m_perf_queries);
+  for (auto& pg : pgs) {
+    if (pg->is_primary()) {
+      pg->lock();
+      pg->get_dynamic_perf_stats(&dps);
+      pg->unlock();
+    }
+  }
+  dps.add_to_reports(reports);
+  dout(20) << "reports for " << reports->size() << " queries" << dendl;
 }
 
 // =============================================================
index 4b6cf8edecd279a4810ca9dc64dce172972c631a..580536929b76e98dae5bbbf424152b997ebbb536 100644 (file)
@@ -2315,7 +2315,11 @@ public:
 
 private:
   void set_perf_queries(const std::list<OSDPerfMetricQuery> &queries);
-  void get_perf_report(OSDPerfMetricReport *report);
+  void get_perf_reports(
+      std::map<OSDPerfMetricQuery, OSDPerfMetricReport> *reports);
+
+  Mutex m_perf_queries_lock = {"OSD::m_perf_queries_lock"};
+  std::list<OSDPerfMetricQuery> m_perf_queries;
 };
 
 
index 817801b7859e9be75d7de7c047fc50cebd8fd399..9fe129ab04dc7116ce6fabe1f109f0f42cc0bbb8 100644 (file)
@@ -45,6 +45,8 @@
 #include "PGBackend.h"
 #include "PGPeeringEvent.h"
 
+#include "mgr/OSDPerfMetricTypes.h"
+
 #include <atomic>
 #include <list>
 #include <memory>
@@ -69,6 +71,7 @@ struct OpRequest;
 typedef OpRequest::Ref OpRequestRef;
 class MOSDPGLog;
 class CephContext;
+class DynamicPerfStats;
 
 namespace Scrub {
   class Store;
@@ -482,6 +485,12 @@ public:
 
   void _delete_some(ObjectStore::Transaction *t);
 
+  virtual void set_dynamic_perf_stats_queries(
+    const std::list<OSDPerfMetricQuery> &queries) {
+  }
+  virtual void get_dynamic_perf_stats(DynamicPerfStats *stats) {
+  }
+
   // reference counting
 #ifdef PG_DEBUG_REFS
   uint64_t get_with_id();
index bb0356713ee3b30106f02e442eeadf9447916309..f26f4bdfd9f98d64c21cba10d8af66f2d65458aa 100644 (file)
@@ -4139,6 +4139,21 @@ void PrimaryLogPG::log_op_stats(const OpRequest& op,
           << " inb " << inb
           << " outb " << outb
           << " lat " << latency << dendl;
+
+  if (m_dynamic_perf_stats.is_enabled()) {
+    m_dynamic_perf_stats.add(op, inb, outb, latency);
+  }
+}
+
+void PrimaryLogPG::set_dynamic_perf_stats_queries(
+    const std::list<OSDPerfMetricQuery> &queries)
+{
+  m_dynamic_perf_stats.set_queries(queries);
+}
+
+void PrimaryLogPG::get_dynamic_perf_stats(DynamicPerfStats *stats)
+{
+  std::swap(m_dynamic_perf_stats, *stats);
 }
 
 void PrimaryLogPG::do_scan(
index ad52529788b467c9bb604a0e6933c1d1f7cb5fcd..2eb333692933258ca9cc3f89fae6f8591ed51971 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <boost/tuple/tuple.hpp>
 #include "include/ceph_assert.h"
+#include "DynamicPerfStats.h"
 #include "OSD.h"
 #include "PG.h"
 #include "Watch.h"
@@ -1871,6 +1872,14 @@ public:
   int getattrs_maybe_cache(
     ObjectContextRef obc,
     map<string, bufferlist> *out);
+
+public:
+  void set_dynamic_perf_stats_queries(
+      const std::list<OSDPerfMetricQuery> &queries)  override;
+  void get_dynamic_perf_stats(DynamicPerfStats *stats)  override;
+
+private:
+  DynamicPerfStats m_dynamic_perf_stats;
 };
 
 inline ostream& operator<<(ostream& out, const PrimaryLogPG::RepGather& repop)