]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common: PerfCountersCache using intrusive_lru
authorAli Maredia <amaredia@redhat.com>
Tue, 19 Jul 2022 21:39:02 +0000 (17:39 -0400)
committerAli Maredia <amaredia@redhat.com>
Fri, 28 Oct 2022 12:23:06 +0000 (08:23 -0400)
This cache is meant to hold labeled perf counters

Signed-off-by: Ali Maredia <amaredia@redhat.com>
src/common/perf_counters_cache.h [new file with mode: 0644]
src/test/common/CMakeLists.txt
src/test/common/test_perf_counters_cache.cc [new file with mode: 0644]

diff --git a/src/common/perf_counters_cache.h b/src/common/perf_counters_cache.h
new file mode 100644 (file)
index 0000000..833f583
--- /dev/null
@@ -0,0 +1,121 @@
+#ifndef RGW_PERFCOUNTERS_CACHE_H
+#define RGW_PERFCOUNTERS_CACHE_H
+
+#include "common/intrusive_lru.h"
+#include "common/perf_counters.h"
+#include "common/ceph_context.h"
+
+enum {
+  l_rgw_metrics_first = 15050,
+  l_rgw_metrics_req,
+  l_rgw_metrics_failed_req,
+  l_rgw_metrics_put_b,
+  l_rgw_metrics_get_b,
+  l_rgw_metrics_last,
+};
+
+template <typename LRUItem>
+struct item_to_key {
+  using type = std::string;
+  const type &operator()(const LRUItem &item) {
+    return item.instance_labels;
+  }
+};
+
+struct PerfCountersCacheEntry : public ceph::common::intrusive_lru_base<
+  ceph::common::intrusive_lru_config<
+    std::string, PerfCountersCacheEntry, item_to_key<PerfCountersCacheEntry>>> {
+  std::string instance_labels;
+  PerfCounters *perfcounters_instance = NULL;
+  //CephContext *cct = NULL;
+  //PerfCountersCollection *collection = NULL;
+
+  PerfCountersCacheEntry(std::string key) : instance_labels(key) {}
+
+  ~PerfCountersCacheEntry() {
+    // perf counters instance clean up code
+    if(perfcounters_instance) {
+      // TODO: figure out removal from perfcounters_collection
+      //ceph_assert(perfcounters_instance);
+      //collection->remove(perfcounters_instance);
+      //cct->get_perfcounters_collection()->remove(perfcounters_instance);
+      //delete perfcounters_instance;
+      //perfcounters_instance = NULL;
+    }
+  }
+};
+
+class PerfCountersCache : public PerfCountersCacheEntry::lru_t {
+private:
+  CephContext *cct;
+public:
+  void add(std::string key) {
+    auto [ref, key_existed] = get_or_create(key);
+    if (!key_existed) {
+      // perf counters instance creation code
+      PerfCountersBuilder plb(cct, key, l_rgw_metrics_first, l_rgw_metrics_last);
+      plb.add_u64_counter(l_rgw_metrics_req, "req", "number of reqs");
+      plb.add_u64_counter(l_rgw_metrics_failed_req, "failed_req", "Aborted Requests");
+      plb.add_u64_counter(l_rgw_metrics_put_b, "put_b", "Size of puts");
+      plb.add_u64_counter(l_rgw_metrics_get_b, "get_b", "Size of gets");
+
+      PerfCounters *counters = plb.create_perf_counters();
+      cct->get_perfcounters_collection()->add(counters);
+      ref->perfcounters_instance = counters;
+      //ref->collection = cct->get_perfcounters_collection();
+      //ref->collection->add(counters);
+      //ref->cct = cct;
+    }
+  }
+
+  void inc(std::string label, int indx, uint64_t v) {
+    auto ref = get(label);
+    if(ref) {
+      if(ref->perfcounters_instance) {
+        PerfCounters *counters = ref->perfcounters_instance;
+        counters->inc(indx, v);
+      }
+    }
+  }
+
+  void dec(std::string label, int indx, uint64_t v) {
+    auto ref = get(label);
+    if(ref) {
+      if(ref->perfcounters_instance) {
+        PerfCounters *counters = ref->perfcounters_instance;
+        counters->dec(indx, v);
+      }
+    }
+  }
+
+  void set_counter(std::string label, int indx, uint64_t val) {
+    auto ref = get(label);
+    if(ref) {
+      if(ref->perfcounters_instance) {
+        PerfCounters *counters = ref->perfcounters_instance;
+        counters->set(indx, val);
+      }
+    }
+  }
+
+  uint64_t get_counter(std::string label, int indx) {
+    auto ref = get(label);
+    uint64_t val= 0;
+    if(ref) {
+      if(ref->perfcounters_instance) {
+        PerfCounters *counters = ref->perfcounters_instance;
+        val = counters->get(indx);
+      }
+    }
+    return val;
+  }
+
+  PerfCountersCache(CephContext *_cct, size_t _cache_size) {
+    cct = _cct;
+    set_target_size(_cache_size);
+  }
+
+  ~PerfCountersCache() {}
+};
+
+#endif
index 26d27151273615f9032160389c81e849af6ed72b..4c845ab29a28720370f4784f42ced1fe24249ab9 100644 (file)
@@ -177,6 +177,13 @@ add_executable(unittest_intrusive_lru
 add_ceph_unittest(unittest_intrusive_lru)
 target_link_libraries(unittest_intrusive_lru ceph-common)
 
+# unittest_perf_counters_cache
+add_executable(unittest_perf_counters_cache 
+  test_perf_counters_cache.cc
+  )
+add_ceph_unittest(unittest_perf_counters_cache)
+target_link_libraries(unittest_perf_counters_cache ceph-common)
+
 # unittest_crc32c
 add_executable(unittest_crc32c
   test_crc32c.cc
diff --git a/src/test/common/test_perf_counters_cache.cc b/src/test/common/test_perf_counters_cache.cc
new file mode 100644 (file)
index 0000000..2301770
--- /dev/null
@@ -0,0 +1,48 @@
+#include "common/perf_counters_cache.h"
+#include "common/perf_counters_cache_key.h"
+//#include "rgw_perfcounters_cache_request.h"
+
+int main() {
+  auto cct = new CephContext(CEPH_ENTITY_TYPE_CLIENT);
+
+  size_t target_size = 1;
+  PerfCountersCache cache(cct, target_size);
+
+  std::string key1 = ceph::perf_counters::cache_key("rgw", {{"Bucket","Foo"}, {"User", "Sally"}});
+  cache.add(key1);
+  std::cout << "instance_labels for entry 1: " << key1 << std::endl;
+
+
+  uint64_t ret = cache.get_counter(key1, l_rgw_metrics_put_b);
+  std::cout << "initial l_rgw_put_b is " << ret << std::endl;
+  cache.inc(key1, l_rgw_metrics_put_b, 500);
+  ret = cache.get_counter(key1, l_rgw_metrics_put_b);
+  std::cout << key1 << " l_rgw_metrics_put_b after inc 500 is " << ret << std::endl;
+  cache.set_counter(key1, l_rgw_metrics_put_b, 300);
+  ret = cache.get_counter(key1, l_rgw_metrics_put_b);
+  std::cout << key1 << " l_rgw_metrics_put_b after set 300 is " << ret << std::endl;
+  cache.dec(key1, l_rgw_metrics_put_b, 50);
+  ret = cache.get_counter(key1, l_rgw_metrics_put_b);
+  std::cout << key1 << " l_rgw_metrics_put_b after dec 50 is " << ret << std::endl;
+  std::cout << std::endl;
+
+  std::string key2 = ceph::perf_counters::cache_key("rgw", {{"Bucket","Foo"}, {"User", "Harry"}});
+  cache.add(key2);
+  std::cout << "instance_labels for entry 2: " << key2 << std::endl;
+
+  ret = cache.get_counter(key2, l_rgw_metrics_get_b);
+  std::cout << key2 << " initial l_rgw_metrics_get_b is " << ret << std::endl;
+  cache.set_counter(key2, l_rgw_metrics_get_b, 400);
+  ret = cache.get_counter(key2, l_rgw_metrics_get_b);
+  std::cout << key2 << " l_rgw_metrics_get_b after set 400 is " << ret << std::endl;
+  cache.inc(key2, l_rgw_metrics_get_b, 1000);
+  ret = cache.get_counter(key2, l_rgw_metrics_get_b);
+  std::cout << key2 << " l_rgw_metrics_get_b after inc 1000 is " << ret << std::endl;
+  cache.dec(key2, l_rgw_metrics_get_b, 500);
+  ret = cache.get_counter(key2, l_rgw_metrics_get_b);
+  std::cout << key2 << " l_rgw_metrics_get_b after dec 500 is " << ret << std::endl;
+
+  delete cct;
+
+  return 0;
+}