]>
Commit | Line | Data |
---|---|---|
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) 2016 ScyllaDB. | |
20 | */ | |
21 | ||
22 | #pragma once | |
23 | ||
24 | #include <functional> | |
20effc67 | 25 | #include <limits> |
1e59de90 TL |
26 | #include <map> |
27 | #include <type_traits> | |
11fdf7f2 TL |
28 | #include <seastar/core/sstring.hh> |
29 | #include <seastar/core/shared_ptr.hh> | |
30 | #include <seastar/core/metrics_registration.hh> | |
31 | #include <boost/lexical_cast.hpp> | |
11fdf7f2 TL |
32 | #include <seastar/core/metrics_types.hh> |
33 | #include <seastar/util/std-compat.hh> | |
1e59de90 | 34 | #include <seastar/util/bool_class.hh> |
11fdf7f2 TL |
35 | |
36 | /*! \file metrics.hh | |
37 | * \brief header for metrics creation. | |
38 | * | |
39 | * This header file contains the metrics creation method with their helper function. | |
40 | * Include this file when need to create metrics. | |
41 | * Typically this will be in your source file. | |
42 | * | |
43 | * Code that is under the impl namespace should not be used directly. | |
44 | * | |
45 | */ | |
46 | ||
47 | namespace seastar { | |
48 | ||
49 | /*! | |
f67539c2 TL |
50 | * \addtogroup metrics |
51 | * @{ | |
52 | * | |
11fdf7f2 TL |
53 | * \namespace seastar::metrics |
54 | * \brief metrics creation and registration | |
55 | * | |
56 | * the metrics namespace holds the relevant method and classes to generate metrics. | |
57 | * | |
58 | * The metrics layer support registering metrics, that later will be | |
59 | * exported via different API protocols. | |
60 | * | |
61 | * To be able to support multiple protocols the following simplifications where made: | |
62 | * 1. The id of the metrics is based on the collectd id | |
63 | * 2. A metric could be a single value either a reference or a function | |
64 | * | |
65 | * To add metrics definition to class A do the following: | |
66 | * * Add a metrics_group memeber to A | |
67 | * * Add a a set_metrics() method that would be called in the constructor. | |
68 | * | |
69 | * | |
70 | * In A header file | |
71 | * \code | |
72 | * #include "core/metrics_registration.hh" | |
73 | * class A { | |
74 | * metric_groups _metrics | |
75 | * | |
76 | * void setup_metrics(); | |
77 | * | |
78 | * }; | |
79 | * \endcode | |
80 | * | |
81 | * In A source file: | |
82 | * | |
83 | * \code | |
84 | * include "core/metrics.hh" | |
85 | * | |
86 | * void A::setup_metrics() { | |
87 | * namespace sm = seastar::metrics; | |
88 | * _metrics = sm::create_metric_group(); | |
89 | * _metrics->add_group("cache", {sm::make_gauge("bytes", "used", [this] { return _region.occupancy().used_space(); })}); | |
90 | * } | |
91 | * \endcode | |
92 | */ | |
93 | ||
94 | namespace metrics { | |
95 | ||
9f95a23c TL |
96 | class double_registration : public std::runtime_error { |
97 | public: | |
98 | double_registration(std::string what); | |
99 | }; | |
11fdf7f2 TL |
100 | |
101 | /*! | |
102 | * \defgroup metrics_types metrics type definitions | |
103 | * The following are for the metric layer use, do not use them directly | |
1e59de90 | 104 | * Instead use the make_counter, make_gauge |
11fdf7f2 TL |
105 | * |
106 | */ | |
107 | using metric_type_def = sstring; /*!< Used to hold an inherit type (like bytes)*/ | |
108 | using metric_name_type = sstring; /*!< The metric name'*/ | |
109 | using instance_id_type = sstring; /*!< typically used for the shard id*/ | |
1e59de90 | 110 | using skip_when_empty = bool_class<class skip_when_empty_tag>; |
11fdf7f2 TL |
111 | |
112 | /*! | |
113 | * \brief Human-readable description of a metric/group. | |
114 | * | |
115 | * | |
116 | * Uses a separate class to deal with type resolution | |
117 | * | |
118 | * Add this to metric creation: | |
119 | * | |
120 | * \code | |
121 | * _metrics->add_group("groupname", { | |
122 | * sm::make_gauge("metric_name", value, description("A documentation about the return value")) | |
123 | * }); | |
124 | * \endcode | |
125 | * | |
126 | */ | |
127 | class description { | |
128 | public: | |
129 | description(sstring s = sstring()) : _s(std::move(s)) | |
130 | {} | |
131 | const sstring& str() const { | |
132 | return _s; | |
133 | } | |
134 | private: | |
135 | sstring _s; | |
136 | }; | |
137 | ||
138 | /*! | |
139 | * \brief Label a metrics | |
140 | * | |
141 | * Label are useful for adding information about a metric that | |
142 | * later you would need to aggregate by. | |
143 | * For example, if you have multiple queues on a shard. | |
144 | * Adding the queue id as a Label will allow you to use the same name | |
145 | * of the metrics with multiple id instances. | |
146 | * | |
147 | * label_instance holds an instance of label consist of a key and value. | |
148 | * | |
149 | * Typically you will not generate a label_instance yourself, but use a label | |
150 | * object for that. | |
151 | * @see label for more information | |
152 | * | |
153 | * | |
154 | */ | |
155 | class label_instance { | |
156 | sstring _key; | |
157 | sstring _value; | |
158 | public: | |
159 | /*! | |
160 | * \brief create a label_instance | |
161 | * label instance consists of key and value. | |
162 | * The key is an sstring. | |
163 | * T - the value type can be any type that can be lexical_cast to string | |
164 | * (ie. if it support the redirection operator for stringstream). | |
165 | * | |
166 | * All primitive types are supported so all the following examples are valid: | |
167 | * label_instance a("smp_queue", 1) | |
168 | * label_instance a("my_key", "my_value") | |
169 | * label_instance a("internal_id", -1) | |
170 | */ | |
171 | template<typename T> | |
172 | label_instance(const sstring& key, T v) : _key(key), _value(boost::lexical_cast<std::string>(v)){} | |
173 | ||
174 | /*! | |
175 | * \brief returns the label key | |
176 | */ | |
177 | const sstring key() const { | |
178 | return _key; | |
179 | } | |
180 | ||
181 | /*! | |
182 | * \brief returns the label value | |
183 | */ | |
184 | const sstring value() const { | |
185 | return _value; | |
186 | } | |
187 | bool operator<(const label_instance&) const; | |
188 | bool operator==(const label_instance&) const; | |
189 | bool operator!=(const label_instance&) const; | |
190 | }; | |
191 | ||
192 | ||
193 | /*! | |
194 | * \brief Class that creates label instances | |
195 | * | |
196 | * A factory class to create label instance | |
197 | * Typically, the same Label name is used in multiple places. | |
198 | * label is a label factory, you create it once, and use it to create the label_instance. | |
199 | * | |
200 | * In the example we would like to label the smp_queue with with the queue owner | |
201 | * | |
202 | * seastar::metrics::label smp_owner("smp_owner"); | |
203 | * | |
204 | * now, when creating a new smp metric we can add a label to it: | |
205 | * | |
206 | * sm::make_queue_length("send_batch_queue_length", _last_snt_batch, {smp_owner(cpuid)}) | |
207 | * | |
208 | * where cpuid in this case is unsiged. | |
209 | */ | |
210 | class label { | |
211 | sstring key; | |
212 | public: | |
213 | using instance = label_instance; | |
214 | /*! | |
215 | * \brief creating a label | |
216 | * key is the label name, it will be the key for all label_instance | |
217 | * that will be created from this label. | |
218 | */ | |
219 | explicit label(const sstring& key) : key(key) { | |
220 | } | |
221 | ||
222 | /*! | |
223 | * \brief creating a label instance | |
224 | * | |
225 | * Use the function operator to create a new label instance. | |
226 | * T - the value type can be any type that can be lexical_cast to string | |
227 | * (ie. if it support the redirection operator for stringstream). | |
228 | * | |
229 | * All primitive types are supported so if lab is a label, all the following examples are valid: | |
230 | * lab(1) | |
231 | * lab("my_value") | |
232 | * lab(-1) | |
233 | */ | |
234 | template<typename T> | |
235 | instance operator()(T value) const { | |
236 | return label_instance(key, std::forward<T>(value)); | |
237 | } | |
238 | ||
239 | /*! | |
240 | * \brief returns the label name | |
241 | */ | |
242 | const sstring& name() const { | |
243 | return key; | |
244 | } | |
245 | }; | |
246 | ||
247 | /*! | |
f67539c2 | 248 | * \namespace impl |
11fdf7f2 TL |
249 | * \brief holds the implementation parts of the metrics layer, do not use directly. |
250 | * | |
251 | * The metrics layer define a thin API for adding metrics. | |
252 | * Some of the implementation details need to be in the header file, they should not be use directly. | |
253 | */ | |
254 | namespace impl { | |
255 | ||
256 | // The value binding data types | |
257 | enum class data_type : uint8_t { | |
1e59de90 TL |
258 | COUNTER, |
259 | REAL_COUNTER, | |
260 | GAUGE, | |
11fdf7f2 | 261 | HISTOGRAM, |
1e59de90 TL |
262 | SUMMARY, |
263 | }; | |
264 | ||
265 | template <bool callable, typename T> | |
266 | struct real_counter_type_traits { | |
267 | using type = T; | |
268 | }; | |
269 | ||
270 | template <typename T> | |
271 | struct real_counter_type_traits<true, T> { | |
272 | using type = typename std::invoke_result<T>::type; | |
273 | }; | |
274 | ||
275 | template <typename T> | |
276 | struct counter_type_traits { | |
277 | using real_traits = real_counter_type_traits<std::is_invocable<T>::value, T>; | |
278 | static constexpr bool is_integral = std::is_integral<typename real_traits::type>::value; | |
279 | static constexpr data_type type = is_integral ? data_type::COUNTER : data_type::REAL_COUNTER; | |
11fdf7f2 TL |
280 | }; |
281 | ||
282 | /*! | |
f67539c2 | 283 | * \brief A helper class that used to return metrics value. |
11fdf7f2 TL |
284 | * |
285 | * Do not use directly @see metrics_creation | |
286 | */ | |
20effc67 TL |
287 | class metric_value { |
288 | public: | |
f67539c2 | 289 | std::variant<double, histogram> u; |
11fdf7f2 TL |
290 | data_type _type; |
291 | data_type type() const { | |
292 | return _type; | |
293 | } | |
294 | ||
295 | double d() const { | |
f67539c2 | 296 | return std::get<double>(u); |
11fdf7f2 TL |
297 | } |
298 | ||
299 | uint64_t ui() const { | |
20effc67 TL |
300 | auto d = std::get<double>(u); |
301 | if (d >= 0 && d <= double(std::numeric_limits<long>::max())) { | |
302 | return lround(d); | |
303 | } else { | |
304 | // double value is out of range or NaN or Inf | |
305 | ulong_conversion_error(d); | |
306 | return 0; | |
307 | } | |
11fdf7f2 TL |
308 | } |
309 | ||
310 | int64_t i() const { | |
20effc67 TL |
311 | auto d = std::get<double>(u); |
312 | if (d >= double(std::numeric_limits<long>::min()) && d <= double(std::numeric_limits<long>::max())) { | |
313 | return lround(d); | |
314 | } else { | |
315 | // double value is out of range or NaN or Inf | |
316 | ulong_conversion_error(d); | |
317 | return 0; | |
318 | } | |
11fdf7f2 TL |
319 | } |
320 | ||
321 | metric_value() | |
322 | : _type(data_type::GAUGE) { | |
323 | } | |
324 | ||
325 | metric_value(histogram&& h, data_type t = data_type::HISTOGRAM) : | |
326 | u(std::move(h)), _type(t) { | |
327 | } | |
328 | metric_value(const histogram& h, data_type t = data_type::HISTOGRAM) : | |
329 | u(h), _type(t) { | |
330 | } | |
331 | ||
332 | metric_value(double d, data_type t) | |
333 | : u(d), _type(t) { | |
334 | } | |
335 | ||
336 | metric_value& operator=(const metric_value& c) = default; | |
337 | ||
338 | metric_value& operator+=(const metric_value& c) { | |
339 | *this = *this + c; | |
340 | return *this; | |
341 | } | |
342 | ||
343 | metric_value operator+(const metric_value& c); | |
344 | const histogram& get_histogram() const { | |
f67539c2 | 345 | return std::get<histogram>(u); |
11fdf7f2 | 346 | } |
20effc67 | 347 | |
1e59de90 TL |
348 | /*! |
349 | * \brief return true if this metric was never used | |
350 | * | |
351 | * Histograms, Summaries and counters are ever growing by nature, so | |
352 | * it is possible to check if they have been used or not. | |
353 | */ | |
354 | bool is_empty() const noexcept { | |
355 | return ((_type == data_type::HISTOGRAM || _type == data_type::SUMMARY) && get_histogram().sample_count == 0) || | |
356 | ((_type == data_type::COUNTER || _type == data_type::REAL_COUNTER) && d() == 0); | |
357 | } | |
20effc67 TL |
358 | private: |
359 | static void ulong_conversion_error(double d); | |
11fdf7f2 TL |
360 | }; |
361 | ||
362 | using metric_function = std::function<metric_value()>; | |
363 | ||
364 | struct metric_type { | |
365 | data_type base_type; | |
366 | metric_type_def type_name; | |
367 | }; | |
368 | ||
369 | struct metric_definition_impl { | |
370 | metric_name_type name; | |
371 | metric_type type; | |
372 | metric_function f; | |
373 | description d; | |
374 | bool enabled = true; | |
1e59de90 TL |
375 | skip_when_empty _skip_when_empty = skip_when_empty::no; |
376 | std::vector<std::string> aggregate_labels; | |
11fdf7f2 TL |
377 | std::map<sstring, sstring> labels; |
378 | metric_definition_impl& operator ()(bool enabled); | |
379 | metric_definition_impl& operator ()(const label_instance& label); | |
1e59de90 TL |
380 | metric_definition_impl& operator ()(skip_when_empty skip) noexcept; |
381 | metric_definition_impl& aggregate(const std::vector<label>& labels) noexcept; | |
382 | metric_definition_impl& set_skip_when_empty(bool skip=true) noexcept; | |
f67539c2 | 383 | metric_definition_impl& set_type(const sstring& type_name); |
11fdf7f2 TL |
384 | metric_definition_impl( |
385 | metric_name_type name, | |
386 | metric_type type, | |
387 | metric_function f, | |
388 | description d, | |
1e59de90 TL |
389 | std::vector<label_instance> labels, |
390 | std::vector<label> aggregate_labels = {}); | |
11fdf7f2 TL |
391 | }; |
392 | ||
393 | class metric_groups_def { | |
394 | public: | |
395 | metric_groups_def() = default; | |
396 | virtual ~metric_groups_def() = default; | |
397 | metric_groups_def(const metric_groups_def&) = delete; | |
398 | metric_groups_def(metric_groups_def&&) = default; | |
399 | virtual metric_groups_def& add_metric(group_name_type name, const metric_definition& md) = 0; | |
400 | virtual metric_groups_def& add_group(group_name_type name, const std::initializer_list<metric_definition>& l) = 0; | |
401 | virtual metric_groups_def& add_group(group_name_type name, const std::vector<metric_definition>& l) = 0; | |
402 | }; | |
403 | ||
404 | instance_id_type shard(); | |
405 | ||
1e59de90 | 406 | template<typename T, typename = std::enable_if_t<std::is_invocable_v<T>>> |
11fdf7f2 | 407 | metric_function make_function(T val, data_type dt) { |
1e59de90 | 408 | return [dt, val = std::move(val)] { |
11fdf7f2 TL |
409 | return metric_value(val(), dt); |
410 | }; | |
411 | } | |
412 | ||
1e59de90 | 413 | template<typename T, typename = std::enable_if_t<!std::is_invocable_v<T>>> |
11fdf7f2 TL |
414 | metric_function make_function(T& val, data_type dt) { |
415 | return [dt, &val] { | |
416 | return metric_value(val, dt); | |
417 | }; | |
418 | } | |
419 | } | |
420 | ||
421 | extern const bool metric_disabled; | |
422 | ||
423 | extern label shard_label; | |
11fdf7f2 TL |
424 | |
425 | /* | |
426 | * The metrics definition are defined to be compatible with collectd metrics defintion. | |
427 | * Typically you should used gauge or derived. | |
428 | */ | |
429 | ||
430 | ||
431 | /*! | |
432 | * \brief Gauge are a general purpose metric. | |
433 | * | |
434 | * They can support floating point and can increase or decrease | |
435 | */ | |
436 | template<typename T> | |
437 | impl::metric_definition_impl make_gauge(metric_name_type name, | |
1e59de90 | 438 | T&& val, description d = description(), std::vector<label_instance> labels = {}) { |
11fdf7f2 TL |
439 | return {name, {impl::data_type::GAUGE, "gauge"}, make_function(std::forward<T>(val), impl::data_type::GAUGE), d, labels}; |
440 | } | |
441 | ||
442 | /*! | |
443 | * \brief Gauge are a general purpose metric. | |
444 | * | |
445 | * They can support floating point and can increase or decrease | |
446 | */ | |
447 | template<typename T> | |
448 | impl::metric_definition_impl make_gauge(metric_name_type name, | |
449 | description d, T&& val) { | |
450 | return {name, {impl::data_type::GAUGE, "gauge"}, make_function(std::forward<T>(val), impl::data_type::GAUGE), d, {}}; | |
451 | } | |
452 | ||
453 | /*! | |
454 | * \brief Gauge are a general purpose metric. | |
455 | * | |
456 | * They can support floating point and can increase or decrease | |
457 | */ | |
458 | template<typename T> | |
459 | impl::metric_definition_impl make_gauge(metric_name_type name, | |
460 | description d, std::vector<label_instance> labels, T&& val) { | |
461 | return {name, {impl::data_type::GAUGE, "gauge"}, make_function(std::forward<T>(val), impl::data_type::GAUGE), d, labels}; | |
462 | } | |
463 | ||
464 | ||
465 | /*! | |
466 | * \brief Derive are used when a rate is more interesting than the value. | |
467 | * | |
468 | * Derive is an integer value that can increase or decrease, typically it is used when looking at the | |
469 | * derivation of the value. | |
470 | * | |
471 | * It is OK to use it when counting things and if no wrap-around is expected (it shouldn't) it's prefer over counter metric. | |
472 | */ | |
473 | template<typename T> | |
1e59de90 | 474 | [[deprecated("Use make_counter()")]] |
11fdf7f2 | 475 | impl::metric_definition_impl make_derive(metric_name_type name, |
1e59de90 TL |
476 | T&& val, description d = description(), std::vector<label_instance> labels = {}) { |
477 | return make_counter(std::move(name), std::forward<T>(val), std::move(d), std::move(labels)); | |
11fdf7f2 TL |
478 | } |
479 | ||
480 | ||
481 | /*! | |
482 | * \brief Derive are used when a rate is more interesting than the value. | |
483 | * | |
484 | * Derive is an integer value that can increase or decrease, typically it is used when looking at the | |
485 | * derivation of the value. | |
486 | * | |
487 | * It is OK to use it when counting things and if no wrap-around is expected (it shouldn't) it's prefer over counter metric. | |
488 | */ | |
489 | template<typename T> | |
1e59de90 | 490 | [[deprecated("Use make_counter()")]] |
11fdf7f2 TL |
491 | impl::metric_definition_impl make_derive(metric_name_type name, description d, |
492 | T&& val) { | |
1e59de90 | 493 | return make_counter(std::move(name), std::forward<T>(val), std::move(d), {}); |
11fdf7f2 TL |
494 | } |
495 | ||
496 | ||
497 | /*! | |
498 | * \brief Derive are used when a rate is more interesting than the value. | |
499 | * | |
500 | * Derive is an integer value that can increase or decrease, typically it is used when looking at the | |
501 | * derivation of the value. | |
502 | * | |
503 | * It is OK to use it when counting things and if no wrap-around is expected (it shouldn't) it's prefer over counter metric. | |
504 | */ | |
505 | template<typename T> | |
1e59de90 | 506 | [[deprecated("Use make_counter()")]] |
11fdf7f2 TL |
507 | impl::metric_definition_impl make_derive(metric_name_type name, description d, std::vector<label_instance> labels, |
508 | T&& val) { | |
1e59de90 | 509 | return make_counter(std::move(name), std::forward<T>(val), std::move(d), std::move(labels)); |
11fdf7f2 TL |
510 | } |
511 | ||
512 | ||
513 | /*! | |
514 | * \brief create a counter metric | |
515 | * | |
1e59de90 TL |
516 | * Counters are used when a rate is more interesting than the value, monitoring systems take |
517 | * derivation from it to display. | |
518 | * | |
519 | * It's an integer or floating point value that can increase or decrease. | |
11fdf7f2 TL |
520 | * |
521 | */ | |
522 | template<typename T> | |
523 | impl::metric_definition_impl make_counter(metric_name_type name, | |
1e59de90 TL |
524 | T&& val, description d = description(), std::vector<label_instance> labels = {}) { |
525 | auto type = impl::counter_type_traits<std::remove_reference_t<T>>::type; | |
526 | return {name, {type, "counter"}, make_function(std::forward<T>(val), type), d, labels}; | |
527 | } | |
528 | ||
529 | /*! | |
530 | * \brief create a counter metric | |
531 | * | |
532 | * Counters are used when a rate is more interesting than the value, monitoring systems take | |
533 | * derivation from it to display. | |
534 | * | |
535 | * It's an integer or floating point value that can increase or decrease. | |
536 | * | |
537 | */ | |
538 | template<typename T> | |
539 | impl::metric_definition_impl make_counter(metric_name_type name, description d, T&& val) { | |
540 | return make_counter(std::move(name), std::forward<T>(val), std::move(d), {}); | |
541 | } | |
542 | ||
543 | /*! | |
544 | * \brief create a counter metric | |
545 | * | |
546 | * Counters are used when a rate is more interesting than the value, monitoring systems take | |
547 | * derivation from it to display. | |
548 | * | |
549 | * It's an integer or floating point value that can increase or decrease. | |
550 | * | |
551 | */ | |
552 | template<typename T> | |
553 | impl::metric_definition_impl make_counter(metric_name_type name, description d, std::vector<label_instance> labels, T&& val) { | |
554 | return make_counter(std::move(name), std::forward<T>(val), std::move(d), std::move(labels)); | |
11fdf7f2 TL |
555 | } |
556 | ||
557 | /*! | |
558 | * \brief create an absolute metric. | |
559 | * | |
560 | * Absolute are used for metric that are being erased after each time they are read. | |
561 | * They are here for compatibility reasons and should general be avoided in most applications. | |
562 | */ | |
563 | template<typename T> | |
1e59de90 | 564 | [[deprecated("Use make_counter()")]] |
11fdf7f2 | 565 | impl::metric_definition_impl make_absolute(metric_name_type name, |
1e59de90 TL |
566 | T&& val, description d = description(), std::vector<label_instance> labels = {}) { |
567 | return make_counter(std::move(name), std::forward<T>(val), std::move(d), std::move(labels)); | |
11fdf7f2 TL |
568 | } |
569 | ||
570 | /*! | |
571 | * \brief create a histogram metric. | |
572 | * | |
573 | * Histograms are a list o buckets with upper values and counter for the number | |
574 | * of entries in each bucket. | |
575 | */ | |
576 | template<typename T> | |
577 | impl::metric_definition_impl make_histogram(metric_name_type name, | |
1e59de90 | 578 | T&& val, description d = description(), std::vector<label_instance> labels = {}) { |
11fdf7f2 TL |
579 | return {name, {impl::data_type::HISTOGRAM, "histogram"}, make_function(std::forward<T>(val), impl::data_type::HISTOGRAM), d, labels}; |
580 | } | |
581 | ||
582 | /*! | |
583 | * \brief create a histogram metric. | |
584 | * | |
585 | * Histograms are a list o buckets with upper values and counter for the number | |
586 | * of entries in each bucket. | |
587 | */ | |
588 | template<typename T> | |
589 | impl::metric_definition_impl make_histogram(metric_name_type name, | |
590 | description d, std::vector<label_instance> labels, T&& val) { | |
591 | return {name, {impl::data_type::HISTOGRAM, "histogram"}, make_function(std::forward<T>(val), impl::data_type::HISTOGRAM), d, labels}; | |
592 | } | |
593 | ||
594 | ||
595 | /*! | |
596 | * \brief create a histogram metric. | |
597 | * | |
598 | * Histograms are a list o buckets with upper values and counter for the number | |
599 | * of entries in each bucket. | |
600 | */ | |
601 | template<typename T> | |
602 | impl::metric_definition_impl make_histogram(metric_name_type name, | |
603 | description d, T&& val) { | |
604 | return {name, {impl::data_type::HISTOGRAM, "histogram"}, make_function(std::forward<T>(val), impl::data_type::HISTOGRAM), d, {}}; | |
605 | } | |
606 | ||
1e59de90 TL |
607 | /*! |
608 | * \brief create a summary metric. | |
609 | * | |
610 | * Summaries are a different kind of histograms. It reports in quantiles. | |
611 | * For example, the p99 and p95 latencies. | |
612 | */ | |
613 | template<typename T> | |
614 | impl::metric_definition_impl make_summary(metric_name_type name, | |
615 | description d, T&& val) { | |
616 | return {name, {impl::data_type::SUMMARY, "summary"}, make_function(std::forward<T>(val), impl::data_type::SUMMARY), d, {}}; | |
617 | } | |
618 | ||
11fdf7f2 TL |
619 | |
620 | /*! | |
621 | * \brief create a total_bytes metric. | |
622 | * | |
623 | * total_bytes are used for an ever growing counters, like the total bytes | |
624 | * passed on a network. | |
625 | */ | |
626 | ||
627 | template<typename T> | |
628 | impl::metric_definition_impl make_total_bytes(metric_name_type name, | |
1e59de90 TL |
629 | T&& val, description d = description(), std::vector<label_instance> labels = {}, |
630 | instance_id_type = impl::shard()) { | |
631 | return make_counter(name, std::forward<T>(val), d, labels).set_type("total_bytes"); | |
11fdf7f2 TL |
632 | } |
633 | ||
634 | /*! | |
635 | * \brief create a current_bytes metric. | |
636 | * | |
637 | * current_bytes are used to report on current status in bytes. | |
638 | * For example the current free memory. | |
639 | */ | |
640 | ||
641 | template<typename T> | |
642 | impl::metric_definition_impl make_current_bytes(metric_name_type name, | |
1e59de90 TL |
643 | T&& val, description d = description(), std::vector<label_instance> labels = {}, |
644 | instance_id_type = impl::shard()) { | |
20effc67 | 645 | return make_gauge(name, std::forward<T>(val), d, labels).set_type("bytes"); |
11fdf7f2 TL |
646 | } |
647 | ||
648 | ||
649 | /*! | |
650 | * \brief create a queue_length metric. | |
651 | * | |
652 | * queue_length are used to report on queue length | |
653 | */ | |
654 | ||
655 | template<typename T> | |
656 | impl::metric_definition_impl make_queue_length(metric_name_type name, | |
1e59de90 TL |
657 | T&& val, description d = description(), std::vector<label_instance> labels = {}, |
658 | instance_id_type = impl::shard()) { | |
f67539c2 | 659 | return make_gauge(name, std::forward<T>(val), d, labels).set_type("queue_length"); |
11fdf7f2 TL |
660 | } |
661 | ||
662 | ||
663 | /*! | |
664 | * \brief create a total operation metric. | |
665 | * | |
666 | * total_operations are used for ever growing operation counter. | |
667 | */ | |
668 | ||
669 | template<typename T> | |
670 | impl::metric_definition_impl make_total_operations(metric_name_type name, | |
1e59de90 TL |
671 | T&& val, description d = description(), std::vector<label_instance> labels = {}, |
672 | instance_id_type = impl::shard()) { | |
673 | return make_counter(name, std::forward<T>(val), d, labels).set_type("total_operations"); | |
11fdf7f2 TL |
674 | } |
675 | ||
676 | /*! @} */ | |
677 | } | |
678 | } |