}
});
+ mgrc->set_perf_metric_query_cb(
+ [this](const ConfigPayload &config_payload) {
+ set_perf_queries(config_payload);
+ },
+ [this]() {
+ return get_perf_reports();
+ });
+
return 0;
}
dout(10) << ": active set=[" << active_rank_addrs << "]" << dendl;
}
+
+void MetricAggregator::set_perf_queries(const ConfigPayload &config_payload) {
+ const MDSConfigPayload &mds_config_payload = boost::get<MDSConfigPayload>(config_payload);
+ const std::map<MDSPerfMetricQuery, MDSPerfMetricLimits> &queries = mds_config_payload.config;
+
+ dout(10) << ": setting " << queries.size() << " queries" << dendl;
+
+ std::scoped_lock locker(lock);
+ std::map<MDSPerfMetricQuery, std::map<MDSPerfMetricKey, PerformanceCounters>> new_data;
+ for (auto &p : queries) {
+ std::swap(new_data[p.first], query_metrics_map[p.first]);
+ }
+ std::swap(query_metrics_map, new_data);
+}
+
+MetricPayload MetricAggregator::get_perf_reports() {
+ MDSMetricPayload payload;
+ MDSPerfMetricReport &metric_report = payload.metric_report;
+ std::map<MDSPerfMetricQuery, MDSPerfMetrics> &reports = metric_report.reports;
+
+ std::scoped_lock locker(lock);
+
+ for (auto& [query, counters] : query_metrics_map) {
+ auto &report = reports[query];
+
+ query.get_performance_counter_descriptors(&report.performance_counter_descriptors);
+
+ auto &descriptors = report.performance_counter_descriptors;
+ ceph_assert(descriptors.size() > 0);
+
+ dout(20) << ": descriptors=" << descriptors << dendl;
+
+ for (auto &p : counters) {
+ dout(20) << ": packing perf_metric_key=" << p.first << ", perf_counter="
+ << p.second << dendl;
+ auto &bl = report.group_packed_performance_counters[p.first];
+ query.pack_counters(p.second, &bl);
+ }
+ }
+
+ // stash a copy of dealyed and failed ranks. mgr culls out metrics
+ // for failed ranks and tags metrics for delayed ranks as "stale".
+ for (auto &p : active_rank_addrs) {
+ auto rank = p.first;
+ if (mds_pinger.is_rank_lagging(rank)) {
+ metric_report.rank_metrics_delayed.insert(rank);
+ }
+ }
+
+ return payload;
+}
#include "common/ceph_mutex.h"
#include "messages/MMDSMetrics.h"
+#include "mgr/MetricTypes.h"
#include "mgr/MDSPerfMetricTypes.h"
#include "mdstypes.h"
void cull_metrics_for_rank(mds_rank_t rank);
void ping_all_active_ranks();
+
+ void set_perf_queries(const ConfigPayload &config_payload);
+ MetricPayload get_perf_reports();
};
#endif // CEPH_MDS_METRIC_AGGREGATOR_H
OSDPerfMetricTypes.cc
OSDPerfMetricCollector.cc
MDSPerfMetricTypes.cc
+ MDSPerfMetricCollector.cc
PyFormatter.cc
PyUtil.cc
PyModule.cc
#include "mgr/mgr_commands.h"
#include "mgr/DaemonHealthMetricCollector.h"
#include "mgr/OSDPerfMetricCollector.h"
+#include "mgr/MDSPerfMetricCollector.h"
#include "mon/MonCommand.h"
#include "messages/MMgrOpen.h"
shutting_down(false),
tick_event(nullptr),
osd_perf_metric_collector_listener(this),
- osd_perf_metric_collector(osd_perf_metric_collector_listener)
+ osd_perf_metric_collector(osd_perf_metric_collector_listener),
+ mds_perf_metric_collector_listener(this),
+ mds_perf_metric_collector(mds_perf_metric_collector_listener)
{
g_conf().add_observer(this);
}
}));
}
+void DaemonServer::handle_mds_perf_metric_query_updated()
+{
+ dout(10) << dendl;
+
+ // Send a fresh MMgrConfigure to all clients, so that they can follow
+ // the new policy for transmitting stats
+ finisher.queue(new LambdaContext([this](int r) {
+ std::lock_guard l(lock);
+ for (auto &c : daemon_connections) {
+ if (c->peer_is_mds()) {
+ _send_configure(c);
+ }
+ }
+ }));
+}
+
void DaemonServer::shutdown()
{
dout(10) << "begin" << dendl;
if (c->peer_is_osd()) {
configure->osd_perf_metric_queries =
osd_perf_metric_collector.get_queries();
+ } else if (c->peer_is_mds()) {
+ configure->metric_config_message =
+ MetricConfigMessage(MDSConfigPayload(mds_perf_metric_collector.get_queries()));
}
c->send_message2(configure);
#include "DaemonState.h"
#include "MetricCollector.h"
#include "OSDPerfMetricCollector.h"
+#include "MDSPerfMetricCollector.h"
class MMgrReport;
class MMgrOpen;
struct MonCommand;
class CommandContext;
struct OSDPerfMetricQuery;
-
+struct MDSPerfMetricQuery;
/**
* Server used in ceph-mgr to communicate with Ceph daemons like
OSDPerfMetricCollector osd_perf_metric_collector;
void handle_osd_perf_metric_query_updated();
+ class MDSPerfMetricCollectorListener : public MetricListener {
+ public:
+ MDSPerfMetricCollectorListener(DaemonServer *server)
+ : server(server) {
+ }
+ void handle_query_updated() override {
+ server->handle_mds_perf_metric_query_updated();
+ }
+ private:
+ DaemonServer *server;
+ };
+ MDSPerfMetricCollectorListener mds_perf_metric_collector_listener;
+ MDSPerfMetricCollector mds_perf_metric_collector;
+ void handle_mds_perf_metric_query_updated();
+
void handle_metric_payload(const OSDMetricPayload &payload) {
osd_perf_metric_collector.process_reports(payload);
}
+ void handle_metric_payload(const MDSMetricPayload &payload) {
+ mds_perf_metric_collector.process_reports(payload);
+ }
+
void handle_metric_payload(const UnknownMetricPayload &payload) {
ceph_abort();
}
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "common/debug.h"
+#include "common/errno.h"
+
+#include "messages/MMgrReport.h"
+#include "mgr/MDSPerfMetricTypes.h"
+#include "mgr/MDSPerfMetricCollector.h"
+
+#define dout_context g_ceph_context
+#define dout_subsys ceph_subsys_mgr
+#undef dout_prefix
+#define dout_prefix *_dout << "mgr.mds_perf_metric_collector " << __func__ << " "
+
+MDSPerfMetricCollector::MDSPerfMetricCollector(MetricListener &listener)
+ : MetricCollector<MDSPerfMetricQuery,
+ MDSPerfMetricLimit,
+ MDSPerfMetricKey,
+ MDSPerfMetrics>(listener) {
+}
+
+void MDSPerfMetricCollector::process_reports(const MetricPayload &payload) {
+ const MDSPerfMetricReport &metric_report = boost::get<MDSMetricPayload>(payload).metric_report;
+
+ std::lock_guard locker(lock);
+ process_reports_generic(
+ metric_report.reports, [](PerformanceCounter *counter, const PerformanceCounter &update) {
+ counter->first = update.first;
+ counter->second = update.second;
+ });
+
+ // update delayed rank set
+ delayed_ranks = metric_report.rank_metrics_delayed;
+ dout(20) << ": delayed ranks=[" << delayed_ranks << "]" << dendl;
+}
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_MGR_MDS_PERF_COLLECTOR_H
+#define CEPH_MGR_MDS_PERF_COLLECTOR_H
+
+#include "mgr/MetricCollector.h"
+#include "mgr/MDSPerfMetricTypes.h"
+
+// MDS performance query class
+class MDSPerfMetricCollector
+ : public MetricCollector<MDSPerfMetricQuery, MDSPerfMetricLimit, MDSPerfMetricKey,
+ MDSPerfMetrics> {
+private:
+ std::set<mds_rank_t> delayed_ranks;
+public:
+ MDSPerfMetricCollector(MetricListener &listener);
+
+ void process_reports(const MetricPayload &payload) override;
+};
+
+#endif // CEPH_MGR_MDS_PERF_COLLECTOR_H
#include "mgr/MetricCollector.h"
#include "mgr/OSDPerfMetricTypes.h"
+#include "mgr/MDSPerfMetricTypes.h"
#define dout_context g_ceph_context
#define dout_subsys ceph_subsys_mgr
template class
MetricCollector<OSDPerfMetricQuery, OSDPerfMetricLimit, OSDPerfMetricKey, OSDPerfMetricReport>;
+template class
+MetricCollector<MDSPerfMetricQuery, MDSPerfMetricLimit, MDSPerfMetricKey, MDSPerfMetrics>;
#include <boost/variant.hpp>
#include "include/denc.h"
#include "mgr/OSDPerfMetricTypes.h"
+#include "mgr/MDSPerfMetricTypes.h"
enum class MetricReportType {
METRIC_REPORT_TYPE_OSD = 0,
+ METRIC_REPORT_TYPE_MDS = 1,
};
struct OSDMetricPayload {
}
};
+struct MDSMetricPayload {
+ static const MetricReportType METRIC_REPORT_TYPE = MetricReportType::METRIC_REPORT_TYPE_MDS;
+ MDSPerfMetricReport metric_report;
+
+ MDSMetricPayload() {
+ }
+ MDSMetricPayload(const MDSPerfMetricReport &metric_report)
+ : metric_report(metric_report) {
+ }
+
+ DENC(MDSMetricPayload, v, p) {
+ DENC_START(1, 1, p);
+ denc(v.metric_report, p);
+ DENC_FINISH(p);
+ }
+};
+
struct UnknownMetricPayload {
static const MetricReportType METRIC_REPORT_TYPE = static_cast<MetricReportType>(-1);
};
WRITE_CLASS_DENC(OSDMetricPayload)
+WRITE_CLASS_DENC(MDSMetricPayload)
WRITE_CLASS_DENC(UnknownMetricPayload)
typedef boost::variant<OSDMetricPayload,
+ MDSMetricPayload,
UnknownMetricPayload> MetricPayload;
class EncodeMetricPayloadVisitor : public boost::static_visitor<void> {
case MetricReportType::METRIC_REPORT_TYPE_OSD:
payload = OSDMetricPayload();
break;
+ case MetricReportType::METRIC_REPORT_TYPE_MDS:
+ payload = MDSMetricPayload();
+ break;
default:
payload = UnknownMetricPayload();
break;
enum MetricConfigType {
METRIC_CONFIG_TYPE_OSD = 0,
+ METRIC_CONFIG_TYPE_MDS = 1,
};
struct OSDConfigPayload {
}
};
+struct MDSConfigPayload {
+ static const MetricConfigType METRIC_CONFIG_TYPE = MetricConfigType::METRIC_CONFIG_TYPE_MDS;
+ std::map<MDSPerfMetricQuery, MDSPerfMetricLimits> config;
+
+ MDSConfigPayload() {
+ }
+ MDSConfigPayload(const std::map<MDSPerfMetricQuery, MDSPerfMetricLimits> &config)
+ : config(config) {
+ }
+
+ DENC(MDSConfigPayload, v, p) {
+ DENC_START(1, 1, p);
+ denc(v.config, p);
+ DENC_FINISH(p);
+ }
+};
+
struct UnknownConfigPayload {
static const MetricConfigType METRIC_CONFIG_TYPE = static_cast<MetricConfigType>(-1);
};
WRITE_CLASS_DENC(OSDConfigPayload)
+WRITE_CLASS_DENC(MDSConfigPayload)
WRITE_CLASS_DENC(UnknownConfigPayload)
typedef boost::variant<OSDConfigPayload,
+ MDSConfigPayload,
UnknownConfigPayload> ConfigPayload;
class EncodeConfigPayloadVisitor : public boost::static_visitor<void> {
case MetricConfigType::METRIC_CONFIG_TYPE_OSD:
payload = OSDConfigPayload();
break;
+ case MetricConfigType::METRIC_CONFIG_TYPE_MDS:
+ payload = MDSConfigPayload();
+ break;
default:
payload = UnknownConfigPayload();
break;
+
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
}
}
+ void handle_config_payload(const MDSConfigPayload &payload) {
+ if (set_perf_queries_cb) {
+ set_perf_queries_cb(payload);
+ }
+ }
+
void handle_config_payload(const UnknownConfigPayload &payload) {
ceph_abort();
}