]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: add read/write io size metric support
authorXiubo Li <xiubli@redhat.com>
Tue, 30 Mar 2021 02:29:26 +0000 (10:29 +0800)
committerXiubo Li <xiubli@redhat.com>
Tue, 19 Oct 2021 01:30:58 +0000 (09:30 +0800)
It will support total_ops/total_size metrics for read and write. and
the cephfs-top tool will show total io sizes for read/write.

Fixes: https://tracker.ceph.com/issues/49811
Signed-off-by: Xiubo Li <xiubli@redhat.com>
14 files changed:
doc/man/8/cephfs-top.rst
src/client/Client.cc
src/client/Client.h
src/include/cephfs/metrics/Types.h
src/mds/MDSPerfMetricTypes.h
src/mds/MetricAggregator.cc
src/mds/MetricsHandler.cc
src/mds/MetricsHandler.h
src/mds/cephfs_features.h
src/mgr/BaseMgrModule.cc
src/mgr/MDSPerfMetricTypes.cc
src/mgr/MDSPerfMetricTypes.h
src/pybind/mgr/stats/fs/perf_stats.py
src/tools/cephfs/top/cephfs-top

index bad687f9aa61fb02d1bbb7e10b3360078d69f567..3a01bb7cdc9e531615335a05c453da4645bc4b1e 100644 (file)
@@ -71,6 +71,14 @@ Descriptions of fields
 
    number of opened inodes
 
+.. describe:: rtio
+
+   total size of read IOs
+
+.. describe:: wtio
+
+   total size of write IOs
+
 
 Availability
 ============
index b5ecc881164e51b5c66e55ae05656f39653b73f5..0ca97c06ca868f14143648cf75d4a385fc53cc3f 100644 (file)
@@ -6712,6 +6712,16 @@ void Client::collect_and_send_global_metrics() {
   }
   message.push_back(metric);
 
+  // read io sizes
+  metric = ClientMetricMessage(ReadIoSizesPayload(total_read_ops,
+                                                  total_read_size));
+  message.push_back(metric);
+
+  // write io sizes
+  metric = ClientMetricMessage(WriteIoSizesPayload(total_write_ops,
+                                                   total_write_size));
+  message.push_back(metric);
+
   session->con->send_message2(make_message<MClientMetrics>(std::move(message)));
 }
 
@@ -9944,6 +9954,7 @@ retry:
 
 success:
   ceph_assert(rc >= 0);
+  update_read_io_size(bl->length());
   if (movepos) {
     // adjust fd pos
     f->pos = start_pos + rc;
@@ -9991,6 +10002,9 @@ Client::C_Readahead::~C_Readahead() {
 void Client::C_Readahead::finish(int r) {
   lgeneric_subdout(client->cct, client, 20) << "client." << client->get_nodeid() << " " << "C_Readahead on " << f->inode << dendl;
   client->put_cap_ref(f->inode.get(), CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE);
+  if (r > 0) {
+    client->update_read_io_size(r);
+  }
 }
 
 int Client::_read_async(Fh *f, uint64_t off, uint64_t len, bufferlist *bl)
@@ -10026,6 +10040,7 @@ int Client::_read_async(Fh *f, uint64_t off, uint64_t len, bufferlist *bl)
     r = onfinish.wait();
     client_lock.lock();
     put_cap_ref(in, CEPH_CAP_FILE_CACHE);
+    update_read_io_size(bl->length());
   }
 
   if(f->readahead.get_min_readahead_size() > 0) {
@@ -10403,6 +10418,7 @@ int64_t Client::_write(Fh *f, int64_t offset, uint64_t size, const char *buf,
 
   // if we get here, write was successful, update client metadata
 success:
+  update_write_io_size(size);
   // time
   lat = ceph_clock_now();
   lat -= start;
index bbf1619fedfddf804f151a50993861b2b62f0206..2a578bd38e1dd42b534505da20da72ba56ae4d43 100644 (file)
@@ -811,6 +811,16 @@ public:
   void tick();
   void start_tick_thread();
 
+  void update_read_io_size(size_t size) {
+    total_read_ops++;
+    total_read_size += size;
+  }
+
+  void update_write_io_size(size_t size) {
+    total_write_ops++;
+    total_write_size += size;
+  }
+
   void inc_dentry_nr() {
     ++dentry_nr;
   }
@@ -1558,6 +1568,12 @@ private:
   uint64_t pinned_icaps = 0;
   uint64_t opened_inodes = 0;
 
+  uint64_t total_read_ops = 0;
+  uint64_t total_read_size = 0;
+
+  uint64_t total_write_ops = 0;
+  uint64_t total_write_size = 0;
+
   ceph::spinlock delay_i_lock;
   std::map<Inode*,int> delay_i_release;
 };
index 2d944bb5b271722ed80782c089b8568745d4a36e..7f5a40e245d89c8f3f9ebffcaea0f1a5e817f819 100644 (file)
@@ -25,6 +25,8 @@ enum ClientMetricType {
   CLIENT_METRIC_TYPE_OPENED_FILES,
   CLIENT_METRIC_TYPE_PINNED_ICAPS,
   CLIENT_METRIC_TYPE_OPENED_INODES,
+  CLIENT_METRIC_TYPE_READ_IO_SIZES,
+  CLIENT_METRIC_TYPE_WRITE_IO_SIZES,
 };
 inline std::ostream &operator<<(std::ostream &os, const ClientMetricType &type) {
   switch(type) {
@@ -52,6 +54,12 @@ inline std::ostream &operator<<(std::ostream &os, const ClientMetricType &type)
   case ClientMetricType::CLIENT_METRIC_TYPE_OPENED_INODES:
     os << "OPENED_INODES";
     break;
+  case ClientMetricType::CLIENT_METRIC_TYPE_READ_IO_SIZES:
+    os << "READ_IO_SIZES";
+    break;
+  case ClientMetricType::CLIENT_METRIC_TYPE_WRITE_IO_SIZES:
+    os << "WRITE_IO_SIZES";
+    break;
   default:
     os << "(UNKNOWN:" << static_cast<std::underlying_type<ClientMetricType>::type>(type) << ")";
     break;
@@ -367,6 +375,79 @@ struct OpenedInodesPayload : public ClientMetricPayloadBase {
   }
 };
 
+struct ReadIoSizesPayload : public ClientMetricPayloadBase {
+  uint64_t total_ops = 0;
+  uint64_t total_size = 0;
+
+  ReadIoSizesPayload()
+    : ClientMetricPayloadBase(ClientMetricType::CLIENT_METRIC_TYPE_READ_IO_SIZES) { }
+  ReadIoSizesPayload(uint64_t total_ops, uint64_t total_size)
+    : ClientMetricPayloadBase(ClientMetricType::CLIENT_METRIC_TYPE_READ_IO_SIZES),
+    total_ops(total_ops), total_size(total_size) {  }
+
+  void encode(bufferlist &bl) const {
+    using ceph::encode;
+    ENCODE_START(1, 1, bl);
+    encode(total_ops, bl);
+    encode(total_size, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator &iter) {
+    using ceph::decode;
+    DECODE_START(1, iter);
+    decode(total_ops, iter);
+    decode(total_size, iter);
+    DECODE_FINISH(iter);
+  }
+
+  void dump(Formatter *f) const {
+    f->dump_int("total_ops", total_ops);
+    f->dump_int("total_size", total_size);
+  }
+
+  void print(std::ostream *out) const {
+    *out << "total_ops: " << total_ops << " total_size: " << total_size;
+  }
+};
+
+struct WriteIoSizesPayload : public ClientMetricPayloadBase {
+  uint64_t total_ops = 0;
+  uint64_t total_size = 0;
+
+  WriteIoSizesPayload()
+    : ClientMetricPayloadBase(ClientMetricType::CLIENT_METRIC_TYPE_WRITE_IO_SIZES) { }
+  WriteIoSizesPayload(uint64_t total_ops, uint64_t total_size)
+    : ClientMetricPayloadBase(ClientMetricType::CLIENT_METRIC_TYPE_WRITE_IO_SIZES),
+    total_ops(total_ops), total_size(total_size) {
+  }
+
+  void encode(bufferlist &bl) const {
+    using ceph::encode;
+    ENCODE_START(1, 1, bl);
+    encode(total_ops, bl);
+    encode(total_size, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator &iter) {
+    using ceph::decode;
+    DECODE_START(1, iter);
+    decode(total_ops, iter);
+    decode(total_size, iter);
+    DECODE_FINISH(iter);
+  }
+
+  void dump(Formatter *f) const {
+    f->dump_int("total_ops", total_ops);
+    f->dump_int("total_size", total_size);
+  }
+
+  void print(std::ostream *out) const {
+    *out << "total_ops: " << total_ops << " total_size: " << total_size;
+  }
+};
+
 struct UnknownPayload : public ClientMetricPayloadBase {
   UnknownPayload()
     : ClientMetricPayloadBase(static_cast<ClientMetricType>(-1)) { }
@@ -394,10 +475,12 @@ typedef boost::variant<CapInfoPayload,
                        ReadLatencyPayload,
                        WriteLatencyPayload,
                        MetadataLatencyPayload,
-                      DentryLeasePayload,
-                      OpenedFilesPayload,
-                      PinnedIcapsPayload,
-                      OpenedInodesPayload,
+                       DentryLeasePayload,
+                       OpenedFilesPayload,
+                       PinnedIcapsPayload,
+                       OpenedInodesPayload,
+                       ReadIoSizesPayload,
+                       WriteIoSizesPayload,
                        UnknownPayload> ClientMetricPayload;
 
 // metric update message sent by clients
@@ -506,6 +589,12 @@ public:
     case ClientMetricType::CLIENT_METRIC_TYPE_OPENED_INODES:
       payload = OpenedInodesPayload();
       break;
+    case ClientMetricType::CLIENT_METRIC_TYPE_READ_IO_SIZES:
+      payload = ReadIoSizesPayload();
+      break;
+    case ClientMetricType::CLIENT_METRIC_TYPE_WRITE_IO_SIZES:
+      payload = WriteIoSizesPayload();
+      break;
     default:
       payload = UnknownPayload(static_cast<ClientMetricType>(metric_type));
       break;
index de69a4277b4aa958f40239df893f6444f1f12c24..6bf64e91809fafcaf9038d51acd586bb4e551ec1 100644 (file)
@@ -202,6 +202,54 @@ struct OpenedInodesMetric {
   }
 };
 
+struct ReadIoSizesMetric {
+  uint64_t total_ops = 0;
+  uint64_t total_size = 0;
+  bool updated = false;
+
+  DENC(ReadIoSizesMetric, v, p) {
+    DENC_START(1, 1, p);
+    denc(v.total_ops, p);
+    denc(v.total_size, p);
+    denc(v.updated, p);
+    DENC_FINISH(p);
+  }
+
+  void dump(Formatter *f) const {
+    f->dump_unsigned("total_ops", total_ops);
+    f->dump_unsigned("total_size", total_size);
+  }
+
+  friend std::ostream& operator<<(std::ostream& os, const ReadIoSizesMetric &metric) {
+    os << "{total_ops=" << metric.total_ops << ", total_size=" << metric.total_size <<"}";
+    return os;
+  }
+};
+
+struct WriteIoSizesMetric {
+  uint64_t total_ops = 0;
+  uint64_t total_size = 0;
+  bool updated = false;
+
+  DENC(WriteIoSizesMetric, v, p) {
+    DENC_START(1, 1, p);
+    denc(v.total_ops, p);
+    denc(v.total_size, p);
+    denc(v.updated, p);
+    DENC_FINISH(p);
+  }
+
+  void dump(Formatter *f) const {
+    f->dump_unsigned("total_ops", total_ops);
+    f->dump_unsigned("total_size", total_size);
+  }
+
+  friend std::ostream& operator<<(std::ostream& os, const WriteIoSizesMetric &metric) {
+    os << "{total_ops=" << metric.total_ops << ", total_size=" << metric.total_size <<"}";
+    return os;
+  }
+};
+
 WRITE_CLASS_DENC(CapHitMetric)
 WRITE_CLASS_DENC(ReadLatencyMetric)
 WRITE_CLASS_DENC(WriteLatencyMetric)
@@ -210,6 +258,8 @@ WRITE_CLASS_DENC(DentryLeaseHitMetric)
 WRITE_CLASS_DENC(OpenedFilesMetric)
 WRITE_CLASS_DENC(PinnedIcapsMetric)
 WRITE_CLASS_DENC(OpenedInodesMetric)
+WRITE_CLASS_DENC(ReadIoSizesMetric)
+WRITE_CLASS_DENC(WriteIoSizesMetric)
 
 // metrics that are forwarded to the MDS by client(s).
 struct Metrics {
@@ -222,12 +272,14 @@ struct Metrics {
   OpenedFilesMetric opened_files_metric;
   PinnedIcapsMetric pinned_icaps_metric;
   OpenedInodesMetric opened_inodes_metric;
+  ReadIoSizesMetric read_io_sizes_metric;
+  WriteIoSizesMetric write_io_sizes_metric;
 
   // metric update type
   uint32_t update_type = UpdateType::UPDATE_TYPE_REFRESH;
 
   DENC(Metrics, v, p) {
-    DENC_START(3, 1, p);
+    DENC_START(4, 1, p);
     denc(v.update_type, p);
     denc(v.cap_hit_metric, p);
     denc(v.read_latency_metric, p);
@@ -241,6 +293,10 @@ struct Metrics {
       denc(v.pinned_icaps_metric, p);
       denc(v.opened_inodes_metric, p);
     }
+    if (struct_v >= 4) {
+      denc(v.read_io_sizes_metric, p);
+      denc(v.write_io_sizes_metric, p);
+    }
     DENC_FINISH(p);
   }
 
@@ -254,6 +310,8 @@ struct Metrics {
     f->dump_object("opened_files_metric", opened_files_metric);
     f->dump_object("pinned_icaps_metric", pinned_icaps_metric);
     f->dump_object("opened_inodes_metric", opened_inodes_metric);
+    f->dump_object("read_io_sizes_metric", read_io_sizes_metric);
+    f->dump_object("write_io_sizes_metric", write_io_sizes_metric);
   }
 
   friend std::ostream& operator<<(std::ostream& os, const Metrics& metrics) {
@@ -262,10 +320,12 @@ struct Metrics {
        << ", read_latency=" << metrics.read_latency_metric
        << ", write_latency=" << metrics.write_latency_metric
        << ", metadata_latency=" << metrics.metadata_latency_metric
-       << ", dentry_lease =" << metrics.dentry_lease_metric
-       << ", opened_files_metric =" << metrics.opened_files_metric
-       << ", pinned_icaps_metric =" << metrics.pinned_icaps_metric
-       << ", opened_inodes_metric =" << metrics.opened_inodes_metric
+       << ", dentry_lease=" << metrics.dentry_lease_metric
+       << ", opened_files_metric=" << metrics.opened_files_metric
+       << ", pinned_icaps_metric=" << metrics.pinned_icaps_metric
+       << ", opened_inodes_metric=" << metrics.opened_inodes_metric
+       << ", read_io_sizes_metric=" << metrics.read_io_sizes_metric
+       << ", write_io_sizes_metric=" << metrics.write_io_sizes_metric
        << "}]";
     return os;
   }
index 8d98db5fd49d09586ff06d1bf730c851bdc14e96..046e79269868e2b34791e1d1232eaec9e2ebc929 100644 (file)
@@ -156,6 +156,18 @@ void MetricAggregator::refresh_metrics_for_rank(const entity_inst_t &client,
         c->second = metrics.opened_inodes_metric.total_inodes;
       }
       break;
+    case MDSPerformanceCounterType::READ_IO_SIZES_METRIC:
+      if (metrics.read_io_sizes_metric.updated) {
+        c->first = metrics.read_io_sizes_metric.total_ops;
+        c->second = metrics.read_io_sizes_metric.total_size;
+      }
+      break;
+    case MDSPerformanceCounterType::WRITE_IO_SIZES_METRIC:
+      if (metrics.write_io_sizes_metric.updated) {
+        c->first = metrics.write_io_sizes_metric.total_ops;
+        c->second = metrics.write_io_sizes_metric.total_size;
+      }
+      break;
     default:
       ceph_abort_msg("unknown counter type");
     }
index 6695441b63c2964244f2f8cac80acf3bfb392458..3fcaaaec1fab667dd22862962802f697311e0f6c 100644 (file)
@@ -127,6 +127,8 @@ void MetricsHandler::remove_session(Session *session) {
   metrics.opened_files_metric = { };
   metrics.pinned_icaps_metric = { };
   metrics.opened_inodes_metric = { };
+  metrics.read_io_sizes_metric = { };
+  metrics.write_io_sizes_metric = { };
   metrics.update_type = UPDATE_TYPE_REMOVE;
 }
 
@@ -275,6 +277,40 @@ void MetricsHandler::handle_payload(Session *session, const OpenedInodesPayload
   metrics.opened_inodes_metric.updated = true;
 }
 
+void MetricsHandler::handle_payload(Session *session, const ReadIoSizesPayload &payload) {
+  dout(20) << ": type=" << payload.get_type()
+           << ", session=" << session << ", total_ops=" << payload.total_ops
+           << ", total_size=" << payload.total_size << dendl;
+
+  auto it = client_metrics_map.find(session->info.inst);
+  if (it == client_metrics_map.end()) {
+    return;
+  }
+
+  auto &metrics = it->second.second;
+  metrics.update_type = UPDATE_TYPE_REFRESH;
+  metrics.read_io_sizes_metric.total_ops = payload.total_ops;
+  metrics.read_io_sizes_metric.total_size = payload.total_size;
+  metrics.read_io_sizes_metric.updated = true;
+}
+
+void MetricsHandler::handle_payload(Session *session, const WriteIoSizesPayload &payload) {
+  dout(20) << ": type=" << payload.get_type()
+           << ", session=" << session << ", total_ops=" << payload.total_ops
+           << ", total_size=" << payload.total_size << dendl;
+
+  auto it = client_metrics_map.find(session->info.inst);
+  if (it == client_metrics_map.end()) {
+    return;
+  }
+
+  auto &metrics = it->second.second;
+  metrics.update_type = UPDATE_TYPE_REFRESH;
+  metrics.write_io_sizes_metric.total_ops = payload.total_ops;
+  metrics.write_io_sizes_metric.total_size = payload.total_size;
+  metrics.write_io_sizes_metric.updated = true;
+}
+
 void MetricsHandler::handle_payload(Session *session, const UnknownPayload &payload) {
   dout(5) << ": type=Unknown, session=" << session << ", ignoring unknown payload" << dendl;
 }
index 65bcf488b5f064fb7c958155e43fef28700c0538..0b75b0248607703bdb92d0e5bf17e9b352436525 100644 (file)
@@ -98,6 +98,8 @@ private:
   void handle_payload(Session *session, const OpenedFilesPayload &payload);
   void handle_payload(Session *session, const PinnedIcapsPayload &payload);
   void handle_payload(Session *session, const OpenedInodesPayload &payload);
+  void handle_payload(Session *session, const ReadIoSizesPayload &payload);
+  void handle_payload(Session *session, const WriteIoSizesPayload &payload);
   void handle_payload(Session *session, const UnknownPayload &payload);
 
   void set_next_seq(version_t seq);
index 848beae5a16070bb08933c0fedc13881d5c8a07a..e934914ba5bb23857b5adc6d6c3397ed7ce4f8be 100644 (file)
@@ -71,6 +71,8 @@ namespace ceph {
     CLIENT_METRIC_TYPE_OPENED_FILES,           \
     CLIENT_METRIC_TYPE_PINNED_ICAPS,           \
     CLIENT_METRIC_TYPE_OPENED_INODES,          \
+    CLIENT_METRIC_TYPE_READ_IO_SIZES,          \
+    CLIENT_METRIC_TYPE_WRITE_IO_SIZES,         \
 }
 
 #define CEPHFS_FEATURES_MDS_SUPPORTED CEPHFS_FEATURES_ALL
index 6386265fc7e919fa70bb43e18a53d7c7cd6669ec..70bbe66052a50c219c884500dfdcad70854220a6 100644 (file)
@@ -1095,6 +1095,8 @@ ceph_add_mds_perf_query(BaseMgrModule *self, PyObject *args)
     {"opened_files", MDSPerformanceCounterType::OPENED_FILES_METRIC},
     {"pinned_icaps", MDSPerformanceCounterType::PINNED_ICAPS_METRIC},
     {"opened_inodes", MDSPerformanceCounterType::OPENED_INODES_METRIC},
+    {"read_io_sizes", MDSPerformanceCounterType::READ_IO_SIZES_METRIC},
+    {"write_io_sizes", MDSPerformanceCounterType::WRITE_IO_SIZES_METRIC},
   };
 
   PyObject *py_query = nullptr;
index bbba88a76bb509d3f101d5bc3b04a889c8edf33a..5568cbe5d7a319e8c9fea36e80ccc922567f19b1 100644 (file)
@@ -33,6 +33,8 @@ void MDSPerformanceCounterDescriptor::pack_counter(
   case MDSPerformanceCounterType::OPENED_FILES_METRIC:
   case MDSPerformanceCounterType::PINNED_ICAPS_METRIC:
   case MDSPerformanceCounterType::OPENED_INODES_METRIC:
+  case MDSPerformanceCounterType::READ_IO_SIZES_METRIC:
+  case MDSPerformanceCounterType::WRITE_IO_SIZES_METRIC:
     break;
   default:
     ceph_abort_msg("unknown counter type");
@@ -53,6 +55,8 @@ void MDSPerformanceCounterDescriptor::unpack_counter(
   case MDSPerformanceCounterType::OPENED_FILES_METRIC:
   case MDSPerformanceCounterType::PINNED_ICAPS_METRIC:
   case MDSPerformanceCounterType::OPENED_INODES_METRIC:
+  case MDSPerformanceCounterType::READ_IO_SIZES_METRIC:
+  case MDSPerformanceCounterType::WRITE_IO_SIZES_METRIC:
     break;
   default:
     ceph_abort_msg("unknown counter type");
@@ -85,6 +89,12 @@ std::ostream& operator<<(std::ostream &os, const MDSPerformanceCounterDescriptor
    case MDSPerformanceCounterType::OPENED_INODES_METRIC:
      os << "opened_inodes_metric";
      break;
+   case MDSPerformanceCounterType::READ_IO_SIZES_METRIC:
+     os << "read_io_sizes_metric";
+     break;
+   case MDSPerformanceCounterType::WRITE_IO_SIZES_METRIC:
+     os << "write_io_sizes_metric";
+     break;
    }
 
    return os;
index 41b183b05e297e9c4a1f468a320cb03dc2d2b9d2..b778b0347431a1a0eda267c41dcadfc86ea28277 100644 (file)
@@ -124,6 +124,8 @@ enum class MDSPerformanceCounterType : uint8_t {
   OPENED_FILES_METRIC = 5,
   PINNED_ICAPS_METRIC = 6,
   OPENED_INODES_METRIC = 7,
+  READ_IO_SIZES_METRIC = 8,
+  WRITE_IO_SIZES_METRIC = 9,
 };
 
 struct MDSPerformanceCounterDescriptor {
@@ -139,6 +141,8 @@ struct MDSPerformanceCounterDescriptor {
     case MDSPerformanceCounterType::OPENED_FILES_METRIC:
     case MDSPerformanceCounterType::PINNED_ICAPS_METRIC:
     case MDSPerformanceCounterType::OPENED_INODES_METRIC:
+    case MDSPerformanceCounterType::READ_IO_SIZES_METRIC:
+    case MDSPerformanceCounterType::WRITE_IO_SIZES_METRIC:
       return true;
     default:
       return false;
index 09b82a23e22cca1d6ee441cf3fec383072381ab9..a66bc7bef7173d3e908023c23bbe0fa5b06359f7 100644 (file)
@@ -33,9 +33,11 @@ MDS_PERF_QUERY_COUNTERS_MAP = OrderedDict({'cap_hit': 0,
                                            'dentry_lease': 4,
                                            'opened_files': 5,
                                            'pinned_icaps': 6,
-                                           'opened_inodes': 7})
+                                           'opened_inodes': 7,
+                                           'read_io_sizes': 8,
+                                           'write_io_sizes': 9})
 MDS_PERF_QUERY_COUNTERS = [] # type: List[str]
-MDS_GLOBAL_PERF_QUERY_COUNTERS = ['cap_hit', 'read_latency', 'write_latency', 'metadata_latency', 'dentry_lease', 'opened_files', 'pinned_icaps', 'opened_inodes'] # type: List[str]
+MDS_GLOBAL_PERF_QUERY_COUNTERS = ['cap_hit', 'read_latency', 'write_latency', 'metadata_latency', 'dentry_lease', 'opened_files', 'pinned_icaps', 'opened_inodes', 'read_io_sizes', 'write_io_sizes'] # type: List[str]
 
 QUERY_EXPIRE_INTERVAL = timedelta(minutes=1)
 
index 2e35adaabcc4cb22f67b00c68a68d57ecee1c819..43019af706a4f4fb18e435f47d661d0304853f61 100755 (executable)
@@ -28,6 +28,7 @@ class MetricType(Enum):
     METRIC_TYPE_NONE = 0
     METRIC_TYPE_PERCENTAGE = 1
     METRIC_TYPE_LATENCY = 2
+    METRIC_TYPE_SIZE = 3
 
 
 FS_TOP_PROG_STR = 'cephfs-top'
@@ -62,6 +63,8 @@ MAIN_WINDOW_TOP_LINE_METRICS = OrderedDict([
     ("OPENED_FILES", MetricType.METRIC_TYPE_NONE),
     ("PINNED_ICAPS", MetricType.METRIC_TYPE_NONE),
     ("OPENED_INODES", MetricType.METRIC_TYPE_NONE),
+    ("READ_IO_SIZES", MetricType.METRIC_TYPE_SIZE),
+    ("WRITE_IO_SIZES", MetricType.METRIC_TYPE_SIZE),
 ])
 MGR_STATS_COUNTERS = list(MAIN_WINDOW_TOP_LINE_METRICS.keys())
 
@@ -90,6 +93,11 @@ def calc_lat(c):
     return round(c[0] + c[1] / 1000000000, 2)
 
 
+# in MB
+def calc_size(c):
+    return round(c[1] / (1024 * 1024), 2)
+
+
 def wrap(s, sl):
     """return a '+' suffixed wrapped string"""
     if len(s) < sl:
@@ -197,6 +205,10 @@ class FSTop(object):
             return "oicaps"
         if item == "OPENED_INODES":
             return "oinodes"
+        if item == "READ_IO_SIZES":
+            return "rtio"
+        if item == "WRITE_IO_SIZES":
+            return "wtio"
         else:
             # return empty string for none type
             return ''
@@ -206,6 +218,8 @@ class FSTop(object):
             return "(%)"
         elif typ == MetricType.METRIC_TYPE_LATENCY:
             return "(s)"
+        elif typ == MetricType.METRIC_TYPE_SIZE:
+            return "(MB)"
         else:
             # return empty string for none type
             return ''
@@ -294,6 +308,8 @@ class FSTop(object):
                     self.mainw.addnstr(y_coord, coord[0], f'{calc_perc(m)}', hlen)
                 elif typ == MetricType.METRIC_TYPE_LATENCY:
                     self.mainw.addnstr(y_coord, coord[0], f'{calc_lat(m)}', hlen)
+                elif typ == MetricType.METRIC_TYPE_SIZE:
+                    self.mainw.addnstr(y_coord, coord[0], f'{calc_size(m)}', hlen)
                 else:
                     # display 0th element from metric tuple
                     self.mainw.addnstr(y_coord, coord[0], f'{m[0]}', hlen)