]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: new message type for providing client side metrics
authorVenky Shankar <vshankar@redhat.com>
Thu, 17 Jan 2019 06:52:46 +0000 (01:52 -0500)
committerVenky Shankar <vshankar@redhat.com>
Mon, 1 Jun 2020 08:04:08 +0000 (04:04 -0400)
Signed-off-by: Venky Shankar <vshankar@redhat.com>
alpine/APKBUILD.in
ceph.spec.in
debian/libcephfs-dev.install
src/include/ceph_fs.h
src/include/cephfs/metrics/Types.h [new file with mode: 0644]
src/messages/MClientMetrics.h [new file with mode: 0644]
src/msg/Message.cc

index a9a9a58ecfced5e547783fab35340dce6eb0e168..7b04393eddd2a3583b69f38ed08756b0929712e1 100644 (file)
@@ -396,7 +396,7 @@ libcephfs_dev() {
        pkgdesc="Ceph distributed file system client library headers"
        depends="libcephfs librados-devel"
 
-       _pkg $_includedir/cephfs ceph_ll_client.h libcephfs.h
+       _pkg $_includedir/cephfs ceph_ll_client.h libcephfs.h metrics/Types.h
        _pkg $_libdir libcephfs.so
 }
 
index eda4c6a8da7ee50e9bf4250a689208412e3e1d02..2ab2042ff9b2dda67ce50c5cd5a383dcf653637d 100644 (file)
@@ -2186,6 +2186,7 @@ fi
 %dir %{_includedir}/cephfs
 %{_includedir}/cephfs/libcephfs.h
 %{_includedir}/cephfs/ceph_ll_client.h
+%{_includedir}/cephfs/metrics/Types.h
 %{_libdir}/libcephfs.so
 
 %files -n python%{python3_pkgversion}-cephfs
index fbc1e4b95ffe6755087e89e4e9718619f676e6e9..e06363ad7008a9483d5c2b55b572db47a7a61d4c 100644 (file)
@@ -1,3 +1,4 @@
 usr/include/cephfs/ceph_ll_client.h
 usr/include/cephfs/libcephfs.h
+usr/include/cephfs/metrics/Types.h
 usr/lib/libcephfs.so
index b01b09adda56a98a9802e32f5a876803f4fa4221..d8ae8271e2ff593296134b8e07fe55a8e4f27fa9 100644 (file)
@@ -151,6 +151,7 @@ extern const char *ceph_con_mode_name(int con_mode);
 #define CEPH_MSG_CLIENT_REPLY           26
 #define CEPH_MSG_CLIENT_RECLAIM                27
 #define CEPH_MSG_CLIENT_RECLAIM_REPLY   28
+#define CEPH_MSG_CLIENT_METRICS         29
 #define CEPH_MSG_CLIENT_CAPS            0x310
 #define CEPH_MSG_CLIENT_LEASE           0x311
 #define CEPH_MSG_CLIENT_SNAP            0x312
diff --git a/src/include/cephfs/metrics/Types.h b/src/include/cephfs/metrics/Types.h
new file mode 100644 (file)
index 0000000..01f4d7e
--- /dev/null
@@ -0,0 +1,284 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_INCLUDE_CEPHFS_METRICS_TYPES_H
+#define CEPH_INCLUDE_CEPHFS_METRICS_TYPES_H
+
+#include <string>
+#include <boost/variant.hpp>
+
+#include "common/Formatter.h"
+#include "include/buffer_fwd.h"
+#include "include/encoding.h"
+#include "include/int_types.h"
+#include "include/stringify.h"
+#include "include/utime.h"
+
+namespace ceph { class Formatter; }
+
+enum ClientMetricType {
+  CLIENT_METRIC_TYPE_CAP_INFO,
+  CLIENT_METRIC_TYPE_READ_LATENCY,
+  CLIENT_METRIC_TYPE_WRITE_LATENCY,
+  CLIENT_METRIC_TYPE_METADATA_LATENCY,
+};
+inline std::ostream &operator<<(std::ostream &os, const ClientMetricType &type) {
+  switch(type) {
+  case ClientMetricType::CLIENT_METRIC_TYPE_CAP_INFO:
+    os << "CAP_INFO";
+    break;
+  case ClientMetricType::CLIENT_METRIC_TYPE_READ_LATENCY:
+    os << "READ_LATENCY";
+    break;
+  case ClientMetricType::CLIENT_METRIC_TYPE_WRITE_LATENCY:
+    os << "WRITE_LATENCY";
+    break;
+  case ClientMetricType::CLIENT_METRIC_TYPE_METADATA_LATENCY:
+    os << "METADATA_LATENCY";
+    break;
+  default:
+    ceph_abort();
+  }
+
+  return os;
+}
+
+struct CapInfoPayload {
+  static const ClientMetricType METRIC_TYPE = ClientMetricType::CLIENT_METRIC_TYPE_CAP_INFO;
+
+  uint64_t cap_hits = 0;
+  uint64_t cap_misses = 0;
+  uint64_t nr_caps = 0;
+
+  CapInfoPayload() { }
+  CapInfoPayload(uint64_t cap_hits, uint64_t cap_misses, uint64_t nr_caps)
+    : cap_hits(cap_hits), cap_misses(cap_misses), nr_caps(nr_caps) {
+  }
+
+  void encode(bufferlist &bl) const {
+    using ceph::encode;
+    ENCODE_START(1, 1, bl);
+    encode(cap_hits, bl);
+    encode(cap_misses, bl);
+    encode(nr_caps, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator &iter) {
+    using ceph::decode;
+    DECODE_START(1, iter);
+    decode(cap_hits, iter);
+    decode(cap_misses, iter);
+    decode(nr_caps, iter);
+    DECODE_FINISH(iter);
+  }
+
+  void dump(Formatter *f) const {
+    f->dump_int("cap_hits", cap_hits);
+    f->dump_int("cap_misses", cap_misses);
+    f->dump_int("num_caps", nr_caps);
+  }
+};
+
+struct ReadLatencyPayload {
+  static const ClientMetricType METRIC_TYPE = ClientMetricType::CLIENT_METRIC_TYPE_READ_LATENCY;
+
+  utime_t lat;
+
+  ReadLatencyPayload() { }
+  ReadLatencyPayload(utime_t lat)
+    : lat(lat) {
+  }
+
+  void encode(bufferlist &bl) const {
+    using ceph::encode;
+    ENCODE_START(1, 1, bl);
+    encode(lat, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator &iter) {
+    using ceph::decode;
+    DECODE_START(1, iter);
+    decode(lat, iter);
+    DECODE_FINISH(iter);
+  }
+
+  void dump(Formatter *f) const {
+    f->dump_int("latency", lat);
+  }
+};
+
+struct WriteLatencyPayload {
+  static const ClientMetricType METRIC_TYPE = ClientMetricType::CLIENT_METRIC_TYPE_WRITE_LATENCY;
+
+  utime_t lat;
+
+  WriteLatencyPayload() { }
+  WriteLatencyPayload(utime_t lat)
+    : lat(lat) {
+  }
+
+  void encode(bufferlist &bl) const {
+    using ceph::encode;
+    ENCODE_START(1, 1, bl);
+    encode(lat, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator &iter) {
+    using ceph::decode;
+    DECODE_START(1, iter);
+    decode(lat, iter);
+    DECODE_FINISH(iter);
+  }
+
+  void dump(Formatter *f) const {
+    f->dump_int("latency", lat);
+  }
+};
+
+struct MetadataLatencyPayload {
+  static const ClientMetricType METRIC_TYPE = ClientMetricType::CLIENT_METRIC_TYPE_METADATA_LATENCY;
+
+  utime_t lat;
+
+  MetadataLatencyPayload() { }
+  MetadataLatencyPayload(utime_t lat)
+    : lat(lat) {
+  }
+
+  void encode(bufferlist &bl) const {
+    using ceph::encode;
+    ENCODE_START(1, 1, bl);
+    encode(lat, bl);
+    ENCODE_FINISH(bl);
+  }
+
+  void decode(bufferlist::const_iterator &iter) {
+    using ceph::decode;
+    DECODE_START(1, iter);
+    decode(lat, iter);
+    DECODE_FINISH(iter);
+  }
+
+  void dump(Formatter *f) const {
+    f->dump_int("latency", lat);
+  }
+};
+
+struct UnknownPayload {
+  static const ClientMetricType METRIC_TYPE = static_cast<ClientMetricType>(-1);
+
+  UnknownPayload() { }
+
+  void encode(bufferlist &bl) const {
+  }
+
+  void decode(bufferlist::const_iterator &iter) {
+  }
+
+  void dump(Formatter *f) const {
+  }
+};
+
+typedef boost::variant<CapInfoPayload,
+                       ReadLatencyPayload,
+                       WriteLatencyPayload,
+                       MetadataLatencyPayload,
+                       UnknownPayload> ClientMetricPayload;
+
+// metric update message sent by clients
+struct ClientMetricMessage {
+public:
+  ClientMetricMessage(const ClientMetricPayload &payload = UnknownPayload())
+    : payload(payload) {
+  }
+
+  class EncodePayloadVisitor : public boost::static_visitor<void> {
+  public:
+    explicit EncodePayloadVisitor(bufferlist &bl) : m_bl(bl) {
+    }
+
+    template <typename ClientMetricPayload>
+    inline void operator()(const ClientMetricPayload &payload) const {
+      using ceph::encode;
+      encode(static_cast<uint32_t>(ClientMetricPayload::METRIC_TYPE), m_bl);
+      payload.encode(m_bl);
+    }
+
+  private:
+    bufferlist &m_bl;
+  };
+
+  class DecodePayloadVisitor : public boost::static_visitor<void> {
+  public:
+    DecodePayloadVisitor(bufferlist::const_iterator &iter) : m_iter(iter) {
+    }
+
+    template <typename ClientMetricPayload>
+    inline void operator()(ClientMetricPayload &payload) const {
+      using ceph::decode;
+      payload.decode(m_iter);
+    }
+
+  private:
+    bufferlist::const_iterator &m_iter;
+  };
+
+  class DumpPayloadVisitor : public boost::static_visitor<void> {
+  public:
+    explicit DumpPayloadVisitor(Formatter *formatter) : m_formatter(formatter) {
+    }
+
+    template <typename ClientMetricPayload>
+    inline void operator()(const ClientMetricPayload &payload) const {
+      ClientMetricType metric_type = ClientMetricPayload::METRIC_TYPE;
+      m_formatter->dump_string("client_metric_type", stringify(metric_type));
+      payload.dump(m_formatter);
+    }
+
+  private:
+    Formatter *m_formatter;
+  };
+
+  void encode(bufferlist &bl) const {
+    boost::apply_visitor(EncodePayloadVisitor(bl), payload);
+  }
+
+  void decode(bufferlist::const_iterator &iter) {
+    using ceph::decode;
+
+    uint32_t metric_type;
+    decode(metric_type, iter);
+
+    switch (metric_type) {
+    case ClientMetricType::CLIENT_METRIC_TYPE_CAP_INFO:
+      payload = CapInfoPayload();
+      break;
+    case ClientMetricType::CLIENT_METRIC_TYPE_READ_LATENCY:
+      payload = ReadLatencyPayload();
+      break;
+    case ClientMetricType::CLIENT_METRIC_TYPE_WRITE_LATENCY:
+      payload = WriteLatencyPayload();
+      break;
+    case ClientMetricType::CLIENT_METRIC_TYPE_METADATA_LATENCY:
+      payload = MetadataLatencyPayload();
+      break;
+    default:
+      payload = UnknownPayload();
+      break;
+    }
+
+    boost::apply_visitor(DecodePayloadVisitor(iter), payload);
+  }
+
+  void dump(Formatter *f) const {
+    apply_visitor(DumpPayloadVisitor(f), payload);
+  }
+
+  ClientMetricPayload payload;
+};
+WRITE_CLASS_ENCODER(ClientMetricMessage);
+
+#endif // CEPH_INCLUDE_CEPHFS_METRICS_TYPES_H
diff --git a/src/messages/MClientMetrics.h b/src/messages/MClientMetrics.h
new file mode 100644 (file)
index 0000000..c348586
--- /dev/null
@@ -0,0 +1,51 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_MDS_CLIENT_METRICS_H
+#define CEPH_MDS_CLIENT_METRICS_H
+
+#include <vector>
+
+#include "msg/Message.h"
+#include "include/cephfs/metrics/Types.h"
+
+class MClientMetrics : public SafeMessage {
+private:
+  static constexpr int HEAD_VERSION = 1;
+  static constexpr int COMPAT_VERSION = 1;
+public:
+  std::vector<ClientMetricMessage> updates;
+
+protected:
+  MClientMetrics() : MClientMetrics(std::vector<ClientMetricMessage>{}) { }
+  MClientMetrics(std::vector<ClientMetricMessage> updates)
+    : SafeMessage(CEPH_MSG_CLIENT_METRICS, HEAD_VERSION, COMPAT_VERSION), updates(updates) {
+  }
+  ~MClientMetrics() { }
+
+public:
+  std::string_view get_type_name() const override {
+    return "client_metrics";
+  }
+
+  void print(ostream &out) const override {
+    out << "client_metrics";
+  }
+
+  void encode_payload(uint64_t features) override {
+    using ceph::encode;
+    encode(updates, payload);
+  }
+
+  void decode_payload() override {
+    using ceph::decode;
+    auto iter = payload.cbegin();
+    decode(updates, iter);
+  }
+
+private:
+  template<class T, typename... Args>
+  friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+};
+
+#endif // CEPH_MDS_CLIENT_METRICS_H
index 27ef95d9db0fe80c7b7af23f25a11f1834f9188d..6ca3cd492affb07eecbe4b22903f50d1eaa27f5d 100644 (file)
 #include "messages/MClientLease.h"
 #include "messages/MClientSnap.h"
 #include "messages/MClientQuota.h"
+#include "messages/MClientMetrics.h"
 
 #include "messages/MMDSSlaveRequest.h"
 
@@ -682,6 +683,9 @@ Message *decode_message(CephContext *cct,
   case CEPH_MSG_CLIENT_QUOTA:
     m = make_message<MClientQuota>();
     break;
+  case CEPH_MSG_CLIENT_METRICS:
+    m = make_message<MClientMetrics>();
+    break;
 
     // mds
   case MSG_MDS_SLAVE_REQUEST: