]> git.proxmox.com Git - ceph.git/blob - ceph/src/mon/health_check.h
update sources to v12.1.1
[ceph.git] / ceph / src / mon / health_check.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #pragma once
5
6 #include <string>
7 #include <map>
8
9 #include "include/health.h"
10 #include "common/Formatter.h"
11
12 struct health_check_t {
13 health_status_t severity;
14 std::string summary;
15 std::list<std::string> detail;
16
17 DENC(health_check_t, v, p) {
18 DENC_START(1, 1, p);
19 denc(v.severity, p);
20 denc(v.summary, p);
21 denc(v.detail, p);
22 DENC_FINISH(p);
23 }
24
25 friend bool operator==(const health_check_t& l,
26 const health_check_t& r) {
27 return l.severity == r.severity &&
28 l.summary == r.summary &&
29 l.detail == r.detail;
30 }
31 friend bool operator!=(const health_check_t& l,
32 const health_check_t& r) {
33 return !(l == r);
34 }
35
36 void dump(Formatter *f) const {
37 f->dump_stream("severity") << severity;
38 f->dump_string("summary", summary);
39 f->open_array_section("detail");
40 for (auto& p : detail) {
41 f->dump_string("item", p);
42 }
43 f->close_section();
44 }
45
46 static void generate_test_instances(list<health_check_t*>& ls) {
47 ls.push_back(new health_check_t);
48 ls.push_back(new health_check_t);
49 ls.back()->severity = HEALTH_ERR;
50 ls.back()->summary = "summarization";
51 ls.back()->detail = {"one", "two", "three"};
52 }
53 };
54 WRITE_CLASS_DENC(health_check_t)
55
56
57 struct health_check_map_t {
58 map<std::string,health_check_t> checks;
59
60 DENC(health_check_map_t, v, p) {
61 DENC_START(1, 1, p);
62 denc(v.checks, p);
63 DENC_FINISH(p);
64 }
65
66 void dump(Formatter *f) const {
67 for (auto& p : checks) {
68 f->dump_object(p.first.c_str(), p.second);
69 }
70 }
71
72 static void generate_test_instances(list<health_check_map_t*>& ls) {
73 ls.push_back(new health_check_map_t);
74 ls.push_back(new health_check_map_t);
75 {
76 auto& d = ls.back()->add("FOO", HEALTH_WARN, "foo");
77 d.detail.push_back("a");
78 d.detail.push_back("b");
79 }
80 {
81 auto& d = ls.back()->add("BAR", HEALTH_ERR, "bar!");
82 d.detail.push_back("c");
83 d.detail.push_back("d");
84 }
85 }
86
87 void clear() {
88 checks.clear();
89 }
90 void swap(health_check_map_t& other) {
91 checks.swap(other.checks);
92 }
93
94 health_check_t& add(const std::string& code,
95 health_status_t severity,
96 const std::string& summary) {
97 assert(checks.count(code) == 0);
98 health_check_t& r = checks[code];
99 r.severity = severity;
100 r.summary = summary;
101 return r;
102 }
103 health_check_t& get_or_add(const std::string& code,
104 health_status_t severity,
105 const std::string& summary) {
106 health_check_t& r = checks[code];
107 r.severity = severity;
108 r.summary = summary;
109 return r;
110 }
111
112 void merge(const health_check_map_t& o) {
113 for (auto& p : o.checks) {
114 auto q = checks.find(p.first);
115 if (q == checks.end()) {
116 // new check
117 checks[p.first] = p.second;
118 } else {
119 // merge details, and hope the summary matches!
120 q->second.detail.insert(
121 q->second.detail.end(),
122 p.second.detail.begin(),
123 p.second.detail.end());
124 }
125 }
126 }
127
128 health_status_t dump_summary(Formatter *f, std::string *plain,
129 const char *sep, bool detail) const {
130 health_status_t r = HEALTH_OK;
131 for (auto& p : checks) {
132 if (r > p.second.severity) {
133 r = p.second.severity;
134 }
135 if (f) {
136 f->open_object_section(p.first.c_str());
137 f->dump_stream("severity") << p.second.severity;
138 f->dump_string("message", p.second.summary);
139 if (detail) {
140 f->open_array_section("detail");
141 for (auto& d : p.second.detail) {
142 f->dump_string("item", d);
143 }
144 f->close_section();
145 }
146 f->close_section();
147 } else {
148 if (!plain->empty()) {
149 *plain += sep;
150 }
151 *plain += p.second.summary;
152 }
153 }
154 return r;
155 }
156
157 void dump_summary_compat(Formatter *f) const {
158 for (auto& p : checks) {
159 f->open_object_section("item");
160 f->dump_stream("severity") << p.second.severity;
161 f->dump_string("summary", p.second.summary);
162 f->close_section();
163 }
164 }
165
166 void dump_detail(Formatter *f, std::string *plain, bool compat) const {
167 for (auto& p : checks) {
168 if (f) {
169 if (compat) {
170 // this is sloppy, but the best we can do: just dump all of the
171 // individual checks' details together
172 for (auto& d : p.second.detail) {
173 f->dump_string("item", d);
174 }
175 }
176 } else {
177 if (!compat) {
178 *plain += p.first + " " + p.second.summary + "\n";
179 }
180 for (auto& d : p.second.detail) {
181 if (!compat) {
182 *plain += " ";
183 }
184 *plain += d;
185 *plain += "\n";
186 }
187 }
188 }
189 }
190
191 friend bool operator==(const health_check_map_t& l,
192 const health_check_map_t& r) {
193 return l.checks == r.checks;
194 }
195 friend bool operator!=(const health_check_map_t& l,
196 const health_check_map_t& r) {
197 return !(l == r);
198 }
199 };
200 WRITE_CLASS_DENC(health_check_map_t)