]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #ifndef CEPH_MGR_MDS_PERF_METRIC_TYPES_H | |
5 | #define CEPH_MGR_MDS_PERF_METRIC_TYPES_H | |
6 | ||
7 | #include <regex> | |
8 | #include <vector> | |
9 | #include <iostream> | |
10 | ||
11 | #include "include/denc.h" | |
12 | #include "include/stringify.h" | |
13 | ||
14 | #include "mds/mdstypes.h" | |
15 | #include "mgr/Types.h" | |
16 | ||
17 | typedef std::vector<std::string> MDSPerfMetricSubKey; // array of regex match | |
18 | typedef std::vector<MDSPerfMetricSubKey> MDSPerfMetricKey; | |
19 | ||
20 | enum class MDSPerfMetricSubKeyType : uint8_t { | |
21 | MDS_RANK = 0, | |
22 | CLIENT_ID = 1, | |
23 | }; | |
24 | ||
25 | struct MDSPerfMetricSubKeyDescriptor { | |
26 | MDSPerfMetricSubKeyType type = static_cast<MDSPerfMetricSubKeyType>(-1); | |
27 | std::string regex_str; | |
28 | std::regex regex; | |
29 | ||
30 | bool is_supported() const { | |
31 | switch (type) { | |
32 | case MDSPerfMetricSubKeyType::MDS_RANK: | |
33 | case MDSPerfMetricSubKeyType::CLIENT_ID: | |
34 | return true; | |
35 | default: | |
36 | return false; | |
37 | } | |
38 | } | |
39 | ||
40 | MDSPerfMetricSubKeyDescriptor() { | |
41 | } | |
42 | MDSPerfMetricSubKeyDescriptor(MDSPerfMetricSubKeyType type, const std::string ®ex_str) | |
43 | : type(type), regex_str(regex_str) { | |
44 | } | |
45 | ||
46 | bool operator<(const MDSPerfMetricSubKeyDescriptor &other) const { | |
47 | if (type < other.type) { | |
48 | return true; | |
49 | } | |
50 | if (type > other.type) { | |
51 | return false; | |
52 | } | |
53 | return regex_str < other.regex_str; | |
54 | } | |
55 | ||
56 | DENC(MDSPerfMetricSubKeyDescriptor, v, p) { | |
57 | DENC_START(1, 1, p); | |
58 | denc(v.type, p); | |
59 | denc(v.regex_str, p); | |
60 | DENC_FINISH(p); | |
61 | } | |
62 | }; | |
63 | WRITE_CLASS_DENC(MDSPerfMetricSubKeyDescriptor) | |
64 | ||
65 | std::ostream& operator<<(std::ostream& os, const MDSPerfMetricSubKeyDescriptor &d); | |
66 | typedef std::vector<MDSPerfMetricSubKeyDescriptor> MDSPerfMetricKeyDescriptor; | |
67 | ||
68 | template<> | |
69 | struct denc_traits<MDSPerfMetricKeyDescriptor> { | |
70 | static constexpr bool supported = true; | |
71 | static constexpr bool bounded = false; | |
72 | static constexpr bool featured = false; | |
73 | static constexpr bool need_contiguous = true; | |
74 | static void bound_encode(const MDSPerfMetricKeyDescriptor& v, size_t& p) { | |
75 | p += sizeof(uint32_t); | |
76 | const auto size = v.size(); | |
77 | if (size) { | |
78 | size_t per = 0; | |
79 | denc(v.front(), per); | |
80 | p += per * size; | |
81 | } | |
82 | } | |
83 | static void encode(const MDSPerfMetricKeyDescriptor& v, | |
84 | ceph::buffer::list::contiguous_appender& p) { | |
85 | denc_varint(v.size(), p); | |
86 | for (auto& i : v) { | |
87 | denc(i, p); | |
88 | } | |
89 | } | |
90 | static void decode(MDSPerfMetricKeyDescriptor& v, | |
91 | ceph::buffer::ptr::const_iterator& p) { | |
92 | unsigned num; | |
93 | denc_varint(num, p); | |
94 | v.clear(); | |
95 | v.reserve(num); | |
96 | for (unsigned i=0; i < num; ++i) { | |
97 | MDSPerfMetricSubKeyDescriptor d; | |
98 | denc(d, p); | |
99 | if (!d.is_supported()) { | |
100 | v.clear(); | |
101 | return; | |
102 | } | |
103 | try { | |
104 | d.regex = d.regex_str.c_str(); | |
105 | } catch (const std::regex_error& e) { | |
106 | v.clear(); | |
107 | return; | |
108 | } | |
109 | if (d.regex.mark_count() == 0) { | |
110 | v.clear(); | |
111 | return; | |
112 | } | |
113 | v.push_back(std::move(d)); | |
114 | } | |
115 | } | |
116 | }; | |
117 | ||
118 | enum class MDSPerformanceCounterType : uint8_t { | |
119 | CAP_HIT_METRIC = 0, | |
120 | READ_LATENCY_METRIC = 1, | |
121 | WRITE_LATENCY_METRIC = 2, | |
122 | METADATA_LATENCY_METRIC = 3, | |
123 | DENTRY_LEASE_METRIC = 4, | |
124 | OPENED_FILES_METRIC = 5, | |
125 | PINNED_ICAPS_METRIC = 6, | |
126 | OPENED_INODES_METRIC = 7, | |
127 | }; | |
128 | ||
129 | struct MDSPerformanceCounterDescriptor { | |
130 | MDSPerformanceCounterType type = static_cast<MDSPerformanceCounterType>(-1); | |
131 | ||
132 | bool is_supported() const { | |
133 | switch(type) { | |
134 | case MDSPerformanceCounterType::CAP_HIT_METRIC: | |
135 | case MDSPerformanceCounterType::READ_LATENCY_METRIC: | |
136 | case MDSPerformanceCounterType::WRITE_LATENCY_METRIC: | |
137 | case MDSPerformanceCounterType::METADATA_LATENCY_METRIC: | |
138 | case MDSPerformanceCounterType::DENTRY_LEASE_METRIC: | |
139 | case MDSPerformanceCounterType::OPENED_FILES_METRIC: | |
140 | case MDSPerformanceCounterType::PINNED_ICAPS_METRIC: | |
141 | case MDSPerformanceCounterType::OPENED_INODES_METRIC: | |
142 | return true; | |
143 | default: | |
144 | return false; | |
145 | } | |
146 | } | |
147 | ||
148 | MDSPerformanceCounterDescriptor() { | |
149 | } | |
150 | MDSPerformanceCounterDescriptor(MDSPerformanceCounterType type) : type(type) { | |
151 | } | |
152 | ||
153 | bool operator<(const MDSPerformanceCounterDescriptor &other) const { | |
154 | return type < other.type; | |
155 | } | |
156 | ||
157 | bool operator==(const MDSPerformanceCounterDescriptor &other) const { | |
158 | return type == other.type; | |
159 | } | |
160 | ||
161 | bool operator!=(const MDSPerformanceCounterDescriptor &other) const { | |
162 | return type != other.type; | |
163 | } | |
164 | ||
165 | DENC(MDSPerformanceCounterDescriptor, v, p) { | |
166 | DENC_START(1, 1, p); | |
167 | denc(v.type, p); | |
168 | DENC_FINISH(p); | |
169 | } | |
170 | ||
171 | void pack_counter(const PerformanceCounter &c, ceph::buffer::list *bl) const; | |
172 | void unpack_counter(ceph::buffer::list::const_iterator& bl, PerformanceCounter *c) const; | |
173 | }; | |
174 | WRITE_CLASS_DENC(MDSPerformanceCounterDescriptor) | |
175 | ||
176 | std::ostream& operator<<(std::ostream &os, const MDSPerformanceCounterDescriptor &d); | |
177 | typedef std::vector<MDSPerformanceCounterDescriptor> MDSPerformanceCounterDescriptors; | |
178 | ||
179 | template<> | |
180 | struct denc_traits<MDSPerformanceCounterDescriptors> { | |
181 | static constexpr bool supported = true; | |
182 | static constexpr bool bounded = false; | |
183 | static constexpr bool featured = false; | |
184 | static constexpr bool need_contiguous = true; | |
185 | static void bound_encode(const MDSPerformanceCounterDescriptors& v, size_t& p) { | |
186 | p += sizeof(uint32_t); | |
187 | const auto size = v.size(); | |
188 | if (size) { | |
189 | size_t per = 0; | |
190 | denc(v.front(), per); | |
191 | p += per * size; | |
192 | } | |
193 | } | |
194 | static void encode(const MDSPerformanceCounterDescriptors& v, | |
195 | ceph::buffer::list::contiguous_appender& p) { | |
196 | denc_varint(v.size(), p); | |
197 | for (auto& i : v) { | |
198 | denc(i, p); | |
199 | } | |
200 | } | |
201 | static void decode(MDSPerformanceCounterDescriptors& v, | |
202 | ceph::buffer::ptr::const_iterator& p) { | |
203 | unsigned num; | |
204 | denc_varint(num, p); | |
205 | v.clear(); | |
206 | v.reserve(num); | |
207 | for (unsigned i=0; i < num; ++i) { | |
208 | MDSPerformanceCounterDescriptor d; | |
209 | denc(d, p); | |
210 | if (d.is_supported()) { | |
211 | v.push_back(std::move(d)); | |
212 | } | |
213 | } | |
214 | } | |
215 | }; | |
216 | ||
217 | struct MDSPerfMetricLimit { | |
218 | MDSPerformanceCounterDescriptor order_by; | |
219 | uint64_t max_count; | |
220 | ||
221 | MDSPerfMetricLimit() { | |
222 | } | |
223 | MDSPerfMetricLimit(const MDSPerformanceCounterDescriptor &order_by, uint64_t max_count) | |
224 | : order_by(order_by), max_count(max_count) { | |
225 | } | |
226 | ||
227 | bool operator<(const MDSPerfMetricLimit &other) const { | |
228 | if (order_by != other.order_by) { | |
229 | return order_by < other.order_by; | |
230 | } | |
231 | ||
232 | return max_count < other.max_count; | |
233 | } | |
234 | ||
235 | DENC(MDSPerfMetricLimit, v, p) { | |
236 | DENC_START(1, 1, p); | |
237 | denc(v.order_by, p); | |
238 | denc(v.max_count, p); | |
239 | DENC_FINISH(p); | |
240 | } | |
241 | }; | |
242 | WRITE_CLASS_DENC(MDSPerfMetricLimit) | |
243 | ||
244 | std::ostream &operator<<(std::ostream &os, const MDSPerfMetricLimit &limit); | |
245 | typedef std::set<MDSPerfMetricLimit> MDSPerfMetricLimits; | |
246 | ||
247 | struct MDSPerfMetricQuery { | |
248 | MDSPerfMetricKeyDescriptor key_descriptor; | |
249 | MDSPerformanceCounterDescriptors performance_counter_descriptors; | |
250 | ||
251 | MDSPerfMetricQuery() { | |
252 | } | |
253 | MDSPerfMetricQuery(const MDSPerfMetricKeyDescriptor &key_descriptor, | |
254 | const MDSPerformanceCounterDescriptors &performance_counter_descriptors) | |
255 | : key_descriptor(key_descriptor), | |
256 | performance_counter_descriptors(performance_counter_descriptors) | |
257 | { | |
258 | } | |
259 | ||
260 | bool operator<(const MDSPerfMetricQuery &other) const { | |
261 | if (key_descriptor < other.key_descriptor) { | |
262 | return true; | |
263 | } | |
264 | if (key_descriptor > other.key_descriptor) { | |
265 | return false; | |
266 | } | |
267 | return performance_counter_descriptors < other.performance_counter_descriptors; | |
268 | } | |
269 | ||
270 | template <typename L> | |
271 | bool get_key(L&& get_sub_key, MDSPerfMetricKey *key) const { | |
272 | for (auto &sub_key_descriptor : key_descriptor) { | |
273 | MDSPerfMetricSubKey sub_key; | |
274 | if (!get_sub_key(sub_key_descriptor, &sub_key)) { | |
275 | return false; | |
276 | } | |
277 | key->push_back(sub_key); | |
278 | } | |
279 | return true; | |
280 | } | |
281 | ||
282 | void get_performance_counter_descriptors(MDSPerformanceCounterDescriptors *descriptors) const { | |
283 | *descriptors = performance_counter_descriptors; | |
284 | } | |
285 | ||
286 | template <typename L> | |
287 | void update_counters(L &&update_counter, PerformanceCounters *counters) const { | |
288 | auto it = counters->begin(); | |
289 | for (auto &descriptor : performance_counter_descriptors) { | |
290 | // TODO: optimize | |
291 | if (it == counters->end()) { | |
292 | counters->push_back(PerformanceCounter()); | |
293 | it = std::prev(counters->end()); | |
294 | } | |
295 | update_counter(descriptor, &(*it)); | |
296 | it++; | |
297 | } | |
298 | } | |
299 | ||
300 | DENC(MDSPerfMetricQuery, v, p) { | |
301 | DENC_START(1, 1, p); | |
302 | denc(v.key_descriptor, p); | |
303 | denc(v.performance_counter_descriptors, p); | |
304 | DENC_FINISH(p); | |
305 | } | |
306 | ||
307 | void pack_counters(const PerformanceCounters &counters, ceph::buffer::list *bl) const; | |
308 | }; | |
309 | WRITE_CLASS_DENC(MDSPerfMetricQuery) | |
310 | ||
311 | std::ostream &operator<<(std::ostream &os, const MDSPerfMetricQuery &query); | |
312 | ||
313 | struct MDSPerfCollector : PerfCollector { | |
314 | std::map<MDSPerfMetricKey, PerformanceCounters> counters; | |
315 | std::set<mds_rank_t> delayed_ranks; | |
316 | ||
317 | MDSPerfCollector(MetricQueryID query_id) | |
318 | : PerfCollector(query_id) { | |
319 | } | |
320 | }; | |
321 | ||
322 | struct MDSPerfMetrics { | |
323 | MDSPerformanceCounterDescriptors performance_counter_descriptors; | |
324 | std::map<MDSPerfMetricKey, ceph::buffer::list> group_packed_performance_counters; | |
325 | ||
326 | DENC(MDSPerfMetrics, v, p) { | |
327 | DENC_START(1, 1, p); | |
328 | denc(v.performance_counter_descriptors, p); | |
329 | denc(v.group_packed_performance_counters, p); | |
330 | DENC_FINISH(p); | |
331 | } | |
332 | }; | |
333 | ||
334 | struct MDSPerfMetricReport { | |
335 | std::map<MDSPerfMetricQuery, MDSPerfMetrics> reports; | |
336 | // set of active ranks that have delayed (stale) metrics | |
337 | std::set<mds_rank_t> rank_metrics_delayed; | |
338 | ||
339 | DENC(MDSPerfMetricReport, v, p) { | |
340 | DENC_START(1, 1, p); | |
341 | denc(v.reports, p); | |
342 | denc(v.rank_metrics_delayed, p); | |
343 | DENC_FINISH(p); | |
344 | } | |
345 | }; | |
346 | ||
347 | WRITE_CLASS_DENC(MDSPerfMetrics) | |
348 | WRITE_CLASS_DENC(MDSPerfMetricReport) | |
349 | ||
350 | #endif // CEPH_MGR_MDS_PERF_METRIC_TYPES_H |