]> git.proxmox.com Git - ceph.git/blame - ceph/src/seastar/include/seastar/core/scollectd.hh
import quincy beta 17.1.0
[ceph.git] / ceph / src / seastar / include / seastar / core / scollectd.hh
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#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>
11fdf7f2
TL
40#include <seastar/util/log.hh>
41
42#include <seastar/core/metrics_api.hh>
43
44namespace 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
f67539c2
TL
59 * `<pluginname>` would be the overall 'module', e.g. "cpu"
60 * `<instance_name>` -> optional distinguisher between plugin instances. For cpu, the built-in
11fdf7f2
TL
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)
f67539c2
TL
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"
11fdf7f2
TL
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
84namespace scollectd {
85
86extern seastar::logger logger;
87
88using data_type = seastar::metrics::impl::data_type;
89
90enum 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.
276template<typename T>
277struct 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
285template<typename T>
286static inline typed<T> make_typed(data_type type, T&& t) {
287 return typed<T>(type, std::forward<T>(t));
288}
289
290using plugin_id = seastar::metrics::group_name_type;
291using plugin_instance_id = seastar::metrics::instance_id_type;
292using type_id = seastar::metrics::metric_type_def;
293using type_instance = seastar::metrics::metric_name_type;
294
295type_id type_id_for(known_type);
296
297using description = seastar::metrics::description;
298
299static constexpr unsigned max_collectd_field_text_len = 63;
300
301class type_instance_id {
302 static thread_local unsigned _next_truncated_idx;
303
304 /// truncate a given field to the maximum allowed length
9f95a23c 305 void truncate(sstring& field, const char* field_desc);
11fdf7f2
TL
306public:
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 }
f67539c2
TL
318 type_instance_id(const seastar::metrics::impl::metric_id &id, const type_id& inherit_type) : _plugin(id.group_name()),
319 _plugin_instance(id.instance_id()), _type(inherit_type),
11fdf7f2
TL
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;
342private:
343 plugin_id _plugin;
344 plugin_instance_id _plugin_instance;
345 type_id _type;
346 scollectd::type_instance _type_instance;
347};
348
349extern const plugin_instance_id per_cpu_plugin_instance;
350
20effc67
TL
351// Scollectd configuration options.
352struct options : public program_options::option_group {
353 /// \brief Enable collectd daemon.
354 ///
355 /// Default: \p false.
356 program_options::value<bool> collectd;
357 /// \brief Address to send/broadcast metrics to.
358 ///
359 /// Default: \p 239.192.74.66:25826.
360 program_options::value<std::string> collectd_address;
361 /// \brief Poll period (ms).
362 ///
363 /// Frequency of sending counter metrics (0 disables).
364 /// Default: \p 1000.
365 program_options::value<unsigned> collectd_poll_period;
366 /// \deprecated use \ref metrics::options::metrics_hostname instead
367 program_options::value<std::string> collectd_hostname;
368
369 /// \cond internal
370 options(program_options::option_group* parent_group);
371 /// \endcond
372};
373
374void configure(const options&);
11fdf7f2
TL
375void remove_polled_metric(const type_instance_id &);
376
377class plugin_instance_metrics;
378
379/**
380 * Anchor for polled registration.
381 * Iff the registered type is in some way none-persistent,
382 * use this as receiver of the reg and ensure it dies before the
383 * added value(s).
384 *
385 * Use:
386 * uint64_t v = 0;
387 * registration r = add_polled_metric(v);
388 * ++r;
389 * <scope end, above dies>
390 */
391struct registration {
392 registration() = default;
393 registration(const type_instance_id& id);
394 registration(type_instance_id&& id);
395 registration(const registration&) = delete;
396 registration(registration&&) = default;
397 ~registration();
398 registration & operator=(const registration&) = delete;
399 registration & operator=(registration&&) = default;
400
401 void unregister() {
402 remove_polled_metric(_id);
403 _id = type_instance_id();
404 }
405private:
406 friend class plugin_instance_metrics;
407 type_instance_id _id;
408 shared_ptr<seastar::metrics::impl::impl> _impl;
409};
410
411/**
412 * Helper type to make generating vectors of registration objects
413 * easier, since it constructs from an initializer list of
414 * type_instance_id:s, avoiding early conversion to registration objs,
415 * which in case of init lists, are copy semantics, not move...
416 */
417class registrations
418 : public std::vector<registration>
419{
420public:
421 typedef std::vector<registration> vector_type;
422
423 registrations()
424 {}
425 registrations(vector_type&& v) : vector_type(std::move(v))
426 {}
427 registrations(const std::initializer_list<type_instance_id>& l)
428 : vector_type(l.begin(),l.end())
429 {}
430 registrations& operator=(vector_type&& v) {
431 vector_type::operator=(std::move(v));
432 return *this;
433 }
434 registrations& operator=(const std::initializer_list<type_instance_id>& l) {
435 return registrations::operator=(registrations(l));
436 }
437};
438
439class value_list;
440
441struct typed_value {
442 /**
443 * Wraps N values of a given type (type_id).
444 * Used to group types into a plugin_instance_metrics
445 */
446 template<typename... Args>
447 typed_value(const type_id& tid, const scollectd::type_instance& ti, description, Args&&... args);
448
449 template<typename... Args>
450 typed_value(const type_id& tid, const scollectd::type_instance& ti, Args&&... args)
451 : typed_value(tid, ti, description(), std::forward<Args>(args)...)
452 {}
453
454 const scollectd::type_instance& type_instance() const {
455 return _type_instance;
456 }
457 const shared_ptr<value_list>& values() const {
458 return _values;
459 }
460 const type_id & type() const {
461 return _type_id;
462 }
463private:
464 type_id _type_id;
465 scollectd::type_instance _type_instance;
466 shared_ptr<value_list> _values;
467};
468
469class plugin_instance_metrics {
470public:
471 template<typename... TypedValues>
472 plugin_instance_metrics(const plugin_id& p, const plugin_instance_id& pi, TypedValues&&... values)
473 : _plugin_id(p)
474 , _plugin_instance(pi)
475 , _registrations({ add_impl(values)... })
476 {}
477 std::vector<type_instance_id> bound_ids() const;
478 void add(const typed_value&);
479private:
480 type_instance_id add_impl(const typed_value&);
481
482 plugin_id _plugin_id;
483 plugin_instance_id _plugin_instance;
484 registrations _registrations;
485};
486
487/**
488 * Simplified wrapper for the common case of per-cpu plugin instances
489 * (i.e. distributed objects)
490 */
491class percpu_plugin_instance_metrics : public plugin_instance_metrics {
492public:
493 template<typename... TypedValues>
494 percpu_plugin_instance_metrics(const plugin_id& p, TypedValues&&... values)
495 : plugin_instance_metrics(p, per_cpu_plugin_instance, std::forward<TypedValues>(values)...)
496 {}
497};
498
499/**
500 * Template wrapper for type_id values, deriving type_id string
501 * from the known_types enum, for auto-completetion joy.
502 */
503template<known_type Type>
504struct typed_value_impl: public typed_value {
505 template<typename ... Args>
506 typed_value_impl(const scollectd::type_instance& ti, Args&& ... args)
507 : typed_value(type_id_for(Type), ti, std::forward<Args>(args)...)
508 {}
509
510 template<typename ... Args>
511 typed_value_impl(scollectd::type_instance ti, description d, Args&& ... args)
512 : typed_value(type_id_for(Type), std::move(ti), std::move(d), std::forward<Args>(args)...)
513 {}
514 template<typename ... Args>
515 typed_value_impl(description d, Args&& ... args)
516 : typed_value(type_id_for(Type), scollectd::type_instance(), std::move(d), std::forward<Args>(args)...)
517 {}
518};
519
520/*!
521 * \deprecated metrics registration should be done using the metrics layer
522 *
523 * Some typedefs for common used types. Feel free to add.
524 */
525typedef typed_value_impl<known_type::total_bytes> total_bytes;
526typedef typed_value_impl<known_type::total_connections> total_connections;
527typedef typed_value_impl<known_type::total_objects> total_objects;
528typedef typed_value_impl<known_type::total_operations> total_operations;
529typedef typed_value_impl<known_type::total_requests> total_requests;
530typedef typed_value_impl<known_type::total_sessions> total_sessions;
531typedef typed_value_impl<known_type::total_threads> total_threads;
532typedef typed_value_impl<known_type::total_time_in_ms> total_time_in_ms;
533typedef typed_value_impl<known_type::total_values> total_values;
534typedef typed_value_impl<known_type::queue_length> queue_length;
535typedef typed_value_impl<known_type::counter> counter;
536typedef typed_value_impl<known_type::count> count;
537typedef typed_value_impl<known_type::gauge> gauge;
538
539// lots of template junk to build typed value list tuples
540// for registered values.
541template<typename T, typename En = void>
542struct data_type_for;
543
544template<typename T, typename En = void>
545struct is_callable;
546
547template<typename T>
548struct is_callable<T,
549typename std::enable_if<
20effc67 550!std::is_void<std::invoke_result_t<T>>::value,
11fdf7f2
TL
551void>::type> : public std::true_type {
552};
553
554template<typename T>
555struct is_callable<T,
556typename std::enable_if<std::is_fundamental<T>::value, void>::type> : public std::false_type {
557};
558
559template<typename T>
560struct data_type_for<T,
561typename std::enable_if<
562std::is_integral<T>::value && std::is_unsigned<T>::value,
563void>::type> : public std::integral_constant<data_type,
564data_type::COUNTER> {
565};
566template<typename T>
567struct data_type_for<T,
568typename std::enable_if<
569std::is_integral<T>::value && std::is_signed<T>::value, void>::type> : public std::integral_constant<
570data_type, data_type::DERIVE> {
571};
572template<typename T>
573struct data_type_for<T,
574typename std::enable_if<std::is_floating_point<T>::value, void>::type> : public std::integral_constant<
575data_type, data_type::GAUGE> {
576};
577template<typename T>
578struct data_type_for<T,
579typename std::enable_if<is_callable<T>::value, void>::type> : public data_type_for<
20effc67 580std::invoke_result_t<T>> {
11fdf7f2
TL
581};
582template<typename T>
583struct data_type_for<typed<T>> : public data_type_for<T> {
584};
585
586template<typename T>
587class value {
588public:
589 template<typename W>
590 struct wrap {
591 wrap(const W & v)
592 : _v(v) {
593 }
594 const W & operator()() const {
595 return _v;
596 }
597 const W & _v;
598 };
599
600 typedef typename std::remove_reference<T>::type value_type;
601 typedef typename std::conditional<
602 is_callable<typename std::remove_reference<T>::type>::value,
603 value_type, wrap<value_type> >::type stored_type;
604
605 value(const value_type & t)
606 : value<T>(data_type_for<value_type>::value, t) {
607 }
608 value(data_type type, const value_type & t)
609 : _type(type), _t(t) {
610 }
611 uint64_t operator()() const {
612 auto v = _t();
613 if (_type == data_type::GAUGE) {
614 return convert(double(v));
615 } else {
616 uint64_t u = v;
617 return convert(u);
618 }
619 }
620 operator uint64_t() const {
621 return (*this)();
622 }
623 operator data_type() const {
624 return _type;
625 }
626 data_type type() const {
627 return _type;
628 }
629private:
630 // not super quick value -> protocol endian 64-bit values.
631 template<typename _Iter>
632 void bpack(_Iter s, _Iter e, uint64_t v) const {
633 while (s != e) {
634 *s++ = (v & 0xff);
635 v >>= 8;
636 }
637 }
638 template<typename V>
639 typename std::enable_if<std::is_integral<V>::value, uint64_t>::type convert(
640 V v) const {
641 uint64_t i = v;
642 // network byte order
643 return ntohq(i);
644 }
645 template<typename V>
646 typename std::enable_if<std::is_floating_point<V>::value, uint64_t>::type convert(
647 V t) const {
648 union {
649 uint64_t i;
650 double v;
651 } v;
652 union {
653 uint64_t i;
654 uint8_t b[8];
655 } u;
656 v.v = t;
657 // intel byte order. could also obviously be faster.
658 // could be ignored if we just assume we're le (for now),
659 // but this is ok me thinks.
660 bpack(std::begin(u.b), std::end(u.b), v.i);
661 return u.i;
662 }
663 ;
664
665 const data_type _type;
666 const stored_type _t;
667};
668
669template<typename T>
670class value<typed<T>> : public value<T> {
671public:
672 value(const typed<T> & args)
673: value<T>(args.type, args.value) {
674 }
675};
676
677class value_list {
678 bool _enabled = true;
679public:
680 value_list(description d) : _description(std::move(d))
681 {}
682 value_list(value_list&&) = default;
683 virtual ~value_list() {}
684
685 virtual size_t size() const = 0;
686
687 virtual void types(data_type *) const = 0;
688 virtual void values(net::packed<uint64_t> *) const = 0;
689
690 const description& desc() const {
691 return _description;
692 }
693
694 bool empty() const {
695 return size() == 0;
696 }
697
698 bool is_enabled() const {
699 return _enabled;
700 }
701
702 void set_enabled(bool b) {
703 _enabled = b;
704 }
705private:
706 description _description;
707};
708
709template<typename ... Args>
710class values_impl: public value_list {
711public:
712 static const size_t num_values = sizeof...(Args);
713
714 values_impl(description d, Args&& ...args)
715 : value_list(std::move(d))
716 , _values(std::forward<Args>(args)...)
717 {}
718
719 values_impl(values_impl<Args...>&& a) = default;
720 values_impl(const values_impl<Args...>& a) = default;
721
722 size_t size() const override {
723 return num_values;
724 }
725 void types(data_type * p) const override {
726 unpack(_values, [p](Args... args) {
727 std::initializer_list<data_type> tmp = { args... };
728 std::copy(tmp.begin(), tmp.end(), p);
729 });
730 }
731 void values(net::packed<uint64_t> * p) const override {
732 unpack(_values, [p](Args... args) {
733 std::initializer_list<uint64_t> tmp = { args... };
734 std::copy(tmp.begin(), tmp.end(), p);
735 });
736 }
737private:
738 template<typename _Op>
739 void unpack(const std::tuple<Args...>& t, _Op&& op) const {
740 do_unpack(t, std::index_sequence_for<Args...> {}, std::forward<_Op>(op));
741 }
742
743 template<size_t ...S, typename _Op>
744 void do_unpack(const std::tuple<Args...>& t, const std::index_sequence<S...> &, _Op&& op) const {
745 op(std::get<S>(t)...);
746 }
747
748 std::tuple < Args... > _values;
749};
750
751void add_polled(const type_instance_id &, const shared_ptr<value_list> &, bool enabled = true);
752
753typedef std::function<void()> notify_function;
754template<typename... _Args>
755static auto make_type_instance(description d, _Args && ... args) -> values_impl < decltype(value<_Args>(std::forward<_Args>(args)))... >
756{
757 return values_impl<decltype(value<_Args>(std::forward<_Args>(args)))...>(
758 std::move(d), value<_Args>(std::forward<_Args>(args))...);
759}
760/*!
761 * \deprecated metrics registration should be done using the metrics layer
762 *
763 */
764template<typename ... _Args>
765[[deprecated("Use the metrics layer")]] static type_instance_id add_polled_metric(const plugin_id & plugin,
766 const plugin_instance_id & plugin_instance, const type_id & type,
767 const scollectd::type_instance & type_instance, _Args&& ... args) {
768 return add_polled_metric(plugin, plugin_instance, type, type_instance, description(),
769 std::forward<_Args>(args)...);
770}
771/*!
772 * \deprecated metrics registration should be done using the metrics layer
773 *
774 */
775template<typename ... _Args>
776[[deprecated("Use the metrics layer")]] static type_instance_id add_polled_metric(const plugin_id & plugin,
777 const plugin_instance_id & plugin_instance, const type_id & type,
778 const scollectd::type_instance & type_instance, description d, _Args&& ... args) {
779 return add_polled_metric(
780 type_instance_id(plugin, plugin_instance, type, type_instance), std::move(d),
781 std::forward<_Args>(args)...);
782}
783template<typename ... _Args>
784static future<> send_explicit_metric(const plugin_id & plugin,
785 const plugin_instance_id & plugin_instance, const type_id & type,
786 const scollectd::type_instance & type_instance, _Args&& ... args) {
787 return send_explicit_metric(
788 type_instance_id(plugin, plugin_instance, type, type_instance),
789 std::forward<_Args>(args)...);
790}
791template<typename ... _Args>
792static notify_function create_explicit_metric(const plugin_id & plugin,
793 const plugin_instance_id & plugin_instance, const type_id & type,
794 const scollectd::type_instance & type_instance, _Args&& ... args) {
795 return create_explicit_metric(
796 type_instance_id(plugin, plugin_instance, type, type_instance),
797 std::forward<_Args>(args)...);
798}
799
800seastar::metrics::impl::metric_id to_metrics_id(const type_instance_id & id);
801/*!
802 * \deprecated metrics registration should be done using the metrics layer
803 *
804 */
805template<typename Arg>
806[[deprecated("Use the metrics layer")]] static type_instance_id add_polled_metric(const type_instance_id & id, description d,
807 Arg&& arg, bool enabled = true) {
f67539c2 808 seastar::metrics::impl::get_local_impl()->add_registration(to_metrics_id(id), arg.type, seastar::metrics::impl::make_function(arg.value, arg.type), d, enabled);
11fdf7f2
TL
809 return id;
810}
811/*!
812 * \deprecated metrics registration should be done using the metrics layer
813 *
814 */
815template<typename Arg>
816[[deprecated("Use the metrics layer")]] static type_instance_id add_polled_metric(const type_instance_id & id,
817 Arg&& arg) {
818 return std::move(add_polled_metric(id, description(), std::forward<Arg>(arg)));
819}
820
821/*!
822 * \deprecated metrics registration should be done using the metrics layer
823 *
824 */
825template<typename Args>
826[[deprecated("Use the metrics layer")]] static type_instance_id add_disabled_polled_metric(const type_instance_id & id, description d,
827 Args&& arg) {
828 return add_polled_metric(id, d, std::forward<Args>(arg), false);
829}
830
831template<typename Args>
832static type_instance_id add_disabled_polled_metric(const type_instance_id & id,
833 Args&& args) {
834 return add_disabled_polled_metric(id, description(), std::forward<Args>(args));
835}
836
837template<typename ... Args>
838static type_instance_id add_disabled_polled_metric(const type_instance_id & id,
839 Args&& ... args) {
840 return add_disabled_polled_metric(id, description(), std::forward<Args>(args)...);
841}
842
843// "Explicit" metric sends. Sends a single value list as a message.
844// Obviously not super efficient either. But maybe someone needs it sometime.
845template<typename ... _Args>
846static future<> send_explicit_metric(const type_instance_id & id,
847 _Args&& ... args) {
848 return send_metric(id, make_type_instance(std::forward<_Args>(args)...));
849}
850template<typename ... _Args>
851static notify_function create_explicit_metric(const type_instance_id & id,
852 _Args&& ... args) {
853 auto list = make_type_instance(std::forward<_Args>(args)...);
854 return [id, list=std::move(list)]() {
855 send_metric(id, list);
856 };
857}
858
859template<typename... Args>
860typed_value::typed_value(const type_id& tid, const scollectd::type_instance& ti, description d, Args&&... args)
861 : _type_id(tid)
862 , _type_instance(ti)
863 , _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)...)))
864{}
865
866// Send a message packet (string)
867future<> send_notification(const type_instance_id & id, const sstring & msg);
868};
869
870}