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