]>
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_INCLUDE_CEPHFS_METRICS_TYPES_H | |
5 | #define CEPH_INCLUDE_CEPHFS_METRICS_TYPES_H | |
6 | ||
7 | #include <string> | |
8 | #include <boost/variant.hpp> | |
9 | ||
10 | #include "common/Formatter.h" | |
11 | #include "include/buffer_fwd.h" | |
12 | #include "include/encoding.h" | |
13 | #include "include/int_types.h" | |
14 | #include "include/stringify.h" | |
15 | #include "include/utime.h" | |
16 | ||
17 | namespace ceph { class Formatter; } | |
18 | ||
19 | enum ClientMetricType { | |
20 | CLIENT_METRIC_TYPE_CAP_INFO, | |
21 | CLIENT_METRIC_TYPE_READ_LATENCY, | |
22 | CLIENT_METRIC_TYPE_WRITE_LATENCY, | |
23 | CLIENT_METRIC_TYPE_METADATA_LATENCY, | |
24 | CLIENT_METRIC_TYPE_DENTRY_LEASE, | |
25 | CLIENT_METRIC_TYPE_OPENED_FILES, | |
26 | CLIENT_METRIC_TYPE_PINNED_ICAPS, | |
27 | CLIENT_METRIC_TYPE_OPENED_INODES, | |
28 | }; | |
29 | inline std::ostream &operator<<(std::ostream &os, const ClientMetricType &type) { | |
30 | switch(type) { | |
31 | case ClientMetricType::CLIENT_METRIC_TYPE_CAP_INFO: | |
32 | os << "CAP_INFO"; | |
33 | break; | |
34 | case ClientMetricType::CLIENT_METRIC_TYPE_READ_LATENCY: | |
35 | os << "READ_LATENCY"; | |
36 | break; | |
37 | case ClientMetricType::CLIENT_METRIC_TYPE_WRITE_LATENCY: | |
38 | os << "WRITE_LATENCY"; | |
39 | break; | |
40 | case ClientMetricType::CLIENT_METRIC_TYPE_METADATA_LATENCY: | |
41 | os << "METADATA_LATENCY"; | |
42 | break; | |
43 | case ClientMetricType::CLIENT_METRIC_TYPE_DENTRY_LEASE: | |
44 | os << "DENTRY_LEASE"; | |
45 | break; | |
46 | case ClientMetricType::CLIENT_METRIC_TYPE_OPENED_FILES: | |
47 | os << "OPENED_FILES"; | |
48 | break; | |
49 | case ClientMetricType::CLIENT_METRIC_TYPE_PINNED_ICAPS: | |
50 | os << "PINNED_ICAPS"; | |
51 | break; | |
52 | case ClientMetricType::CLIENT_METRIC_TYPE_OPENED_INODES: | |
53 | os << "OPENED_INODES"; | |
54 | break; | |
55 | default: | |
b3b6e05e TL |
56 | os << "(UNKNOWN:" << static_cast<std::underlying_type<ClientMetricType>::type>(type) << ")"; |
57 | break; | |
f67539c2 TL |
58 | } |
59 | ||
60 | return os; | |
61 | } | |
62 | ||
63 | struct CapInfoPayload { | |
64 | static const ClientMetricType METRIC_TYPE = ClientMetricType::CLIENT_METRIC_TYPE_CAP_INFO; | |
65 | ||
66 | uint64_t cap_hits = 0; | |
67 | uint64_t cap_misses = 0; | |
68 | uint64_t nr_caps = 0; | |
69 | ||
70 | CapInfoPayload() { } | |
71 | CapInfoPayload(uint64_t cap_hits, uint64_t cap_misses, uint64_t nr_caps) | |
72 | : cap_hits(cap_hits), cap_misses(cap_misses), nr_caps(nr_caps) { | |
73 | } | |
74 | ||
75 | void encode(bufferlist &bl) const { | |
76 | using ceph::encode; | |
77 | ENCODE_START(1, 1, bl); | |
78 | encode(cap_hits, bl); | |
79 | encode(cap_misses, bl); | |
80 | encode(nr_caps, bl); | |
81 | ENCODE_FINISH(bl); | |
82 | } | |
83 | ||
84 | void decode(bufferlist::const_iterator &iter) { | |
85 | using ceph::decode; | |
86 | DECODE_START(1, iter); | |
87 | decode(cap_hits, iter); | |
88 | decode(cap_misses, iter); | |
89 | decode(nr_caps, iter); | |
90 | DECODE_FINISH(iter); | |
91 | } | |
92 | ||
93 | void dump(Formatter *f) const { | |
94 | f->dump_int("cap_hits", cap_hits); | |
95 | f->dump_int("cap_misses", cap_misses); | |
96 | f->dump_int("num_caps", nr_caps); | |
97 | } | |
98 | ||
99 | void print(ostream *out) const { | |
100 | *out << "cap_hits: " << cap_hits << " " | |
101 | << "cap_misses: " << cap_misses << " " | |
102 | << "num_caps: " << nr_caps; | |
103 | } | |
104 | }; | |
105 | ||
106 | struct ReadLatencyPayload { | |
107 | static const ClientMetricType METRIC_TYPE = ClientMetricType::CLIENT_METRIC_TYPE_READ_LATENCY; | |
108 | ||
109 | utime_t lat; | |
110 | ||
111 | ReadLatencyPayload() { } | |
112 | ReadLatencyPayload(utime_t lat) | |
113 | : lat(lat) { | |
114 | } | |
115 | ||
116 | void encode(bufferlist &bl) const { | |
117 | using ceph::encode; | |
118 | ENCODE_START(1, 1, bl); | |
119 | encode(lat, bl); | |
120 | ENCODE_FINISH(bl); | |
121 | } | |
122 | ||
123 | void decode(bufferlist::const_iterator &iter) { | |
124 | using ceph::decode; | |
125 | DECODE_START(1, iter); | |
126 | decode(lat, iter); | |
127 | DECODE_FINISH(iter); | |
128 | } | |
129 | ||
130 | void dump(Formatter *f) const { | |
131 | f->dump_int("latency", lat); | |
132 | } | |
133 | ||
134 | void print(ostream *out) const { | |
135 | *out << "latency: " << lat; | |
136 | } | |
137 | }; | |
138 | ||
139 | struct WriteLatencyPayload { | |
140 | static const ClientMetricType METRIC_TYPE = ClientMetricType::CLIENT_METRIC_TYPE_WRITE_LATENCY; | |
141 | ||
142 | utime_t lat; | |
143 | ||
144 | WriteLatencyPayload() { } | |
145 | WriteLatencyPayload(utime_t lat) | |
146 | : lat(lat) { | |
147 | } | |
148 | ||
149 | void encode(bufferlist &bl) const { | |
150 | using ceph::encode; | |
151 | ENCODE_START(1, 1, bl); | |
152 | encode(lat, bl); | |
153 | ENCODE_FINISH(bl); | |
154 | } | |
155 | ||
156 | void decode(bufferlist::const_iterator &iter) { | |
157 | using ceph::decode; | |
158 | DECODE_START(1, iter); | |
159 | decode(lat, iter); | |
160 | DECODE_FINISH(iter); | |
161 | } | |
162 | ||
163 | void dump(Formatter *f) const { | |
164 | f->dump_int("latency", lat); | |
165 | } | |
166 | ||
167 | void print(ostream *out) const { | |
168 | *out << "latency: " << lat; | |
169 | } | |
170 | }; | |
171 | ||
172 | struct MetadataLatencyPayload { | |
173 | static const ClientMetricType METRIC_TYPE = ClientMetricType::CLIENT_METRIC_TYPE_METADATA_LATENCY; | |
174 | ||
175 | utime_t lat; | |
176 | ||
177 | MetadataLatencyPayload() { } | |
178 | MetadataLatencyPayload(utime_t lat) | |
179 | : lat(lat) { | |
180 | } | |
181 | ||
182 | void encode(bufferlist &bl) const { | |
183 | using ceph::encode; | |
184 | ENCODE_START(1, 1, bl); | |
185 | encode(lat, bl); | |
186 | ENCODE_FINISH(bl); | |
187 | } | |
188 | ||
189 | void decode(bufferlist::const_iterator &iter) { | |
190 | using ceph::decode; | |
191 | DECODE_START(1, iter); | |
192 | decode(lat, iter); | |
193 | DECODE_FINISH(iter); | |
194 | } | |
195 | ||
196 | void dump(Formatter *f) const { | |
197 | f->dump_int("latency", lat); | |
198 | } | |
199 | ||
200 | void print(ostream *out) const { | |
201 | *out << "latency: " << lat; | |
202 | } | |
203 | }; | |
204 | ||
205 | struct DentryLeasePayload { | |
206 | static const ClientMetricType METRIC_TYPE = ClientMetricType::CLIENT_METRIC_TYPE_DENTRY_LEASE; | |
207 | ||
208 | uint64_t dlease_hits = 0; | |
209 | uint64_t dlease_misses = 0; | |
210 | uint64_t nr_dentries = 0; | |
211 | ||
212 | DentryLeasePayload() { } | |
213 | DentryLeasePayload(uint64_t dlease_hits, uint64_t dlease_misses, uint64_t nr_dentries) | |
214 | : dlease_hits(dlease_hits), dlease_misses(dlease_misses), nr_dentries(nr_dentries) { | |
215 | } | |
216 | ||
217 | void encode(bufferlist &bl) const { | |
218 | using ceph::encode; | |
219 | ENCODE_START(1, 1, bl); | |
220 | encode(dlease_hits, bl); | |
221 | encode(dlease_misses, bl); | |
222 | encode(nr_dentries, bl); | |
223 | ENCODE_FINISH(bl); | |
224 | } | |
225 | ||
226 | void decode(bufferlist::const_iterator &iter) { | |
227 | using ceph::decode; | |
228 | DECODE_START(1, iter); | |
229 | decode(dlease_hits, iter); | |
230 | decode(dlease_misses, iter); | |
231 | decode(nr_dentries, iter); | |
232 | DECODE_FINISH(iter); | |
233 | } | |
234 | ||
235 | void dump(Formatter *f) const { | |
236 | f->dump_int("dlease_hits", dlease_hits); | |
237 | f->dump_int("dlease_misses", dlease_misses); | |
238 | f->dump_int("num_dentries", nr_dentries); | |
239 | } | |
240 | ||
241 | void print(ostream *out) const { | |
242 | *out << "dlease_hits: " << dlease_hits << " " | |
243 | << "dlease_misses: " << dlease_misses << " " | |
244 | << "num_dentries: " << nr_dentries; | |
245 | } | |
246 | }; | |
247 | ||
248 | struct OpenedFilesPayload { | |
249 | static const ClientMetricType METRIC_TYPE = ClientMetricType::CLIENT_METRIC_TYPE_OPENED_FILES; | |
250 | ||
251 | uint64_t opened_files = 0; | |
252 | uint64_t total_inodes = 0; | |
253 | ||
254 | OpenedFilesPayload() { } | |
255 | OpenedFilesPayload(uint64_t opened_files, uint64_t total_inodes) | |
256 | : opened_files(opened_files), total_inodes(total_inodes) { | |
257 | } | |
258 | ||
259 | void encode(bufferlist &bl) const { | |
260 | using ceph::encode; | |
261 | ENCODE_START(1, 1, bl); | |
262 | encode(opened_files, bl); | |
263 | encode(total_inodes, bl); | |
264 | ENCODE_FINISH(bl); | |
265 | } | |
266 | ||
267 | void decode(bufferlist::const_iterator &iter) { | |
268 | using ceph::decode; | |
269 | DECODE_START(1, iter); | |
270 | decode(opened_files, iter); | |
271 | decode(total_inodes, iter); | |
272 | DECODE_FINISH(iter); | |
273 | } | |
274 | ||
275 | void dump(Formatter *f) const { | |
276 | f->dump_int("opened_files", opened_files); | |
277 | f->dump_int("total_inodes", total_inodes); | |
278 | } | |
279 | ||
280 | void print(ostream *out) const { | |
281 | *out << "opened_files: " << opened_files << " " | |
282 | << "total_inodes: " << total_inodes; | |
283 | } | |
284 | }; | |
285 | ||
286 | struct PinnedIcapsPayload { | |
287 | static const ClientMetricType METRIC_TYPE = ClientMetricType::CLIENT_METRIC_TYPE_PINNED_ICAPS; | |
288 | ||
289 | uint64_t pinned_icaps = 0; | |
290 | uint64_t total_inodes = 0; | |
291 | ||
292 | PinnedIcapsPayload() { } | |
293 | PinnedIcapsPayload(uint64_t pinned_icaps, uint64_t total_inodes) | |
294 | : pinned_icaps(pinned_icaps), total_inodes(total_inodes) { | |
295 | } | |
296 | ||
297 | void encode(bufferlist &bl) const { | |
298 | using ceph::encode; | |
299 | ENCODE_START(1, 1, bl); | |
300 | encode(pinned_icaps, bl); | |
301 | encode(total_inodes, bl); | |
302 | ENCODE_FINISH(bl); | |
303 | } | |
304 | ||
305 | void decode(bufferlist::const_iterator &iter) { | |
306 | using ceph::decode; | |
307 | DECODE_START(1, iter); | |
308 | decode(pinned_icaps, iter); | |
309 | decode(total_inodes, iter); | |
310 | DECODE_FINISH(iter); | |
311 | } | |
312 | ||
313 | void dump(Formatter *f) const { | |
314 | f->dump_int("pinned_icaps", pinned_icaps); | |
315 | f->dump_int("total_inodes", total_inodes); | |
316 | } | |
317 | ||
318 | void print(ostream *out) const { | |
319 | *out << "pinned_icaps: " << pinned_icaps << " " | |
320 | << "total_inodes: " << total_inodes; | |
321 | } | |
322 | }; | |
323 | ||
324 | struct OpenedInodesPayload { | |
325 | static const ClientMetricType METRIC_TYPE = ClientMetricType::CLIENT_METRIC_TYPE_OPENED_INODES; | |
326 | ||
327 | uint64_t opened_inodes = 0; | |
328 | uint64_t total_inodes = 0; | |
329 | ||
330 | OpenedInodesPayload() { } | |
331 | OpenedInodesPayload(uint64_t opened_inodes, uint64_t total_inodes) | |
332 | : opened_inodes(opened_inodes), total_inodes(total_inodes) { | |
333 | } | |
334 | ||
335 | void encode(bufferlist &bl) const { | |
336 | using ceph::encode; | |
337 | ENCODE_START(1, 1, bl); | |
338 | encode(opened_inodes, bl); | |
339 | encode(total_inodes, bl); | |
340 | ENCODE_FINISH(bl); | |
341 | } | |
342 | ||
343 | void decode(bufferlist::const_iterator &iter) { | |
344 | using ceph::decode; | |
345 | DECODE_START(1, iter); | |
346 | decode(opened_inodes, iter); | |
347 | decode(total_inodes, iter); | |
348 | DECODE_FINISH(iter); | |
349 | } | |
350 | ||
351 | void dump(Formatter *f) const { | |
352 | f->dump_int("opened_inodes", opened_inodes); | |
353 | f->dump_int("total_inodes", total_inodes); | |
354 | } | |
355 | ||
356 | void print(ostream *out) const { | |
357 | *out << "opened_inodes: " << opened_inodes << " " | |
358 | << "total_inodes: " << total_inodes; | |
359 | } | |
360 | }; | |
361 | ||
362 | struct UnknownPayload { | |
363 | static const ClientMetricType METRIC_TYPE = static_cast<ClientMetricType>(-1); | |
364 | ||
365 | UnknownPayload() { } | |
366 | ||
367 | void encode(bufferlist &bl) const { | |
368 | } | |
369 | ||
370 | void decode(bufferlist::const_iterator &iter) { | |
371 | using ceph::decode; | |
372 | DECODE_START(254, iter); | |
373 | iter.seek(struct_len); | |
374 | DECODE_FINISH(iter); | |
375 | } | |
376 | ||
377 | void dump(Formatter *f) const { | |
378 | } | |
379 | ||
380 | void print(ostream *out) const { | |
381 | } | |
382 | }; | |
383 | ||
384 | typedef boost::variant<CapInfoPayload, | |
385 | ReadLatencyPayload, | |
386 | WriteLatencyPayload, | |
387 | MetadataLatencyPayload, | |
388 | DentryLeasePayload, | |
389 | OpenedFilesPayload, | |
390 | PinnedIcapsPayload, | |
391 | OpenedInodesPayload, | |
392 | UnknownPayload> ClientMetricPayload; | |
393 | ||
394 | // metric update message sent by clients | |
395 | struct ClientMetricMessage { | |
396 | public: | |
397 | ClientMetricMessage(const ClientMetricPayload &payload = UnknownPayload()) | |
398 | : payload(payload) { | |
399 | } | |
400 | ||
401 | class EncodePayloadVisitor : public boost::static_visitor<void> { | |
402 | public: | |
403 | explicit EncodePayloadVisitor(bufferlist &bl) : m_bl(bl) { | |
404 | } | |
405 | ||
406 | template <typename ClientMetricPayload> | |
407 | inline void operator()(const ClientMetricPayload &payload) const { | |
408 | using ceph::encode; | |
409 | encode(static_cast<uint32_t>(ClientMetricPayload::METRIC_TYPE), m_bl); | |
410 | payload.encode(m_bl); | |
411 | } | |
412 | ||
413 | private: | |
414 | bufferlist &m_bl; | |
415 | }; | |
416 | ||
417 | class DecodePayloadVisitor : public boost::static_visitor<void> { | |
418 | public: | |
419 | DecodePayloadVisitor(bufferlist::const_iterator &iter) : m_iter(iter) { | |
420 | } | |
421 | ||
422 | template <typename ClientMetricPayload> | |
423 | inline void operator()(ClientMetricPayload &payload) const { | |
424 | using ceph::decode; | |
425 | payload.decode(m_iter); | |
426 | } | |
427 | ||
428 | private: | |
429 | bufferlist::const_iterator &m_iter; | |
430 | }; | |
431 | ||
432 | class DumpPayloadVisitor : public boost::static_visitor<void> { | |
433 | public: | |
434 | explicit DumpPayloadVisitor(Formatter *formatter) : m_formatter(formatter) { | |
435 | } | |
436 | ||
437 | template <typename ClientMetricPayload> | |
438 | inline void operator()(const ClientMetricPayload &payload) const { | |
439 | ClientMetricType metric_type = ClientMetricPayload::METRIC_TYPE; | |
440 | m_formatter->dump_string("client_metric_type", stringify(metric_type)); | |
441 | payload.dump(m_formatter); | |
442 | } | |
443 | ||
444 | private: | |
445 | Formatter *m_formatter; | |
446 | }; | |
447 | ||
448 | class PrintPayloadVisitor : public boost::static_visitor<void> { | |
449 | public: | |
450 | explicit PrintPayloadVisitor(ostream *out) : _out(out) { | |
451 | } | |
452 | ||
453 | template <typename ClientMetricPayload> | |
454 | inline void operator()(const ClientMetricPayload &payload) const { | |
455 | ClientMetricType metric_type = ClientMetricPayload::METRIC_TYPE; | |
456 | *_out << "[client_metric_type: " << metric_type; | |
457 | payload.print(_out); | |
458 | *_out << "]"; | |
459 | } | |
460 | ||
461 | private: | |
462 | ostream *_out; | |
463 | }; | |
464 | ||
465 | void encode(bufferlist &bl) const { | |
466 | boost::apply_visitor(EncodePayloadVisitor(bl), payload); | |
467 | } | |
468 | ||
469 | void decode(bufferlist::const_iterator &iter) { | |
470 | using ceph::decode; | |
471 | ||
472 | uint32_t metric_type; | |
473 | decode(metric_type, iter); | |
474 | ||
475 | switch (metric_type) { | |
476 | case ClientMetricType::CLIENT_METRIC_TYPE_CAP_INFO: | |
477 | payload = CapInfoPayload(); | |
478 | break; | |
479 | case ClientMetricType::CLIENT_METRIC_TYPE_READ_LATENCY: | |
480 | payload = ReadLatencyPayload(); | |
481 | break; | |
482 | case ClientMetricType::CLIENT_METRIC_TYPE_WRITE_LATENCY: | |
483 | payload = WriteLatencyPayload(); | |
484 | break; | |
485 | case ClientMetricType::CLIENT_METRIC_TYPE_METADATA_LATENCY: | |
486 | payload = MetadataLatencyPayload(); | |
487 | break; | |
488 | case ClientMetricType::CLIENT_METRIC_TYPE_DENTRY_LEASE: | |
489 | payload = DentryLeasePayload(); | |
490 | break; | |
491 | case ClientMetricType::CLIENT_METRIC_TYPE_OPENED_FILES: | |
492 | payload = OpenedFilesPayload(); | |
493 | break; | |
494 | case ClientMetricType::CLIENT_METRIC_TYPE_PINNED_ICAPS: | |
495 | payload = PinnedIcapsPayload(); | |
496 | break; | |
497 | case ClientMetricType::CLIENT_METRIC_TYPE_OPENED_INODES: | |
498 | payload = OpenedInodesPayload(); | |
499 | break; | |
500 | default: | |
501 | payload = UnknownPayload(); | |
502 | break; | |
503 | } | |
504 | ||
505 | boost::apply_visitor(DecodePayloadVisitor(iter), payload); | |
506 | } | |
507 | ||
508 | void dump(Formatter *f) const { | |
509 | apply_visitor(DumpPayloadVisitor(f), payload); | |
510 | } | |
511 | ||
512 | void print(ostream *out) const { | |
513 | apply_visitor(PrintPayloadVisitor(out), payload); | |
514 | } | |
515 | ||
516 | ClientMetricPayload payload; | |
517 | }; | |
518 | WRITE_CLASS_ENCODER(ClientMetricMessage); | |
519 | ||
520 | #endif // CEPH_INCLUDE_CEPHFS_METRICS_TYPES_H |