]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/src/core/scollectd.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / seastar / src / core / scollectd.cc
1 /*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18 /*
19 * Copyright (C) 2014 Cloudius Systems, Ltd.
20 */
21
22 #include <functional>
23 #include <unordered_map>
24 #include <forward_list>
25 #include <utility>
26 #include <string>
27 #include <map>
28 #include <iostream>
29 #include <unordered_map>
30
31 #include <seastar/core/future-util.hh>
32 #include <seastar/core/scollectd_api.hh>
33 #include <seastar/core/metrics_api.hh>
34 #include <seastar/core/byteorder.hh>
35
36 #include "core/scollectd-impl.hh"
37
38 namespace seastar {
39
40 bool scollectd::type_instance_id::operator<(
41 const scollectd::type_instance_id& id2) const {
42 auto& id1 = *this;
43 return std::tie(id1.plugin(), id1.plugin_instance(), id1.type(),
44 id1.type_instance())
45 < std::tie(id2.plugin(), id2.plugin_instance(), id2.type(),
46 id2.type_instance());
47 }
48 bool scollectd::type_instance_id::operator==(
49 const scollectd::type_instance_id & id2) const {
50 auto& id1 = *this;
51 return std::tie(id1.plugin(), id1.plugin_instance(), id1.type(),
52 id1.type_instance())
53 == std::tie(id2.plugin(), id2.plugin_instance(), id2.type(),
54 id2.type_instance());
55 }
56
57 namespace scollectd {
58
59 ::seastar::logger logger("scollectd");
60 thread_local unsigned type_instance_id::_next_truncated_idx = 0;
61
62 registration::~registration() {
63 unregister();
64 }
65
66 registration::registration(const type_instance_id& id)
67 : _id(id), _impl(seastar::metrics::impl::get_local_impl()) {
68 }
69
70 registration::registration(type_instance_id&& id)
71 : _id(std::move(id)), _impl(seastar::metrics::impl::get_local_impl()) {
72 }
73
74 seastar::metrics::impl::metric_id to_metrics_id(const type_instance_id & id) {
75 return seastar::metrics::impl::metric_id(id.plugin(), id.type_instance(),
76 {{seastar::metrics::shard_label.name(), seastar::metrics::impl::shard()}, {seastar::metrics::type_label.name(), id.type()}});
77 }
78
79
80 const plugin_instance_id per_cpu_plugin_instance("#cpu");
81
82 static const size_t payload_size = 1024;
83
84 enum class part_type : uint16_t {
85 Host = 0x0000, // The name of the host to associate with subsequent data values
86 Time = 0x0001, // Time Numeric The timestamp to associate with subsequent data values, unix time format (seconds since epoch)
87 TimeHr = 0x0008, // Time (high resolution) Numeric The timestamp to associate with subsequent data values. Time is defined in 2–30 seconds since epoch. New in Version 5.0.
88 Plugin = 0x0002, // Plugin String The plugin name to associate with subsequent data values, e.g. "cpu"
89 PluginInst = 0x0003, // Plugin instance String The plugin instance name to associate with subsequent data values, e.g. "1"
90 Type = 0x0004, // Type String The type name to associate with subsequent data values, e.g. "cpu"
91 TypeInst = 0x0005, // Type instance String The type instance name to associate with subsequent data values, e.g. "idle"
92 Values = 0x0006, // Values other Data values, see above
93 Interval = 0x0007, // Interval Numeric Interval used to set the "step" when creating new RRDs unless rrdtool plugin forces StepSize. Also used to detect values that have timed out.
94 IntervalHr = 0x0009, // Interval (high resolution) Numeric The interval in which subsequent data values are collected. The interval is given in 2–30 seconds. New in Version 5.0.
95 Message = 0x0100, // Message (notifications) String
96 Severity = 0x0101, // Severity Numeric
97 Signature = 0x0200, // Signature (HMAC-SHA-256) other (todo)
98 Encryption = 0x0210, // Encryption (AES-256/OFB
99 };
100
101 // "Time is defined in 2^–30 seconds since epoch. New in Version 5.0."
102 typedef std::chrono::duration<uint64_t, std::ratio<1, 0x40000000>> collectd_hres_duration;
103
104 // yet another writer type, this one to construct collectd network
105 // protocol data.
106 struct cpwriter {
107 typedef std::array<char, payload_size> buffer_type;
108 typedef buffer_type::iterator mark_type;
109 typedef buffer_type::const_iterator const_mark_type;
110
111 buffer_type _buf;
112 mark_type _pos;
113 bool _overflow = false;
114
115 std::unordered_map<uint16_t, sstring> _cache;
116
117 cpwriter()
118 : _pos(_buf.begin()) {
119 }
120 mark_type mark() const {
121 return _pos;
122 }
123 bool overflow() const {
124 return _overflow;
125 }
126 void reset(mark_type m) {
127 _pos = m;
128 _overflow = false;
129 }
130 size_t size() const {
131 return std::distance(_buf.begin(), const_mark_type(_pos));
132 }
133 bool empty() const {
134 return _pos == _buf.begin();
135 }
136 void clear() {
137 reset(_buf.begin());
138 _cache.clear();
139 _overflow = false;
140 }
141 const char * data() const {
142 return &_buf.at(0);
143 }
144 char * data() {
145 return &_buf.at(0);
146 }
147 cpwriter& check(size_t sz) {
148 size_t av = std::distance(_pos, _buf.end());
149 _overflow |= av < sz;
150 return *this;
151 }
152
153 sstring get_type_instance(const seastar::metrics::impl::metric_id & id) {
154 if (id.labels().empty()) {
155 return id.name();
156 }
157 sstring res = id.name();
158 for (auto i : id.labels()) {
159 if (i.first != seastar::metrics::shard_label.name() && i.first != seastar::metrics::type_label.name()) {
160 res += "-" + i.second;
161 }
162 }
163 return res;
164 }
165 explicit operator bool() const {
166 return !_overflow;
167 }
168 bool operator!() const {
169 return !operator bool();
170 }
171 template<typename _Iter>
172 cpwriter & write(_Iter s, _Iter e) {
173 if (check(std::distance(s, e))) {
174 _pos = std::copy(s, e, _pos);
175 }
176 return *this;
177 }
178 template<typename T>
179 typename std::enable_if<std::is_integral<T>::value, cpwriter &>::type write(
180 const T & t) {
181 T tmp = net::hton(t);
182 auto * p = reinterpret_cast<const uint8_t *>(&tmp);
183 auto * e = p + sizeof(T);
184 write(p, e);
185 return *this;
186 }
187 template<typename T>
188 typename std::enable_if<std::is_integral<T>::value, cpwriter &>::type write_le(const T & t) {
189 T tmp = cpu_to_le(t);
190 auto * p = reinterpret_cast<const uint8_t *>(&tmp);
191 auto * e = p + sizeof(T);
192 write(p, e);
193 return *this;
194 }
195 void write_value(const seastar::metrics::impl::metric_value& v) {
196 switch (v.type()) {
197 case data_type::GAUGE: {
198 double tmpd = v.d();
199 uint64_t tmpi;
200 std::copy_n(reinterpret_cast<const char*>(&tmpd), 8, reinterpret_cast<char*>(&tmpi));
201 write_le(tmpi);
202 break;
203 }
204 case data_type::COUNTER:
205 case data_type::DERIVE:
206 case data_type::ABSOLUTE:
207 write(v.ui()); // big endian
208 break;
209 default:
210 assert(0);
211 }
212 }
213 cpwriter & write(const sstring & s) {
214 write(s.begin(), s.end() + 1); // include \0
215 return *this;
216 }
217 cpwriter & put(part_type type, const sstring & s) {
218 write(uint16_t(type));
219 write(uint16_t(4 + s.size() + 1)); // include \0
220 write(s); // include \0
221 return *this;
222 }
223 cpwriter & put_cached(part_type type, const sstring & s) {
224 auto & cached = _cache[uint16_t(type)];
225 if (cached != s) {
226 put(type, s);
227 cached = s;
228 }
229 return *this;
230 }
231 template<typename T>
232 typename std::enable_if<std::is_integral<T>::value, cpwriter &>::type put(
233 part_type type, T t) {
234 write(uint16_t(type));
235 write(uint16_t(4 + sizeof(t)));
236 write(t);
237 return *this;
238 }
239 cpwriter & put(part_type type, const value_list & v) {
240 auto s = v.size();
241 auto sz = 6 + s + s * sizeof(uint64_t);
242 if (check(sz)) {
243 write(uint16_t(type));
244 write(uint16_t(sz));
245 write(uint16_t(s));
246 v.types(reinterpret_cast<data_type *>(&(*_pos)));
247 _pos += s;
248 v.values(reinterpret_cast<net::packed<uint64_t> *>(&(*_pos)));
249 _pos += s * sizeof(uint64_t);
250 }
251 return *this;
252 }
253
254 cpwriter & put(part_type type, const seastar::metrics::impl::metric_value & v) {
255 auto sz = 7 + sizeof(uint64_t);
256 if (check(sz)) {
257 write(uint16_t(type));
258 write(uint16_t(sz));
259 write(uint16_t(1));
260 write(static_cast<uint8_t>(v.type()));
261 write_value(v);
262 }
263 return *this;
264 }
265 cpwriter & put(const sstring & host, const seastar::metrics::impl::metric_id & id) {
266 const auto ts = std::chrono::system_clock::now().time_since_epoch();
267 const auto lrts =
268 std::chrono::duration_cast<std::chrono::seconds>(ts).count();
269
270 put_cached(part_type::Host, host);
271 put(part_type::Time, uint64_t(lrts));
272 // Seems hi-res timestamp does not work very well with
273 // at the very least my default collectd in fedora (or I did it wrong?)
274 // Use lo-res ts for now, it is probably quite sufficient.
275 put_cached(part_type::Plugin, id.group_name());
276 // Optional
277 put_cached(part_type::PluginInst,
278 id.instance_id() == per_cpu_plugin_instance ?
279 to_sstring(engine().cpu_id()) : id.instance_id());
280 put_cached(part_type::Type, id.inherit_type());
281 // Optional
282 put_cached(part_type::TypeInst, get_type_instance(id));
283 return *this;
284 }
285 cpwriter & put(const sstring & host,
286 const duration & period,
287 const type_instance_id & id, const value_list & v) {
288 const auto ps = std::chrono::duration_cast<collectd_hres_duration>(
289 period).count();
290 put(host, to_metrics_id(id));
291 put(part_type::Values, v);
292 if (ps != 0) {
293 put(part_type::IntervalHr, ps);
294 }
295 return *this;
296 }
297
298 cpwriter & put(const sstring & host,
299 const duration & period,
300 const seastar::metrics::impl::metric_id & id, const seastar::metrics::impl::metric_value & v) {
301 const auto ps = std::chrono::duration_cast<collectd_hres_duration>(
302 period).count();
303 put(host, id);
304 put(part_type::Values, v);
305 if (ps != 0) {
306 put(part_type::IntervalHr, ps);
307 }
308 return *this;
309 }
310 };
311
312 void impl::add_polled(const type_instance_id & id,
313 const shared_ptr<value_list> & values, bool enable) {
314 // do nothing
315 // add_polled is now implemented on the metrics layer
316
317 }
318
319 void impl::remove_polled(const type_instance_id & id) {
320 seastar::metrics::impl::unregister_metric(to_metrics_id(id));
321 }
322
323 // explicitly send a type_instance value list (outside polling)
324 future<> impl::send_metric(const type_instance_id & id,
325 const value_list & values) {
326 if (values.empty()) {
327 return make_ready_future();
328 }
329 cpwriter out;
330 out.put(_host, duration(), id, values);
331 return _chan.send(_addr, net::packet(out.data(), out.size()));
332 }
333
334 future<> impl::send_notification(const type_instance_id & id,
335 const sstring & msg) {
336 cpwriter out;
337 out.put(_host, to_metrics_id(id));
338 out.put(part_type::Message, msg);
339 return _chan.send(_addr, net::packet(out.data(), out.size()));
340 }
341
342 // initiates actual value polling -> send to target "loop"
343 void impl::start(const sstring & host, const ipv4_addr & addr, const duration period) {
344 _period = period;
345 _addr = addr;
346 _host = host;
347 _chan = engine().net().make_udp_channel();
348 _timer.set_callback(std::bind(&impl::run, this));
349
350 // dogfood ourselves
351 namespace sm = seastar::metrics;
352
353 _metrics.add_group("scollectd", {
354 // total_bytes value:DERIVE:0:U
355 sm::make_derive("total_bytes_sent", sm::description("total bytes sent"), _bytes),
356 // total_requests value:DERIVE:0:U
357 sm::make_derive("total_requests", sm::description("total requests"), _num_packets),
358 // latency value:GAUGE:0:U
359 sm::make_gauge("latency", sm::description("avrage latency"), _avg),
360 // total_time_in_ms value:DERIVE:0:U
361 sm::make_derive("total_time_in_ms", sm::description("total time in milliseconds"), _millis),
362 // total_values value:DERIVE:0:U
363 sm::make_gauge("total_values", sm::description("current number of values reported"), [this] {return values().size();}),
364 // records value:GAUGE:0:U
365 sm::make_gauge("records", sm::description("number of records reported"), [this] {return values().size();}),
366 });
367
368 send_notification(
369 type_instance_id("scollectd", per_cpu_plugin_instance,
370 "network"), "daemon started");
371 arm();
372 }
373
374 void impl::stop() {
375 _timer.cancel();
376 _metrics.clear();
377 }
378
379
380 void impl::arm() {
381 if (_period != duration()) {
382 _timer.arm(_period);
383 }
384 }
385
386 void impl::run() {
387 typedef size_t metric_family_id;
388 typedef seastar::metrics::impl::value_vector::iterator value_iterator;
389 typedef seastar::metrics::impl::metric_metadata_vector::iterator metadata_iterator;
390 typedef std::tuple<metric_family_id, metadata_iterator, value_iterator, cpwriter> context;
391
392 auto ctxt = make_lw_shared<context>();
393 foreign_ptr<shared_ptr<seastar::metrics::impl::values_copy>> vals = seastar::metrics::impl::get_values();
394
395 // note we're doing this unsynced since we assume
396 // all registrations to this instance will be done on the
397 // same cpu, and without interuptions (no wait-states)
398
399 auto& values = vals->values;
400 auto metadata = vals->metadata;
401 std::get<metric_family_id>(*ctxt) = 0;
402 if (values.size() > 0) {
403 std::get<value_iterator>(*ctxt) = values[0].begin();
404 std::get<metadata_iterator>(*ctxt) = metadata->at(0).metrics.begin();
405 }
406
407 auto stop_when = [ctxt, metadata]() {
408 auto done = std::get<metric_family_id>(*ctxt) == metadata->size();
409 return done;
410 };
411 // append as many values as we can fit into a packet (1024 bytes)
412 auto send_packet = [this, ctxt, &values, metadata]() mutable {
413 auto start = steady_clock_type::now();
414 auto& mf = std::get<metric_family_id>(*ctxt);
415 auto & md_iterator = std::get<metadata_iterator>(*ctxt);
416 auto & i = std::get<value_iterator>(*ctxt);
417 auto & out = std::get<cpwriter>(*ctxt);
418
419 out.clear();
420
421 bool out_of_space = false;
422 while (!out_of_space && mf < values.size()) {
423 while (i != values[mf].end()) {
424 if (i->type() == seastar::metrics::impl::data_type::HISTOGRAM) {
425 ++i;
426 ++md_iterator;
427 continue;
428 }
429 auto m = out.mark();
430 out.put(_host, _period, md_iterator->id, *i);
431 if (!out) {
432 out.reset(m);
433 out_of_space = true;
434 break;
435 }
436 ++i;
437 ++md_iterator;
438 }
439 if (out_of_space) {
440 break;
441 }
442 ++mf;
443 if (mf < values.size()) {
444 i = values[mf].begin();
445 md_iterator = metadata->at(mf).metrics.begin();
446 }
447 }
448 if (out.empty()) {
449 return make_ready_future();
450 }
451 return _chan.send(_addr, net::packet(out.data(), out.size())).then([start, ctxt, this]() {
452 auto & out = std::get<cpwriter>(*ctxt);
453 auto now = steady_clock_type::now();
454 // dogfood stats
455 ++_num_packets;
456 _millis += std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count();
457 _bytes += out.size();
458 _avg = double(_millis) / _num_packets;
459 }).then_wrapped([] (auto&& f) {
460 try {
461 f.get();
462 } catch (std::exception & ex) {
463 std::cout << "send failed: " << ex.what() << std::endl;
464 } catch (...) {
465 std::cout << "send failed: - unknown exception" << std::endl;
466 }
467 });
468 };
469 do_until(stop_when, send_packet).finally([this, vals = std::move(vals)]() mutable {
470 arm();
471 });
472 }
473
474 std::vector<type_instance_id> impl::get_instance_ids() const {
475 std::vector<type_instance_id> res;
476 for (auto&& v: values()) {
477 // Need to check for empty value_list, since unreg is two-stage.
478 // Not an issue for most uses, but unit testing etc that would like
479 // fully deterministic operation here would like us to only return
480 // actually active ids
481 for (auto i : v.second) {
482 if (i.second) {
483 res.emplace_back(i.second->get_id());
484 }
485 }
486 }
487 return res;
488 }
489
490 void add_polled(const type_instance_id & id,
491 const shared_ptr<value_list> & values, bool enabled) {
492 get_impl().add_polled(id, values, enabled);
493 }
494
495 void remove_polled_metric(const type_instance_id & id) {
496 get_impl().remove_polled(id);
497 }
498
499 future<> send_notification(const type_instance_id & id,
500 const sstring & msg) {
501 return get_impl().send_notification(id, msg);
502 }
503
504 future<> send_metric(const type_instance_id & id,
505 const value_list & values) {
506 return get_impl().send_metric(id, values);
507 }
508
509 void configure(const boost::program_options::variables_map & opts) {
510 bool enable = opts["collectd"].as<bool>();
511 if (!enable) {
512 return;
513 }
514 auto addr = ipv4_addr(opts["collectd-address"].as<std::string>());
515 auto period = std::chrono::milliseconds(opts["collectd-poll-period"].as<unsigned>());
516
517 auto host = (opts["collectd-hostname"].as<std::string>() == "")
518 ? seastar::metrics::impl::get_local_impl()->get_config().hostname
519 : sstring(opts["collectd-hostname"].as<std::string>());
520
521 // Now create send loops on each cpu
522 for (unsigned c = 0; c < smp::count; c++) {
523 smp::submit_to(c, [=] () {
524 get_impl().start(host, addr, period);
525 });
526 }
527 }
528
529 boost::program_options::options_description get_options_description() {
530 namespace bpo = boost::program_options;
531 bpo::options_description opts("COLLECTD options");
532 opts.add_options()("collectd", bpo::value<bool>()->default_value(false),
533 "enable collectd daemon")("collectd-address",
534 bpo::value<std::string>()->default_value("239.192.74.66:25826"),
535 "address to send/broadcast metrics to")("collectd-poll-period",
536 bpo::value<unsigned>()->default_value(1000),
537 "poll period - frequency of sending counter metrics (default: 1000ms, 0 disables)")(
538 "collectd-hostname",
539 bpo::value<std::string>()->default_value(""),
540 "Deprecated option, use metrics-hostname instead");
541 return opts;
542 }
543
544 static seastar::metrics::impl::register_ref get_register(const scollectd::type_instance_id& i) {
545 seastar::metrics::impl::metric_id id = to_metrics_id(i);
546 return seastar::metrics::impl::get_value_map().at(id.full_name()).at(id.labels());
547 }
548
549 std::vector<collectd_value> get_collectd_value(
550 const scollectd::type_instance_id& id) {
551 std::vector<collectd_value> vals;
552 const seastar::metrics::impl::registered_metric& val = *get_register(id);
553 vals.push_back(val());
554 return vals;
555 }
556
557 std::vector<scollectd::type_instance_id> get_collectd_ids() {
558 return get_impl().get_instance_ids();
559 }
560
561 bool is_enabled(const scollectd::type_instance_id& id) {
562 return get_register(id)->is_enabled();
563 }
564
565 void enable(const scollectd::type_instance_id& id, bool enable) {
566 get_register(id)->set_enabled(enable);
567 }
568
569 type_instance_id plugin_instance_metrics::add_impl(const typed_value& v) {
570 type_instance_id id(_plugin_id, _plugin_instance, v.type(), v.type_instance());
571 get_impl().add_polled(id, v.values());
572 return id;
573 }
574
575 void plugin_instance_metrics::add(const typed_value& v) {
576 _registrations.emplace_back(add_impl(v));
577 }
578
579 std::vector<type_instance_id> plugin_instance_metrics::bound_ids() const {
580 std::vector<type_instance_id> res;
581 res.reserve(_registrations.size());
582 std::transform(_registrations.begin(), _registrations.end(), std::back_inserter(res), [](const registration& r) {
583 return r._id;
584 });
585 return res;
586 }
587
588 type_id type_id_for(known_type t) {
589 switch (t) {
590 case known_type::absolute:
591 return "absolute";
592 case known_type::backends:
593 return "backends";
594 case known_type::bitrate:
595 return "bitrate";
596 case known_type::blocked_clients:
597 return "blocked_clients";
598 case known_type::bytes:
599 return "bytes";
600 case known_type::cache_eviction:
601 return "cache_eviction";
602 case known_type::cache_operation:
603 return "cache_operation";
604 case known_type::cache_ratio:
605 return "cache_ratio";
606 case known_type::cache_result:
607 return "cache_result";
608 case known_type::cache_size:
609 return "cache_size";
610 case known_type::capacity:
611 return "capacity";
612 case known_type::changes_since_last_save:
613 return "changes_since_last_save";
614 case known_type::charge:
615 return "charge";
616 case known_type::clock_last_meas:
617 return "clock_last_meas";
618 case known_type::clock_last_update:
619 return "clock_last_update";
620 case known_type::clock_mode:
621 return "clock_mode";
622 case known_type::clock_reachability:
623 return "clock_reachability";
624 case known_type::clock_skew_ppm:
625 return "clock_skew_ppm";
626 case known_type::clock_state:
627 return "clock_state";
628 case known_type::clock_stratum:
629 return "clock_stratum";
630 case known_type::compression:
631 return "compression";
632 case known_type::compression_ratio:
633 return "compression_ratio";
634 case known_type::connections:
635 return "connections";
636 case known_type::conntrack:
637 return "conntrack";
638 case known_type::contextswitch:
639 return "contextswitch";
640 case known_type::count:
641 return "count";
642 case known_type::counter:
643 return "counter";
644 case known_type::cpu:
645 return "cpu";
646 case known_type::cpufreq:
647 return "cpufreq";
648 case known_type::current:
649 return "current";
650 case known_type::current_connections:
651 return "current_connections";
652 case known_type::current_sessions:
653 return "current_sessions";
654 case known_type::delay:
655 return "delay";
656 case known_type::derive:
657 return "derive";
658 case known_type::df:
659 return "df";
660 case known_type::df_complex:
661 return "df_complex";
662 case known_type::df_inodes:
663 return "df_inodes";
664 case known_type::disk_io_time:
665 return "disk_io_time";
666 case known_type::disk_latency:
667 return "disk_latency";
668 case known_type::disk_merged:
669 return "disk_merged";
670 case known_type::disk_octets:
671 return "disk_octets";
672 case known_type::disk_ops:
673 return "disk_ops";
674 case known_type::disk_ops_complex:
675 return "disk_ops_complex";
676 case known_type::disk_time:
677 return "disk_time";
678 case known_type::dns_answer:
679 return "dns_answer";
680 case known_type::dns_notify:
681 return "dns_notify";
682 case known_type::dns_octets:
683 return "dns_octets";
684 case known_type::dns_opcode:
685 return "dns_opcode";
686 case known_type::dns_qtype:
687 return "dns_qtype";
688 case known_type::dns_qtype_cached:
689 return "dns_qtype_cached";
690 case known_type::dns_query:
691 return "dns_query";
692 case known_type::dns_question:
693 return "dns_question";
694 case known_type::dns_rcode:
695 return "dns_rcode";
696 case known_type::dns_reject:
697 return "dns_reject";
698 case known_type::dns_request:
699 return "dns_request";
700 case known_type::dns_resolver:
701 return "dns_resolver";
702 case known_type::dns_response:
703 return "dns_response";
704 case known_type::dns_transfer:
705 return "dns_transfer";
706 case known_type::dns_update:
707 return "dns_update";
708 case known_type::dns_zops:
709 return "dns_zops";
710 case known_type::drbd_resource:
711 return "drbd_resource";
712 case known_type::duration:
713 return "duration";
714 case known_type::email_check:
715 return "email_check";
716 case known_type::email_count:
717 return "email_count";
718 case known_type::email_size:
719 return "email_size";
720 case known_type::entropy:
721 return "entropy";
722 case known_type::evicted_keys:
723 return "evicted_keys";
724 case known_type::expired_keys:
725 return "expired_keys";
726 case known_type::fanspeed:
727 return "fanspeed";
728 case known_type::file_handles:
729 return "file_handles";
730 case known_type::file_size:
731 return "file_size";
732 case known_type::files:
733 return "files";
734 case known_type::flow:
735 return "flow";
736 case known_type::fork_rate:
737 return "fork_rate";
738 case known_type::frequency:
739 return "frequency";
740 case known_type::frequency_error:
741 return "frequency_error";
742 case known_type::frequency_offset:
743 return "frequency_offset";
744 case known_type::fscache_stat:
745 return "fscache_stat";
746 case known_type::gauge:
747 return "gauge";
748 case known_type::hash_collisions:
749 return "hash_collisions";
750 case known_type::http_request_methods:
751 return "http_request_methods";
752 case known_type::http_requests:
753 return "http_requests";
754 case known_type::http_response_codes:
755 return "http_response_codes";
756 case known_type::humidity:
757 return "humidity";
758 case known_type::if_collisions:
759 return "if_collisions";
760 case known_type::if_dropped:
761 return "if_dropped";
762 case known_type::if_errors:
763 return "if_errors";
764 case known_type::if_multicast:
765 return "if_multicast";
766 case known_type::if_octets:
767 return "if_octets";
768 case known_type::if_packets:
769 return "if_packets";
770 case known_type::if_rx_errors:
771 return "if_rx_errors";
772 case known_type::if_rx_octets:
773 return "if_rx_octets";
774 case known_type::if_tx_errors:
775 return "if_tx_errors";
776 case known_type::if_tx_octets:
777 return "if_tx_octets";
778 case known_type::invocations:
779 return "invocations";
780 case known_type::io_octets:
781 return "io_octets";
782 case known_type::io_packets:
783 return "io_packets";
784 case known_type::ipt_bytes:
785 return "ipt_bytes";
786 case known_type::ipt_packets:
787 return "ipt_packets";
788 case known_type::irq:
789 return "irq";
790 case known_type::latency:
791 return "latency";
792 case known_type::links:
793 return "links";
794 case known_type::load:
795 return "load";
796 case known_type::md_disks:
797 return "md_disks";
798 case known_type::memory:
799 return "memory";
800 case known_type::memory_lua:
801 return "memory_lua";
802 case known_type::memory_throttle_count:
803 return "memory_throttle_count";
804 case known_type::multimeter:
805 return "multimeter";
806 case known_type::mutex_operations:
807 return "mutex_operations";
808 case known_type::objects:
809 return "objects";
810 case known_type::operations:
811 return "operations";
812 case known_type::packets:
813 return "packets";
814 case known_type::pending_operations:
815 return "pending_operations";
816 case known_type::percent:
817 return "percent";
818 case known_type::percent_bytes:
819 return "percent_bytes";
820 case known_type::percent_inodes:
821 return "percent_inodes";
822 case known_type::ping:
823 return "ping";
824 case known_type::ping_droprate:
825 return "ping_droprate";
826 case known_type::ping_stddev:
827 return "ping_stddev";
828 case known_type::players:
829 return "players";
830 case known_type::power:
831 return "power";
832 case known_type::pressure:
833 return "pressure";
834 case known_type::protocol_counter:
835 return "protocol_counter";
836 case known_type::pubsub:
837 return "pubsub";
838 case known_type::queue_length:
839 return "queue_length";
840 case known_type::records:
841 return "records";
842 case known_type::requests:
843 return "requests";
844 case known_type::response_code:
845 return "response_code";
846 case known_type::response_time:
847 return "response_time";
848 case known_type::root_delay:
849 return "root_delay";
850 case known_type::root_dispersion:
851 return "root_dispersion";
852 case known_type::route_etx:
853 return "route_etx";
854 case known_type::route_metric:
855 return "route_metric";
856 case known_type::routes:
857 return "routes";
858 case known_type::segments:
859 return "segments";
860 case known_type::serial_octets:
861 return "serial_octets";
862 case known_type::signal_noise:
863 return "signal_noise";
864 case known_type::signal_power:
865 return "signal_power";
866 case known_type::signal_quality:
867 return "signal_quality";
868 case known_type::snr:
869 return "snr";
870 case known_type::spl:
871 return "spl";
872 case known_type::swap:
873 return "swap";
874 case known_type::swap_io:
875 return "swap_io";
876 case known_type::tcp_connections:
877 return "tcp_connections";
878 case known_type::temperature:
879 return "temperature";
880 case known_type::threads:
881 return "threads";
882 case known_type::time_dispersion:
883 return "time_dispersion";
884 case known_type::time_offset:
885 return "time_offset";
886 case known_type::time_offset_ntp:
887 return "time_offset_ntp";
888 case known_type::time_offset_rms:
889 return "time_offset_rms";
890 case known_type::time_ref:
891 return "time_ref";
892 case known_type::timeleft:
893 return "timeleft";
894 case known_type::total_bytes:
895 return "total_bytes";
896 case known_type::total_connections:
897 return "total_connections";
898 case known_type::total_objects:
899 return "total_objects";
900 case known_type::total_operations:
901 return "total_operations";
902 case known_type::total_requests:
903 return "total_requests";
904 case known_type::total_sessions:
905 return "total_sessions";
906 case known_type::total_threads:
907 return "total_threads";
908 case known_type::total_time_in_ms:
909 return "total_time_in_ms";
910 case known_type::total_values:
911 return "total_values";
912 case known_type::uptime:
913 return "uptime";
914 case known_type::users:
915 return "users";
916 case known_type::vcl:
917 return "vcl";
918 case known_type::vcpu:
919 return "vcpu";
920 case known_type::virt_cpu_total:
921 return "virt_cpu_total";
922 case known_type::virt_vcpu:
923 return "virt_vcpu";
924 case known_type::vmpage_action:
925 return "vmpage_action";
926 case known_type::vmpage_faults:
927 return "vmpage_faults";
928 case known_type::vmpage_io:
929 return "vmpage_io";
930 case known_type::vmpage_number:
931 return "vmpage_number";
932 case known_type::volatile_changes:
933 return "volatile_changes";
934 case known_type::voltage:
935 return "voltage";
936 case known_type::voltage_threshold:
937 return "voltage_threshold";
938 case known_type::vs_memory:
939 return "vs_memory";
940 case known_type::vs_processes:
941 return "vs_processes";
942 case known_type::vs_threads:
943 return "vs_threads";
944 default:
945 throw std::invalid_argument("Unknown type");
946 }
947 }
948
949 metrics::impl::value_map get_value_map() {
950 return metrics::impl::get_value_map();
951 }
952
953 }
954
955 }