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