]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/include/seastar/core/scollectd.hh
import 15.2.0 Octopus source
[ceph.git] / ceph / src / seastar / include / seastar / core / scollectd.hh
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 #pragma once
23
24 #include <type_traits>
25 #include <utility>
26 #include <functional>
27 #include <array>
28 #include <iterator>
29 #include <stdint.h>
30 #include <memory>
31 #include <string>
32 #include <tuple>
33 #include <chrono>
34 #include <boost/program_options.hpp>
35
36 #include <seastar/core/future.hh>
37 #include <seastar/net/byteorder.hh>
38 #include <seastar/core/shared_ptr.hh>
39 #include <seastar/core/sstring.hh>
40 #include <seastar/util/log.hh>
41
42 #include <seastar/core/metrics_api.hh>
43
44 namespace seastar {
45
46 /**
47 * Implementation of rudimentary collectd data gathering.
48 *
49 * Usage is hopefully straight forward. Though, feel free to read
50 * https://collectd.org/wiki/index.php/Naming_schema
51 * for an explanation on the naming model.
52 *
53 * Typically, you'll add values something like:
54 *
55 * scollectd::type_instance_id typ("<pluginname>", "<instance_name>", "<type_name>", "<instance_name>");
56 * scollectd::add_polled_metric(typ, [<metric var> | scollectd::make_typed(<data_type>, <metric_var>) [, ...]);
57 *
58 * Where
59 * <pluginname> would be the overall 'module', e.g. "cpu"
60 * <instance_name> -> optional distinguisher between plugin instances. For cpu, the built-in
61 * scollectd::per_cpu_plugin_instance constant is a good choice, i.e. 0->N cpu.
62 * If there are no instances (e.g. only one), empty constant is appropriate (none)
63 * <type_name> is the 'type' of metric collected, for ex. "usage" (cpu/0/usage)
64 * <type_instance> is a distinguisher for metric parts of the type, e.g. "idle", "user", "kernel"
65 * -> cpu/0/usage/idle | cpu/0/usage/user | cpu/0/usage/kernel
66 *
67 * Each type instance can bind an arbitrary number of values, ech representing some aspect in turn of the instance.
68 * The structure and interpretation is up to the producer/consumer
69 *
70 * There is a single "scollectd" instance per cpu, and values should be bound locally
71 * to this cpu. Polling is done at a frequency set in the seastar config (def once per s),
72 * and all registered values will be sent via UDP packages to the destination host(s)
73 *
74 * Note that the tuple { plugin, plugin_instance, type, type_instance } is considered a
75 * unique ID for a value registration, so using the same tuple twice will remove the previously
76 * registered values.
77 *
78 * Values can be unregistered at any time, though they must be so on the same thread/cpu
79 * as they we're registered. The "registration" achor type provides RAII style value unregistration
80 * semantics.
81 *
82 */
83
84 namespace scollectd {
85
86 extern seastar::logger logger;
87
88 using data_type = seastar::metrics::impl::data_type;
89
90 enum class known_type {
91 // from types.db. Defined collectd types (type_id) selection.
92 // This enum omits the very application specific types, such
93 // as mysql_* etc, since if you really are re-writing mysql
94 // in seastar, you probably know how to look the type up manually...
95
96 absolute,
97 backends,
98 bitrate,
99 blocked_clients,
100 bytes,
101 cache_eviction,
102 cache_operation,
103 cache_ratio,
104 cache_result,
105 cache_size,
106 capacity,
107 changes_since_last_save,
108 charge,
109 clock_last_meas,
110 clock_last_update,
111 clock_mode,
112 clock_reachability,
113 clock_skew_ppm,
114 clock_state,
115 clock_stratum,
116 compression,
117 compression_ratio,
118 connections,
119 conntrack,
120 contextswitch,
121 count,
122 counter,
123 cpu,
124 cpufreq,
125 current,
126 current_connections,
127 current_sessions,
128 delay,
129 derive,
130 df,
131 df_complex,
132 df_inodes,
133 disk_io_time,
134 disk_latency,
135 disk_merged,
136 disk_octets,
137 disk_ops,
138 disk_ops_complex,
139 disk_time,
140 dns_answer,
141 dns_notify,
142 dns_octets,
143 dns_opcode,
144 dns_qtype,
145 dns_qtype_cached,
146 dns_query,
147 dns_question,
148 dns_rcode,
149 dns_reject,
150 dns_request,
151 dns_resolver,
152 dns_response,
153 dns_transfer,
154 dns_update,
155 dns_zops,
156 drbd_resource,
157 duration,
158 email_check,
159 email_count,
160 email_size,
161 entropy,
162 evicted_keys,
163 expired_keys,
164 fanspeed,
165 file_handles,
166 file_size,
167 files,
168 flow,
169 fork_rate,
170 frequency,
171 frequency_error,
172 frequency_offset,
173 fscache_stat,
174 gauge,
175 hash_collisions,
176 http_request_methods,
177 http_requests,
178 http_response_codes,
179 humidity,
180 if_collisions,
181 if_dropped,
182 if_errors,
183 if_multicast,
184 if_octets,
185 if_packets,
186 if_rx_errors,
187 if_rx_octets,
188 if_tx_errors,
189 if_tx_octets,
190 invocations,
191 io_octets,
192 io_packets,
193 ipt_bytes,
194 ipt_packets,
195 irq,
196 latency,
197 links,
198 load,
199 md_disks,
200 memory,
201 memory_lua,
202 memory_throttle_count,
203 multimeter,
204 mutex_operations,
205 objects,
206 operations,
207 packets,
208 pending_operations,
209 percent,
210 percent_bytes,
211 percent_inodes,
212 ping,
213 ping_droprate,
214 ping_stddev,
215 players,
216 power,
217 pressure,
218 protocol_counter,
219 pubsub,
220 queue_length,
221 records,
222 requests,
223 response_code,
224 response_time,
225 root_delay,
226 root_dispersion,
227 route_etx,
228 route_metric,
229 routes,
230 segments,
231 serial_octets,
232 signal_noise,
233 signal_power,
234 signal_quality,
235 snr,
236 spl,
237 swap,
238 swap_io,
239 tcp_connections,
240 temperature,
241 threads,
242 time_dispersion,
243 time_offset,
244 time_offset_ntp,
245 time_offset_rms,
246 time_ref,
247 timeleft,
248 total_bytes,
249 total_connections,
250 total_objects,
251 total_operations,
252 total_requests,
253 total_sessions,
254 total_threads,
255 total_time_in_ms,
256 total_values,
257 uptime,
258 users,
259 vcl,
260 vcpu,
261 virt_cpu_total,
262 virt_vcpu,
263 vmpage_action,
264 vmpage_faults,
265 vmpage_io,
266 vmpage_number,
267 volatile_changes,
268 voltage,
269 voltage_threshold,
270 vs_memory,
271 vs_processes,
272 vs_threads,
273 };
274
275 // don't use directly. use make_typed.
276 template<typename T>
277 struct typed {
278 typed(data_type t, T && v)
279 : type(t), value(std::forward<T>(v)) {
280 }
281 data_type type;
282 T value;
283 };
284
285 template<typename T>
286 static inline typed<T> make_typed(data_type type, T&& t) {
287 return typed<T>(type, std::forward<T>(t));
288 }
289
290 using plugin_id = seastar::metrics::group_name_type;
291 using plugin_instance_id = seastar::metrics::instance_id_type;
292 using type_id = seastar::metrics::metric_type_def;
293 using type_instance = seastar::metrics::metric_name_type;
294
295 type_id type_id_for(known_type);
296
297 using description = seastar::metrics::description;
298
299 static constexpr unsigned max_collectd_field_text_len = 63;
300
301 class type_instance_id {
302 static thread_local unsigned _next_truncated_idx;
303
304 /// truncate a given field to the maximum allowed length
305 void truncate(sstring& field, const char* field_desc);
306 public:
307 type_instance_id() = default;
308 type_instance_id(plugin_id p, plugin_instance_id pi, type_id t,
309 scollectd::type_instance ti = std::string())
310 : _plugin(std::move(p)), _plugin_instance(std::move(pi)), _type(
311 std::move(t)), _type_instance(std::move(ti)) {
312 // truncate strings to the maximum allowed length
313 truncate(_plugin, "plugin");
314 truncate(_plugin_instance, "plugin_instance");
315 truncate(_type, "type");
316 truncate(_type_instance, "type_instance");
317 }
318 type_instance_id(const seastar::metrics::impl::metric_id &id) : _plugin(id.group_name()),
319 _plugin_instance(id.instance_id()), _type(id.inherit_type()),
320 _type_instance(id.name()) {
321 }
322 type_instance_id(type_instance_id &&) = default;
323 type_instance_id(const type_instance_id &) = default;
324
325 type_instance_id & operator=(type_instance_id &&) = default;
326 type_instance_id & operator=(const type_instance_id &) = default;
327
328 const plugin_id & plugin() const {
329 return _plugin;
330 }
331 const plugin_instance_id & plugin_instance() const {
332 return _plugin_instance;
333 }
334 const type_id & type() const {
335 return _type;
336 }
337 const scollectd::type_instance & type_instance() const {
338 return _type_instance;
339 }
340 bool operator<(const type_instance_id&) const;
341 bool operator==(const type_instance_id&) const;
342 private:
343 plugin_id _plugin;
344 plugin_instance_id _plugin_instance;
345 type_id _type;
346 scollectd::type_instance _type_instance;
347 };
348
349 extern const plugin_instance_id per_cpu_plugin_instance;
350
351 void configure(const boost::program_options::variables_map&);
352 boost::program_options::options_description get_options_description();
353 void remove_polled_metric(const type_instance_id &);
354
355 class plugin_instance_metrics;
356
357 /**
358 * Anchor for polled registration.
359 * Iff the registered type is in some way none-persistent,
360 * use this as receiver of the reg and ensure it dies before the
361 * added value(s).
362 *
363 * Use:
364 * uint64_t v = 0;
365 * registration r = add_polled_metric(v);
366 * ++r;
367 * <scope end, above dies>
368 */
369 struct registration {
370 registration() = default;
371 registration(const type_instance_id& id);
372 registration(type_instance_id&& id);
373 registration(const registration&) = delete;
374 registration(registration&&) = default;
375 ~registration();
376 registration & operator=(const registration&) = delete;
377 registration & operator=(registration&&) = default;
378
379 void unregister() {
380 remove_polled_metric(_id);
381 _id = type_instance_id();
382 }
383 private:
384 friend class plugin_instance_metrics;
385 type_instance_id _id;
386 shared_ptr<seastar::metrics::impl::impl> _impl;
387 };
388
389 /**
390 * Helper type to make generating vectors of registration objects
391 * easier, since it constructs from an initializer list of
392 * type_instance_id:s, avoiding early conversion to registration objs,
393 * which in case of init lists, are copy semantics, not move...
394 */
395 class registrations
396 : public std::vector<registration>
397 {
398 public:
399 typedef std::vector<registration> vector_type;
400
401 registrations()
402 {}
403 registrations(vector_type&& v) : vector_type(std::move(v))
404 {}
405 registrations(const std::initializer_list<type_instance_id>& l)
406 : vector_type(l.begin(),l.end())
407 {}
408 registrations& operator=(vector_type&& v) {
409 vector_type::operator=(std::move(v));
410 return *this;
411 }
412 registrations& operator=(const std::initializer_list<type_instance_id>& l) {
413 return registrations::operator=(registrations(l));
414 }
415 };
416
417 class value_list;
418
419 struct typed_value {
420 /**
421 * Wraps N values of a given type (type_id).
422 * Used to group types into a plugin_instance_metrics
423 */
424 template<typename... Args>
425 typed_value(const type_id& tid, const scollectd::type_instance& ti, description, Args&&... args);
426
427 template<typename... Args>
428 typed_value(const type_id& tid, const scollectd::type_instance& ti, Args&&... args)
429 : typed_value(tid, ti, description(), std::forward<Args>(args)...)
430 {}
431
432 const scollectd::type_instance& type_instance() const {
433 return _type_instance;
434 }
435 const shared_ptr<value_list>& values() const {
436 return _values;
437 }
438 const type_id & type() const {
439 return _type_id;
440 }
441 private:
442 type_id _type_id;
443 scollectd::type_instance _type_instance;
444 shared_ptr<value_list> _values;
445 };
446
447 class plugin_instance_metrics {
448 public:
449 template<typename... TypedValues>
450 plugin_instance_metrics(const plugin_id& p, const plugin_instance_id& pi, TypedValues&&... values)
451 : _plugin_id(p)
452 , _plugin_instance(pi)
453 , _registrations({ add_impl(values)... })
454 {}
455 std::vector<type_instance_id> bound_ids() const;
456 void add(const typed_value&);
457 private:
458 type_instance_id add_impl(const typed_value&);
459
460 plugin_id _plugin_id;
461 plugin_instance_id _plugin_instance;
462 registrations _registrations;
463 };
464
465 /**
466 * Simplified wrapper for the common case of per-cpu plugin instances
467 * (i.e. distributed objects)
468 */
469 class percpu_plugin_instance_metrics : public plugin_instance_metrics {
470 public:
471 template<typename... TypedValues>
472 percpu_plugin_instance_metrics(const plugin_id& p, TypedValues&&... values)
473 : plugin_instance_metrics(p, per_cpu_plugin_instance, std::forward<TypedValues>(values)...)
474 {}
475 };
476
477 /**
478 * Template wrapper for type_id values, deriving type_id string
479 * from the known_types enum, for auto-completetion joy.
480 */
481 template<known_type Type>
482 struct typed_value_impl: public typed_value {
483 template<typename ... Args>
484 typed_value_impl(const scollectd::type_instance& ti, Args&& ... args)
485 : typed_value(type_id_for(Type), ti, std::forward<Args>(args)...)
486 {}
487
488 template<typename ... Args>
489 typed_value_impl(scollectd::type_instance ti, description d, Args&& ... args)
490 : typed_value(type_id_for(Type), std::move(ti), std::move(d), std::forward<Args>(args)...)
491 {}
492 template<typename ... Args>
493 typed_value_impl(description d, Args&& ... args)
494 : typed_value(type_id_for(Type), scollectd::type_instance(), std::move(d), std::forward<Args>(args)...)
495 {}
496 };
497
498 /*!
499 * \deprecated metrics registration should be done using the metrics layer
500 *
501 * Some typedefs for common used types. Feel free to add.
502 */
503 typedef typed_value_impl<known_type::total_bytes> total_bytes;
504 typedef typed_value_impl<known_type::total_connections> total_connections;
505 typedef typed_value_impl<known_type::total_objects> total_objects;
506 typedef typed_value_impl<known_type::total_operations> total_operations;
507 typedef typed_value_impl<known_type::total_requests> total_requests;
508 typedef typed_value_impl<known_type::total_sessions> total_sessions;
509 typedef typed_value_impl<known_type::total_threads> total_threads;
510 typedef typed_value_impl<known_type::total_time_in_ms> total_time_in_ms;
511 typedef typed_value_impl<known_type::total_values> total_values;
512 typedef typed_value_impl<known_type::queue_length> queue_length;
513 typedef typed_value_impl<known_type::counter> counter;
514 typedef typed_value_impl<known_type::count> count;
515 typedef typed_value_impl<known_type::gauge> gauge;
516
517 // lots of template junk to build typed value list tuples
518 // for registered values.
519 template<typename T, typename En = void>
520 struct data_type_for;
521
522 template<typename T, typename En = void>
523 struct is_callable;
524
525 template<typename T>
526 struct is_callable<T,
527 typename std::enable_if<
528 !std::is_void<typename std::result_of<T()>::type>::value,
529 void>::type> : public std::true_type {
530 };
531
532 template<typename T>
533 struct is_callable<T,
534 typename std::enable_if<std::is_fundamental<T>::value, void>::type> : public std::false_type {
535 };
536
537 template<typename T>
538 struct data_type_for<T,
539 typename std::enable_if<
540 std::is_integral<T>::value && std::is_unsigned<T>::value,
541 void>::type> : public std::integral_constant<data_type,
542 data_type::COUNTER> {
543 };
544 template<typename T>
545 struct data_type_for<T,
546 typename std::enable_if<
547 std::is_integral<T>::value && std::is_signed<T>::value, void>::type> : public std::integral_constant<
548 data_type, data_type::DERIVE> {
549 };
550 template<typename T>
551 struct data_type_for<T,
552 typename std::enable_if<std::is_floating_point<T>::value, void>::type> : public std::integral_constant<
553 data_type, data_type::GAUGE> {
554 };
555 template<typename T>
556 struct data_type_for<T,
557 typename std::enable_if<is_callable<T>::value, void>::type> : public data_type_for<
558 typename std::result_of<T()>::type> {
559 };
560 template<typename T>
561 struct data_type_for<typed<T>> : public data_type_for<T> {
562 };
563
564 template<typename T>
565 class value {
566 public:
567 template<typename W>
568 struct wrap {
569 wrap(const W & v)
570 : _v(v) {
571 }
572 const W & operator()() const {
573 return _v;
574 }
575 const W & _v;
576 };
577
578 typedef typename std::remove_reference<T>::type value_type;
579 typedef typename std::conditional<
580 is_callable<typename std::remove_reference<T>::type>::value,
581 value_type, wrap<value_type> >::type stored_type;
582
583 value(const value_type & t)
584 : value<T>(data_type_for<value_type>::value, t) {
585 }
586 value(data_type type, const value_type & t)
587 : _type(type), _t(t) {
588 }
589 uint64_t operator()() const {
590 auto v = _t();
591 if (_type == data_type::GAUGE) {
592 return convert(double(v));
593 } else {
594 uint64_t u = v;
595 return convert(u);
596 }
597 }
598 operator uint64_t() const {
599 return (*this)();
600 }
601 operator data_type() const {
602 return _type;
603 }
604 data_type type() const {
605 return _type;
606 }
607 private:
608 // not super quick value -> protocol endian 64-bit values.
609 template<typename _Iter>
610 void bpack(_Iter s, _Iter e, uint64_t v) const {
611 while (s != e) {
612 *s++ = (v & 0xff);
613 v >>= 8;
614 }
615 }
616 template<typename V>
617 typename std::enable_if<std::is_integral<V>::value, uint64_t>::type convert(
618 V v) const {
619 uint64_t i = v;
620 // network byte order
621 return ntohq(i);
622 }
623 template<typename V>
624 typename std::enable_if<std::is_floating_point<V>::value, uint64_t>::type convert(
625 V t) const {
626 union {
627 uint64_t i;
628 double v;
629 } v;
630 union {
631 uint64_t i;
632 uint8_t b[8];
633 } u;
634 v.v = t;
635 // intel byte order. could also obviously be faster.
636 // could be ignored if we just assume we're le (for now),
637 // but this is ok me thinks.
638 bpack(std::begin(u.b), std::end(u.b), v.i);
639 return u.i;
640 }
641 ;
642
643 const data_type _type;
644 const stored_type _t;
645 };
646
647 template<typename T>
648 class value<typed<T>> : public value<T> {
649 public:
650 value(const typed<T> & args)
651 : value<T>(args.type, args.value) {
652 }
653 };
654
655 class value_list {
656 bool _enabled = true;
657 public:
658 value_list(description d) : _description(std::move(d))
659 {}
660 value_list(value_list&&) = default;
661 virtual ~value_list() {}
662
663 virtual size_t size() const = 0;
664
665 virtual void types(data_type *) const = 0;
666 virtual void values(net::packed<uint64_t> *) const = 0;
667
668 const description& desc() const {
669 return _description;
670 }
671
672 bool empty() const {
673 return size() == 0;
674 }
675
676 bool is_enabled() const {
677 return _enabled;
678 }
679
680 void set_enabled(bool b) {
681 _enabled = b;
682 }
683 private:
684 description _description;
685 };
686
687 template<typename ... Args>
688 class values_impl: public value_list {
689 public:
690 static const size_t num_values = sizeof...(Args);
691
692 values_impl(description d, Args&& ...args)
693 : value_list(std::move(d))
694 , _values(std::forward<Args>(args)...)
695 {}
696
697 values_impl(values_impl<Args...>&& a) = default;
698 values_impl(const values_impl<Args...>& a) = default;
699
700 size_t size() const override {
701 return num_values;
702 }
703 void types(data_type * p) const override {
704 unpack(_values, [p](Args... args) {
705 std::initializer_list<data_type> tmp = { args... };
706 std::copy(tmp.begin(), tmp.end(), p);
707 });
708 }
709 void values(net::packed<uint64_t> * p) const override {
710 unpack(_values, [p](Args... args) {
711 std::initializer_list<uint64_t> tmp = { args... };
712 std::copy(tmp.begin(), tmp.end(), p);
713 });
714 }
715 private:
716 template<typename _Op>
717 void unpack(const std::tuple<Args...>& t, _Op&& op) const {
718 do_unpack(t, std::index_sequence_for<Args...> {}, std::forward<_Op>(op));
719 }
720
721 template<size_t ...S, typename _Op>
722 void do_unpack(const std::tuple<Args...>& t, const std::index_sequence<S...> &, _Op&& op) const {
723 op(std::get<S>(t)...);
724 }
725
726 std::tuple < Args... > _values;
727 };
728
729 void add_polled(const type_instance_id &, const shared_ptr<value_list> &, bool enabled = true);
730
731 typedef std::function<void()> notify_function;
732 template<typename... _Args>
733 static auto make_type_instance(description d, _Args && ... args) -> values_impl < decltype(value<_Args>(std::forward<_Args>(args)))... >
734 {
735 return values_impl<decltype(value<_Args>(std::forward<_Args>(args)))...>(
736 std::move(d), value<_Args>(std::forward<_Args>(args))...);
737 }
738 /*!
739 * \deprecated metrics registration should be done using the metrics layer
740 *
741 */
742 template<typename ... _Args>
743 [[deprecated("Use the metrics layer")]] static type_instance_id add_polled_metric(const plugin_id & plugin,
744 const plugin_instance_id & plugin_instance, const type_id & type,
745 const scollectd::type_instance & type_instance, _Args&& ... args) {
746 return add_polled_metric(plugin, plugin_instance, type, type_instance, description(),
747 std::forward<_Args>(args)...);
748 }
749 /*!
750 * \deprecated metrics registration should be done using the metrics layer
751 *
752 */
753 template<typename ... _Args>
754 [[deprecated("Use the metrics layer")]] static type_instance_id add_polled_metric(const plugin_id & plugin,
755 const plugin_instance_id & plugin_instance, const type_id & type,
756 const scollectd::type_instance & type_instance, description d, _Args&& ... args) {
757 return add_polled_metric(
758 type_instance_id(plugin, plugin_instance, type, type_instance), std::move(d),
759 std::forward<_Args>(args)...);
760 }
761 template<typename ... _Args>
762 static future<> send_explicit_metric(const plugin_id & plugin,
763 const plugin_instance_id & plugin_instance, const type_id & type,
764 const scollectd::type_instance & type_instance, _Args&& ... args) {
765 return send_explicit_metric(
766 type_instance_id(plugin, plugin_instance, type, type_instance),
767 std::forward<_Args>(args)...);
768 }
769 template<typename ... _Args>
770 static notify_function create_explicit_metric(const plugin_id & plugin,
771 const plugin_instance_id & plugin_instance, const type_id & type,
772 const scollectd::type_instance & type_instance, _Args&& ... args) {
773 return create_explicit_metric(
774 type_instance_id(plugin, plugin_instance, type, type_instance),
775 std::forward<_Args>(args)...);
776 }
777
778 seastar::metrics::impl::metric_id to_metrics_id(const type_instance_id & id);
779 /*!
780 * \deprecated metrics registration should be done using the metrics layer
781 *
782 */
783 template<typename Arg>
784 [[deprecated("Use the metrics layer")]] static type_instance_id add_polled_metric(const type_instance_id & id, description d,
785 Arg&& arg, bool enabled = true) {
786 namespace sm = seastar::metrics::impl;
787
788 seastar::metrics::impl::get_local_impl()->add_registration(to_metrics_id(id), arg.type, sm::make_function(arg.value, arg.type), d, enabled);
789 return id;
790 }
791 /*!
792 * \deprecated metrics registration should be done using the metrics layer
793 *
794 */
795 template<typename Arg>
796 [[deprecated("Use the metrics layer")]] static type_instance_id add_polled_metric(const type_instance_id & id,
797 Arg&& arg) {
798 return std::move(add_polled_metric(id, description(), std::forward<Arg>(arg)));
799 }
800
801 /*!
802 * \deprecated metrics registration should be done using the metrics layer
803 *
804 */
805 template<typename Args>
806 [[deprecated("Use the metrics layer")]] static type_instance_id add_disabled_polled_metric(const type_instance_id & id, description d,
807 Args&& arg) {
808 return add_polled_metric(id, d, std::forward<Args>(arg), false);
809 }
810
811 template<typename Args>
812 static type_instance_id add_disabled_polled_metric(const type_instance_id & id,
813 Args&& args) {
814 return add_disabled_polled_metric(id, description(), std::forward<Args>(args));
815 }
816
817 template<typename ... Args>
818 static type_instance_id add_disabled_polled_metric(const type_instance_id & id,
819 Args&& ... args) {
820 return add_disabled_polled_metric(id, description(), std::forward<Args>(args)...);
821 }
822
823 // "Explicit" metric sends. Sends a single value list as a message.
824 // Obviously not super efficient either. But maybe someone needs it sometime.
825 template<typename ... _Args>
826 static future<> send_explicit_metric(const type_instance_id & id,
827 _Args&& ... args) {
828 return send_metric(id, make_type_instance(std::forward<_Args>(args)...));
829 }
830 template<typename ... _Args>
831 static notify_function create_explicit_metric(const type_instance_id & id,
832 _Args&& ... args) {
833 auto list = make_type_instance(std::forward<_Args>(args)...);
834 return [id, list=std::move(list)]() {
835 send_metric(id, list);
836 };
837 }
838
839 template<typename... Args>
840 typed_value::typed_value(const type_id& tid, const scollectd::type_instance& ti, description d, Args&&... args)
841 : _type_id(tid)
842 , _type_instance(ti)
843 , _values(::seastar::make_shared<decltype(make_type_instance(std::move(d), std::forward<Args>(args)...))>(make_type_instance(std::move(d), std::forward<Args>(args)...)))
844 {}
845
846 // Send a message packet (string)
847 future<> send_notification(const type_instance_id & id, const sstring & msg);
848 };
849
850 }