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