]> git.proxmox.com Git - ceph.git/blame - ceph/src/mgr/DaemonHealthMetricCollector.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / mgr / DaemonHealthMetricCollector.cc
CommitLineData
11fdf7f2
TL
1#include <boost/format.hpp>
2
3#include "include/health.h"
4#include "include/types.h"
5#include "DaemonHealthMetricCollector.h"
6
11fdf7f2
TL
7namespace {
8
9class SlowOps final : public DaemonHealthMetricCollector {
10 bool _is_relevant(daemon_metric type) const override {
11 return type == daemon_metric::SLOW_OPS;
12 }
13 health_check_t& _get_check(health_check_map_t& cm) const override {
9f95a23c 14 return cm.get_or_add("SLOW_OPS", HEALTH_WARN, "", 1);
11fdf7f2
TL
15 }
16 bool _update(const DaemonKey& daemon,
17 const DaemonHealthMetric& metric) override {
18 auto num_slow = metric.get_n1();
19 auto blocked_time = metric.get_n2();
20 value.n1 += num_slow;
21 value.n2 = std::max(value.n2, blocked_time);
22 if (num_slow || blocked_time) {
23 daemons.push_back(daemon);
24 return true;
25 } else {
26 return false;
27 }
28 }
29 void _summarize(health_check_t& check) const override {
30 if (daemons.empty()) {
31 return;
32 }
33 static const char* fmt = "%1% slow ops, oldest one blocked for %2% sec, %3%";
34 ostringstream ss;
35 if (daemons.size() > 1) {
36 if (daemons.size() > 10) {
37 ss << "daemons " << vector<DaemonKey>(daemons.begin(), daemons.begin()+10)
38 << "..." << " have slow ops.";
39 } else {
40 ss << "daemons " << daemons << " have slow ops.";
41 }
42 } else {
43 ss << daemons.front() << " has slow ops";
44 }
45 check.summary = boost::str(boost::format(fmt) % value.n1 % value.n2 % ss.str());
46 // No detail
47 }
48 vector<DaemonKey> daemons;
49};
50
51
52class PendingPGs final : public DaemonHealthMetricCollector {
53 bool _is_relevant(daemon_metric type) const override {
54 return type == daemon_metric::PENDING_CREATING_PGS;
55 }
56 health_check_t& _get_check(health_check_map_t& cm) const override {
9f95a23c 57 return cm.get_or_add("PENDING_CREATING_PGS", HEALTH_WARN, "", 1);
11fdf7f2
TL
58 }
59 bool _update(const DaemonKey& osd,
60 const DaemonHealthMetric& metric) override {
61 value.n += metric.get_n();
62 if (metric.get_n()) {
63 osds.push_back(osd);
64 return true;
65 } else {
66 return false;
67 }
68 }
69 void _summarize(health_check_t& check) const override {
70 if (osds.empty()) {
71 return;
72 }
73 static const char* fmt = "%1% PGs pending on creation";
74 check.summary = boost::str(boost::format(fmt) % value.n);
75 ostringstream ss;
76 if (osds.size() > 1) {
77 ss << "osds " << osds << " have pending PGs.";
78 } else {
79 ss << osds.front() << " has pending PGs";
80 }
81 check.detail.push_back(ss.str());
82 }
83 vector<DaemonKey> osds;
84};
85
86} // anonymous namespace
87
88unique_ptr<DaemonHealthMetricCollector>
89DaemonHealthMetricCollector::create(daemon_metric m)
90{
91 switch (m) {
92 case daemon_metric::SLOW_OPS:
93 return unique_ptr<DaemonHealthMetricCollector>{new SlowOps};
94 case daemon_metric::PENDING_CREATING_PGS:
95 return unique_ptr<DaemonHealthMetricCollector>{new PendingPGs};
96 default:
97 return unique_ptr<DaemonHealthMetricCollector>{};
98 }
99}