From: Venky Shankar Date: Tue, 10 Sep 2019 13:50:37 +0000 (-0400) Subject: mgr: introduce query/report types for ceph metadata server X-Git-Tag: wip-pdonnell-testing-20200918.022351~1113^2~5 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=f5f1d1e7e2b62157bb3fb9e77068854760f74403;p=ceph-ci.git mgr: introduce query/report types for ceph metadata server These types will be used for supporting user define querying from ceph-mgr. Signed-off-by: Venky Shankar --- diff --git a/src/mgr/CMakeLists.txt b/src/mgr/CMakeLists.txt index f6f9e73d433..fc6564cef55 100644 --- a/src/mgr/CMakeLists.txt +++ b/src/mgr/CMakeLists.txt @@ -20,6 +20,7 @@ if(WITH_MGR) MetricCollector.cc OSDPerfMetricTypes.cc OSDPerfMetricCollector.cc + MDSPerfMetricTypes.cc PyFormatter.cc PyUtil.cc PyModule.cc diff --git a/src/mgr/MDSPerfMetricTypes.cc b/src/mgr/MDSPerfMetricTypes.cc new file mode 100644 index 00000000000..5af885b4792 --- /dev/null +++ b/src/mgr/MDSPerfMetricTypes.cc @@ -0,0 +1,93 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include +#include "mgr/MDSPerfMetricTypes.h" + +std::ostream& operator<<(std::ostream& os, const MDSPerfMetricSubKeyDescriptor &d) { + switch (d.type) { + case MDSPerfMetricSubKeyType::MDS_RANK: + os << "mds_rank"; + break; + case MDSPerfMetricSubKeyType::CLIENT_ID: + os << "client_id"; + break; + default: + os << "unknown (" << static_cast(d.type) << ")"; + } + + return os << "~/" << d.regex_str << "/"; +} + +void MDSPerformanceCounterDescriptor::pack_counter( + const PerformanceCounter &c, bufferlist *bl) const { + using ceph::encode; + encode(c.first, *bl); + encode(c.second, *bl); + switch(type) { + case MDSPerformanceCounterType::CAP_HIT_METRIC: + case MDSPerformanceCounterType::READ_LATENCY_METRIC: + case MDSPerformanceCounterType::WRITE_LATENCY_METRIC: + case MDSPerformanceCounterType::METADATA_LATENCY_METRIC: + break; + default: + ceph_abort_msg("unknown counter type"); + } +} + +void MDSPerformanceCounterDescriptor::unpack_counter( + bufferlist::const_iterator& bl, PerformanceCounter *c) const { + using ceph::decode; + decode(c->first, bl); + decode(c->second, bl); + switch(type) { + case MDSPerformanceCounterType::CAP_HIT_METRIC: + case MDSPerformanceCounterType::READ_LATENCY_METRIC: + case MDSPerformanceCounterType::WRITE_LATENCY_METRIC: + case MDSPerformanceCounterType::METADATA_LATENCY_METRIC: + break; + default: + ceph_abort_msg("unknown counter type"); + } +} + +std::ostream& operator<<(std::ostream &os, const MDSPerformanceCounterDescriptor &d) { + switch(d.type) { + case MDSPerformanceCounterType::CAP_HIT_METRIC: + os << "cap_hit_metric"; + break; + case MDSPerformanceCounterType::READ_LATENCY_METRIC: + os << "read_latency_metric"; + break; + case MDSPerformanceCounterType::WRITE_LATENCY_METRIC: + os << "write_latency_metric"; + break; + case MDSPerformanceCounterType::METADATA_LATENCY_METRIC: + os << "metadata_latency_metric"; + break; + } + + return os; +} + +std::ostream &operator<<(std::ostream &os, const MDSPerfMetricLimit &limit) { + return os << "[order_by=" << limit.order_by << ", max_count=" << limit.max_count << "]"; +} + +void MDSPerfMetricQuery::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 MDSPerfMetricQuery &query) { + return os << "[key=" << query.key_descriptor << ", counter=" + << query.performance_counter_descriptors << "]"; +} diff --git a/src/mgr/MDSPerfMetricTypes.h b/src/mgr/MDSPerfMetricTypes.h new file mode 100644 index 00000000000..2111439b09b --- /dev/null +++ b/src/mgr/MDSPerfMetricTypes.h @@ -0,0 +1,333 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_MGR_MDS_PERF_METRIC_TYPES_H +#define CEPH_MGR_MDS_PERF_METRIC_TYPES_H + +#include +#include +#include + +#include "include/denc.h" +#include "include/stringify.h" + +#include "mds/mdstypes.h" +#include "mgr/Types.h" + +typedef std::vector MDSPerfMetricSubKey; // array of regex match +typedef std::vector MDSPerfMetricKey; + +enum class MDSPerfMetricSubKeyType : uint8_t { + MDS_RANK = 0, + CLIENT_ID = 1, +}; + +struct MDSPerfMetricSubKeyDescriptor { + MDSPerfMetricSubKeyType type = static_cast(-1); + std::string regex_str; + std::regex regex; + + bool is_supported() const { + switch (type) { + case MDSPerfMetricSubKeyType::MDS_RANK: + case MDSPerfMetricSubKeyType::CLIENT_ID: + return true; + default: + return false; + } + } + + MDSPerfMetricSubKeyDescriptor() { + } + MDSPerfMetricSubKeyDescriptor(MDSPerfMetricSubKeyType type, const std::string ®ex_str) + : type(type), regex_str(regex_str) { + } + + bool operator<(const MDSPerfMetricSubKeyDescriptor &other) const { + if (type < other.type) { + return true; + } + if (type > other.type) { + return false; + } + return regex_str < other.regex_str; + } + + DENC(MDSPerfMetricSubKeyDescriptor, v, p) { + DENC_START(1, 1, p); + denc(v.type, p); + denc(v.regex_str, p); + DENC_FINISH(p); + } +}; +WRITE_CLASS_DENC(MDSPerfMetricSubKeyDescriptor) + +std::ostream& operator<<(std::ostream& os, const MDSPerfMetricSubKeyDescriptor &d); +typedef std::vector MDSPerfMetricKeyDescriptor; + +template<> +struct denc_traits { + static constexpr bool supported = true; + static constexpr bool bounded = false; + static constexpr bool featured = false; + static constexpr bool need_contiguous = true; + static void bound_encode(const MDSPerfMetricKeyDescriptor& v, size_t& p) { + p += sizeof(uint32_t); + const auto size = v.size(); + if (size) { + size_t per = 0; + denc(v.front(), per); + p += per * size; + } + } + static void encode(const MDSPerfMetricKeyDescriptor& v, + ceph::buffer::list::contiguous_appender& p) { + denc_varint(v.size(), p); + for (auto& i : v) { + denc(i, p); + } + } + static void decode(MDSPerfMetricKeyDescriptor& v, + ceph::buffer::ptr::const_iterator& p) { + unsigned num; + denc_varint(num, p); + v.clear(); + v.reserve(num); + for (unsigned i=0; i < num; ++i) { + MDSPerfMetricSubKeyDescriptor d; + denc(d, p); + if (!d.is_supported()) { + v.clear(); + return; + } + try { + d.regex = d.regex_str.c_str(); + } catch (const std::regex_error& e) { + v.clear(); + return; + } + if (d.regex.mark_count() == 0) { + v.clear(); + return; + } + v.push_back(std::move(d)); + } + } +}; + +enum class MDSPerformanceCounterType : uint8_t { + CAP_HIT_METRIC = 0, + READ_LATENCY_METRIC = 1, + WRITE_LATENCY_METRIC = 2, + METADATA_LATENCY_METRIC = 3, +}; + +struct MDSPerformanceCounterDescriptor { + MDSPerformanceCounterType type = static_cast(-1); + + bool is_supported() const { + switch(type) { + case MDSPerformanceCounterType::CAP_HIT_METRIC: + case MDSPerformanceCounterType::READ_LATENCY_METRIC: + case MDSPerformanceCounterType::WRITE_LATENCY_METRIC: + case MDSPerformanceCounterType::METADATA_LATENCY_METRIC: + return true; + default: + return false; + } + } + + MDSPerformanceCounterDescriptor() { + } + MDSPerformanceCounterDescriptor(MDSPerformanceCounterType type) : type(type) { + } + + bool operator<(const MDSPerformanceCounterDescriptor &other) const { + return type < other.type; + } + + bool operator==(const MDSPerformanceCounterDescriptor &other) const { + return type == other.type; + } + + bool operator!=(const MDSPerformanceCounterDescriptor &other) const { + return type != other.type; + } + + DENC(MDSPerformanceCounterDescriptor, v, p) { + DENC_START(1, 1, p); + denc(v.type, p); + DENC_FINISH(p); + } + + void pack_counter(const PerformanceCounter &c, ceph::buffer::list *bl) const; + void unpack_counter(ceph::buffer::list::const_iterator& bl, PerformanceCounter *c) const; +}; +WRITE_CLASS_DENC(MDSPerformanceCounterDescriptor) + +std::ostream& operator<<(std::ostream &os, const MDSPerformanceCounterDescriptor &d); +typedef std::vector MDSPerformanceCounterDescriptors; + +template<> +struct denc_traits { + static constexpr bool supported = true; + static constexpr bool bounded = false; + static constexpr bool featured = false; + static constexpr bool need_contiguous = true; + static void bound_encode(const MDSPerformanceCounterDescriptors& v, size_t& p) { + p += sizeof(uint32_t); + const auto size = v.size(); + if (size) { + size_t per = 0; + denc(v.front(), per); + p += per * size; + } + } + static void encode(const MDSPerformanceCounterDescriptors& v, + ceph::buffer::list::contiguous_appender& p) { + denc_varint(v.size(), p); + for (auto& i : v) { + denc(i, p); + } + } + static void decode(MDSPerformanceCounterDescriptors& v, + ceph::buffer::ptr::const_iterator& p) { + unsigned num; + denc_varint(num, p); + v.clear(); + v.reserve(num); + for (unsigned i=0; i < num; ++i) { + MDSPerformanceCounterDescriptor d; + denc(d, p); + if (d.is_supported()) { + v.push_back(std::move(d)); + } + } + } +}; + +struct MDSPerfMetricLimit { + MDSPerformanceCounterDescriptor order_by; + uint64_t max_count; + + MDSPerfMetricLimit() { + } + MDSPerfMetricLimit(const MDSPerformanceCounterDescriptor &order_by, uint64_t max_count) + : order_by(order_by), max_count(max_count) { + } + + bool operator<(const MDSPerfMetricLimit &other) const { + if (order_by != other.order_by) { + return order_by < other.order_by; + } + + return max_count < other.max_count; + } + + DENC(MDSPerfMetricLimit, v, p) { + DENC_START(1, 1, p); + denc(v.order_by, p); + denc(v.max_count, p); + DENC_FINISH(p); + } +}; +WRITE_CLASS_DENC(MDSPerfMetricLimit) + +std::ostream &operator<<(std::ostream &os, const MDSPerfMetricLimit &limit); +typedef std::set MDSPerfMetricLimits; + +struct MDSPerfMetricQuery { + MDSPerfMetricKeyDescriptor key_descriptor; + MDSPerformanceCounterDescriptors performance_counter_descriptors; + + MDSPerfMetricQuery() { + } + MDSPerfMetricQuery(const MDSPerfMetricKeyDescriptor &key_descriptor, + const MDSPerformanceCounterDescriptors &performance_counter_descriptors) + : key_descriptor(key_descriptor), + performance_counter_descriptors(performance_counter_descriptors) + { + } + + bool operator<(const MDSPerfMetricQuery &other) const { + if (key_descriptor < other.key_descriptor) { + return true; + } + if (key_descriptor > other.key_descriptor) { + return false; + } + return performance_counter_descriptors < other.performance_counter_descriptors; + } + + template + bool get_key(L&& get_sub_key, MDSPerfMetricKey *key) const { + for (auto &sub_key_descriptor : key_descriptor) { + MDSPerfMetricSubKey sub_key; + if (!get_sub_key(sub_key_descriptor, &sub_key)) { + return false; + } + key->push_back(sub_key); + } + return true; + } + + void get_performance_counter_descriptors(MDSPerformanceCounterDescriptors *descriptors) const { + *descriptors = performance_counter_descriptors; + } + + template + void update_counters(L &&update_counter, 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()); + } + update_counter(descriptor, &(*it)); + it++; + } + } + + DENC(MDSPerfMetricQuery, v, p) { + DENC_START(1, 1, p); + denc(v.key_descriptor, p); + denc(v.performance_counter_descriptors, p); + DENC_FINISH(p); + } + + void pack_counters(const PerformanceCounters &counters, ceph::buffer::list *bl) const; +}; +WRITE_CLASS_DENC(MDSPerfMetricQuery) + +std::ostream &operator<<(std::ostream &os, const MDSPerfMetricQuery &query); + +struct MDSPerfMetrics { + MDSPerformanceCounterDescriptors performance_counter_descriptors; + std::map group_packed_performance_counters; + + DENC(MDSPerfMetrics, v, p) { + DENC_START(1, 1, p); + denc(v.performance_counter_descriptors, p); + denc(v.group_packed_performance_counters, p); + DENC_FINISH(p); + } +}; + +struct MDSPerfMetricReport { + std::map reports; + // set of active ranks that have delayed (stale) metrics + std::set rank_metrics_delayed; + + DENC(MDSPerfMetricReport, v, p) { + DENC_START(1, 1, p); + denc(v.reports, p); + denc(v.rank_metrics_delayed, p); + DENC_FINISH(p); + } +}; + +WRITE_CLASS_DENC(MDSPerfMetrics) +WRITE_CLASS_DENC(MDSPerfMetricReport) + +#endif // CEPH_MGR_MDS_PERF_METRIC_TYPES_H