summaryrefslogtreecommitdiffstats
path: root/src/messages/MMgrReport.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/messages/MMgrReport.h')
-rw-r--r--src/messages/MMgrReport.h204
1 files changed, 204 insertions, 0 deletions
diff --git a/src/messages/MMgrReport.h b/src/messages/MMgrReport.h
new file mode 100644
index 000000000..bd3c221a8
--- /dev/null
+++ b/src/messages/MMgrReport.h
@@ -0,0 +1,204 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2016 John Spray <john.spray@redhat.com>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ */
+
+
+#ifndef CEPH_MMGRREPORT_H_
+#define CEPH_MMGRREPORT_H_
+
+#include <boost/optional.hpp>
+
+#include "msg/Message.h"
+#include "mgr/MetricTypes.h"
+#include "mgr/OSDPerfMetricTypes.h"
+
+#include "common/perf_counters.h"
+#include "include/common_fwd.h"
+#include "mgr/DaemonHealthMetric.h"
+
+class PerfCounterType
+{
+public:
+ std::string path;
+ std::string description;
+ std::string nick;
+ enum perfcounter_type_d type;
+
+ // For older clients that did not send priority, pretend everything
+ // is "useful" so that mgr plugins filtering on prio will get some
+ // data (albeit probably more than they wanted)
+ uint8_t priority = PerfCountersBuilder::PRIO_USEFUL;
+ enum unit_t unit;
+
+ void encode(ceph::buffer::list &bl) const
+ {
+ // TODO: decide whether to drop the per-type
+ // encoding here, we could rely on the MgrReport
+ // verisoning instead.
+ ENCODE_START(3, 1, bl);
+ encode(path, bl);
+ encode(description, bl);
+ encode(nick, bl);
+ static_assert(sizeof(type) == 1, "perfcounter_type_d must be one byte");
+ encode((uint8_t)type, bl);
+ encode(priority, bl);
+ encode((uint8_t)unit, bl);
+ ENCODE_FINISH(bl);
+ }
+
+ void decode(ceph::buffer::list::const_iterator &p)
+ {
+ DECODE_START(3, p);
+ decode(path, p);
+ decode(description, p);
+ decode(nick, p);
+ uint8_t raw_type;
+ decode(raw_type, p);
+ type = (enum perfcounter_type_d)raw_type;
+ if (struct_v >= 2) {
+ decode(priority, p);
+ }
+ if (struct_v >= 3) {
+ uint8_t raw_unit;
+ decode(raw_unit, p);
+ unit = (enum unit_t)raw_unit;
+ }
+ DECODE_FINISH(p);
+ }
+};
+WRITE_CLASS_ENCODER(PerfCounterType)
+
+class MMgrReport : public Message {
+private:
+ static constexpr int HEAD_VERSION = 9;
+ static constexpr int COMPAT_VERSION = 1;
+
+public:
+ /**
+ * Client is responsible for remembering whether it has introduced
+ * each perf counter to the server. When first sending a particular
+ * counter, it must inline the counter's schema here.
+ */
+ std::vector<PerfCounterType> declare_types;
+ std::vector<std::string> undeclare_types;
+
+ // For all counters present, sorted by idx, output
+ // as many bytes as are needed to represent them
+
+ // Decode: iterate over the types we know about, sorted by idx,
+ // and use the current type's type to decide how to decode
+ // the next bytes from the ceph::buffer::list.
+ ceph::buffer::list packed;
+
+ std::string daemon_name;
+ std::string service_name; // optional; otherwise infer from entity type
+
+ // for service registration
+ boost::optional<std::map<std::string,std::string>> daemon_status;
+ boost::optional<std::map<std::string,std::string>> task_status;
+
+ std::vector<DaemonHealthMetric> daemon_health_metrics;
+
+ // encode map<string,map<int32_t,string>> of current config
+ ceph::buffer::list config_bl;
+
+ std::map<OSDPerfMetricQuery, OSDPerfMetricReport> osd_perf_metric_reports;
+
+ boost::optional<MetricReportMessage> metric_report_message;
+
+ void decode_payload() override
+ {
+ using ceph::decode;
+ auto p = payload.cbegin();
+ decode(daemon_name, p);
+ decode(declare_types, p);
+ decode(packed, p);
+ if (header.version >= 2)
+ decode(undeclare_types, p);
+ if (header.version >= 3) {
+ decode(service_name, p);
+ decode(daemon_status, p);
+ }
+ if (header.version >= 5) {
+ decode(daemon_health_metrics, p);
+ }
+ if (header.version >= 6) {
+ decode(config_bl, p);
+ }
+ if (header.version >= 7) {
+ decode(osd_perf_metric_reports, p);
+ }
+ if (header.version >= 8) {
+ decode(task_status, p);
+ }
+ if (header.version >= 9) {
+ decode(metric_report_message, p);
+ }
+ }
+
+ void encode_payload(uint64_t features) override {
+ using ceph::encode;
+ encode(daemon_name, payload);
+ encode(declare_types, payload);
+ encode(packed, payload);
+ encode(undeclare_types, payload);
+ encode(service_name, payload);
+ encode(daemon_status, payload);
+ encode(daemon_health_metrics, payload);
+ encode(config_bl, payload);
+ encode(osd_perf_metric_reports, payload);
+ encode(task_status, payload);
+ if (metric_report_message && metric_report_message->should_encode(features)) {
+ encode(metric_report_message, payload);
+ } else {
+ boost::optional<MetricReportMessage> empty;
+ encode(empty, payload);
+ }
+ }
+
+ std::string_view get_type_name() const override { return "mgrreport"; }
+ void print(std::ostream& out) const override {
+ out << get_type_name() << "(";
+ if (service_name.length()) {
+ out << service_name;
+ } else {
+ out << ceph_entity_type_name(get_source().type());
+ }
+ out << "." << daemon_name
+ << " +" << declare_types.size()
+ << "-" << undeclare_types.size()
+ << " packed " << packed.length();
+ if (daemon_status) {
+ out << " status=" << daemon_status->size();
+ }
+ if (!daemon_health_metrics.empty()) {
+ out << " daemon_metrics=" << daemon_health_metrics.size();
+ }
+ if (task_status) {
+ out << " task_status=" << task_status->size();
+ }
+ out << ")";
+ }
+
+private:
+ MMgrReport()
+ : Message{MSG_MGR_REPORT, HEAD_VERSION, COMPAT_VERSION}
+ {}
+ using RefCountedObject::put;
+ using RefCountedObject::get;
+ template<class T, typename... Args>
+ friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
+ template<class T, typename... Args>
+ friend MURef<T> crimson::make_message(Args&&... args);
+};
+
+#endif