Seastar
High performance C++ framework for concurrent servers
metrics.hh
Go to the documentation of this file.
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>
25 #include <seastar/core/sstring.hh>
26 #include <seastar/core/shared_ptr.hh>
28 #include <boost/lexical_cast.hpp>
29 #include <map>
30 #include <seastar/core/metrics_types.hh>
31 #include <seastar/util/std-compat.hh>
32 
44 namespace seastar {
45 
91 namespace metrics {
92 
93 class double_registration : public std::runtime_error {
94 public:
95  double_registration(std::string what);
96 };
97 
104 using metric_type_def = sstring;
105 using metric_name_type = sstring;
106 using instance_id_type = sstring;
123 class description {
124 public:
125  description(sstring s = sstring()) : _s(std::move(s))
126  {}
127  const sstring& str() const {
128  return _s;
129  }
130 private:
131  sstring _s;
132 };
133 
152  sstring _key;
153  sstring _value;
154 public:
167  template<typename T>
168  label_instance(const sstring& key, T v) : _key(key), _value(boost::lexical_cast<std::string>(v)){}
169 
173  const sstring key() const {
174  return _key;
175  }
176 
180  const sstring value() const {
181  return _value;
182  }
183  bool operator<(const label_instance&) const;
184  bool operator==(const label_instance&) const;
185  bool operator!=(const label_instance&) const;
186 };
187 
188 
206 class label {
207  sstring key;
208 public:
209  using instance = label_instance;
215  explicit label(const sstring& key) : key(key) {
216  }
217 
230  template<typename T>
231  instance operator()(T value) const {
232  return label_instance(key, std::forward<T>(value));
233  }
234 
238  const sstring& name() const {
239  return key;
240  }
241 };
242 
250 namespace impl {
251 
252 // The value binding data types
253 enum class data_type : uint8_t {
254  COUNTER, // unsigned int 64
255  GAUGE, // double
256  DERIVE, // signed int 64
257  ABSOLUTE, // unsigned int 64
258  HISTOGRAM,
259 };
260 
266 struct metric_value {
267  std::variant<double, histogram> u;
268  data_type _type;
269  data_type type() const {
270  return _type;
271  }
272 
273  double d() const {
274  return std::get<double>(u);
275  }
276 
277  uint64_t ui() const {
278  return std::get<double>(u);
279  }
280 
281  int64_t i() const {
282  return std::get<double>(u);
283  }
284 
285  metric_value()
286  : _type(data_type::GAUGE) {
287  }
288 
289  metric_value(histogram&& h, data_type t = data_type::HISTOGRAM) :
290  u(std::move(h)), _type(t) {
291  }
292  metric_value(const histogram& h, data_type t = data_type::HISTOGRAM) :
293  u(h), _type(t) {
294  }
295 
296  metric_value(double d, data_type t)
297  : u(d), _type(t) {
298  }
299 
300  metric_value& operator=(const metric_value& c) = default;
301 
302  metric_value& operator+=(const metric_value& c) {
303  *this = *this + c;
304  return *this;
305  }
306 
307  metric_value operator+(const metric_value& c);
308  const histogram& get_histogram() const {
309  return std::get<histogram>(u);
310  }
311 };
312 
313 using metric_function = std::function<metric_value()>;
314 
315 struct metric_type {
316  data_type base_type;
317  metric_type_def type_name;
318 };
319 
321  metric_name_type name;
322  metric_type type;
323  metric_function f;
324  description d;
325  bool enabled = true;
326  std::map<sstring, sstring> labels;
327  metric_definition_impl& operator ()(bool enabled);
328  metric_definition_impl& operator ()(const label_instance& label);
329  metric_definition_impl& set_type(const sstring& type_name);
331  metric_name_type name,
332  metric_type type,
333  metric_function f,
334  description d,
335  std::vector<label_instance> labels);
336 };
337 
339 public:
340  metric_groups_def() = default;
341  virtual ~metric_groups_def() = default;
342  metric_groups_def(const metric_groups_def&) = delete;
344  virtual metric_groups_def& add_metric(group_name_type name, const metric_definition& md) = 0;
345  virtual metric_groups_def& add_group(group_name_type name, const std::initializer_list<metric_definition>& l) = 0;
346  virtual metric_groups_def& add_group(group_name_type name, const std::vector<metric_definition>& l) = 0;
347 };
348 
349 instance_id_type shard();
350 
351 template<typename T, typename En = std::true_type>
352 struct is_callable;
353 
354 template<typename T>
355 struct is_callable<T, typename std::integral_constant<bool, !std::is_void<typename std::result_of<T()>::type>::value>::type> : public std::true_type {
356 };
357 
358 template<typename T>
359 struct is_callable<T, typename std::enable_if<std::is_fundamental<T>::value, std::true_type>::type> : public std::false_type {
360 };
361 
362 template<typename T, typename = std::enable_if_t<is_callable<T>::value>>
363 metric_function make_function(T val, data_type dt) {
364  return [dt, val] {
365  return metric_value(val(), dt);
366  };
367 }
368 
369 template<typename T, typename = std::enable_if_t<!is_callable<T>::value>>
370 metric_function make_function(T& val, data_type dt) {
371  return [dt, &val] {
372  return metric_value(val, dt);
373  };
374 }
375 }
376 
377 extern const bool metric_disabled;
378 
379 extern label shard_label;
380 
381 /*
382  * The metrics definition are defined to be compatible with collectd metrics defintion.
383  * Typically you should used gauge or derived.
384  */
385 
386 
392 template<typename T>
394  T&& val, description d=description(), std::vector<label_instance> labels = {}) {
395  return {name, {impl::data_type::GAUGE, "gauge"}, make_function(std::forward<T>(val), impl::data_type::GAUGE), d, labels};
396 }
397 
403 template<typename T>
405  description d, T&& val) {
406  return {name, {impl::data_type::GAUGE, "gauge"}, make_function(std::forward<T>(val), impl::data_type::GAUGE), d, {}};
407 }
408 
414 template<typename T>
416  description d, std::vector<label_instance> labels, T&& val) {
417  return {name, {impl::data_type::GAUGE, "gauge"}, make_function(std::forward<T>(val), impl::data_type::GAUGE), d, labels};
418 }
419 
420 
429 template<typename T>
431  T&& val, description d=description(), std::vector<label_instance> labels = {}) {
432  return {name, {impl::data_type::DERIVE, "derive"}, make_function(std::forward<T>(val), impl::data_type::DERIVE), d, labels};
433 }
434 
435 
444 template<typename T>
446  T&& val) {
447  return {name, {impl::data_type::DERIVE, "derive"}, make_function(std::forward<T>(val), impl::data_type::DERIVE), d, {}};
448 }
449 
450 
459 template<typename T>
460 impl::metric_definition_impl make_derive(metric_name_type name, description d, std::vector<label_instance> labels,
461  T&& val) {
462  return {name, {impl::data_type::DERIVE, "derive"}, make_function(std::forward<T>(val), impl::data_type::DERIVE), d, labels};
463 }
464 
465 
473 template<typename T>
475  T&& val, description d=description(), std::vector<label_instance> labels = {}) {
476  return {name, {impl::data_type::COUNTER, "counter"}, make_function(std::forward<T>(val), impl::data_type::COUNTER), d, labels};
477 }
478 
485 template<typename T>
487  T&& val, description d=description(), std::vector<label_instance> labels = {}) {
488  return {name, {impl::data_type::ABSOLUTE, "absolute"}, make_function(std::forward<T>(val), impl::data_type::ABSOLUTE), d, labels};
489 }
490 
497 template<typename T>
499  T&& val, description d=description(), std::vector<label_instance> labels = {}) {
500  return {name, {impl::data_type::HISTOGRAM, "histogram"}, make_function(std::forward<T>(val), impl::data_type::HISTOGRAM), d, labels};
501 }
502 
509 template<typename T>
511  description d, std::vector<label_instance> labels, T&& val) {
512  return {name, {impl::data_type::HISTOGRAM, "histogram"}, make_function(std::forward<T>(val), impl::data_type::HISTOGRAM), d, labels};
513 }
514 
515 
522 template<typename T>
524  description d, T&& val) {
525  return {name, {impl::data_type::HISTOGRAM, "histogram"}, make_function(std::forward<T>(val), impl::data_type::HISTOGRAM), d, {}};
526 }
527 
528 
536 template<typename T>
538  T&& val, description d=description(), std::vector<label_instance> labels = {},
539  instance_id_type instance = impl::shard()) {
540  return make_derive(name, std::forward<T>(val), d, labels).set_type("total_bytes");
541 }
542 
550 template<typename T>
552  T&& val, description d=description(), std::vector<label_instance> labels = {},
553  instance_id_type instance = impl::shard()) {
554  return make_derive(name, std::forward<T>(val), d, labels).set_type("bytes");
555 }
556 
557 
564 template<typename T>
566  T&& val, description d=description(), std::vector<label_instance> labels = {},
567  instance_id_type instance = impl::shard()) {
568  return make_gauge(name, std::forward<T>(val), d, labels).set_type("queue_length");
569 }
570 
571 
578 template<typename T>
580  T&& val, description d=description(), std::vector<label_instance> labels = {},
581  instance_id_type instance = impl::shard()) {
582  return make_derive(name, std::forward<T>(val), d, labels).set_type("total_operations");
583 }
584 
586 }
587 }
seastar::metrics::make_absolute
impl::metric_definition_impl make_absolute(metric_name_type name, T &&val, description d=description(), std::vector< label_instance > labels={})
create an absolute metric.
Definition: metrics.hh:486
seastar::metrics::double_registration
Definition: metrics.hh:93
seastar::metrics::impl::is_callable
Definition: metrics.hh:352
seastar
Seastar API namespace.
Definition: abort_on_ebadf.hh:24
seastar::metrics::label_instance::value
const sstring value() const
returns the label value
Definition: metrics.hh:180
seastar::metrics::histogram
Histogram data type.
Definition: metrics_types.hh:48
seastar::metrics::label_instance::label_instance
label_instance(const sstring &key, T v)
create a label_instance label instance consists of key and value. The key is an sstring....
Definition: metrics.hh:168
seastar::metrics::description
Human-readable description of a metric/group.
Definition: metrics.hh:123
seastar::metrics::make_total_operations
impl::metric_definition_impl make_total_operations(metric_name_type name, T &&val, description d=description(), std::vector< label_instance > labels={}, instance_id_type instance=impl::shard())
create a total operation metric.
Definition: metrics.hh:579
seastar::metrics::label::operator()
instance operator()(T value) const
creating a label instance
Definition: metrics.hh:231
seastar::metrics::label::name
const sstring & name() const
returns the label name
Definition: metrics.hh:238
seastar::metrics::instance_id_type
sstring instance_id_type
Definition: metrics.hh:106
seastar::metrics::label::label
label(const sstring &key)
creating a label key is the label name, it will be the key for all label_instance that will be create...
Definition: metrics.hh:215
seastar::metrics::group_name_type
sstring group_name_type
Definition: metrics_registration.hh:59
seastar::metrics::label_instance
Label a metrics.
Definition: metrics.hh:151
seastar::metrics::make_current_bytes
impl::metric_definition_impl make_current_bytes(metric_name_type name, T &&val, description d=description(), std::vector< label_instance > labels={}, instance_id_type instance=impl::shard())
create a current_bytes metric.
Definition: metrics.hh:551
seastar::metrics::metric_definition
Definition: metrics_registration.hh:62
seastar::metrics::make_queue_length
impl::metric_definition_impl make_queue_length(metric_name_type name, T &&val, description d=description(), std::vector< label_instance > labels={}, instance_id_type instance=impl::shard())
create a queue_length metric.
Definition: metrics.hh:565
seastar::metrics::make_gauge
impl::metric_definition_impl make_gauge(metric_name_type name, T &&val, description d=description(), std::vector< label_instance > labels={})
Gauge are a general purpose metric.
Definition: metrics.hh:393
seastar::metrics::impl::metric_type
Definition: metrics.hh:315
seastar::metrics::impl::metric_definition_impl
Definition: metrics.hh:320
seastar::metrics::metric_type_def
sstring metric_type_def
Definition: metrics.hh:104
impl
holds the implementation parts of the metrics layer, do not use directly.
seastar::metrics::impl::metric_value
A helper class that used to return metrics value.
Definition: metrics.hh:266
seastar::metrics::make_total_bytes
impl::metric_definition_impl make_total_bytes(metric_name_type name, T &&val, description d=description(), std::vector< label_instance > labels={}, instance_id_type instance=impl::shard())
create a total_bytes metric.
Definition: metrics.hh:537
seastar::metrics::make_counter
impl::metric_definition_impl make_counter(metric_name_type name, T &&val, description d=description(), std::vector< label_instance > labels={})
create a counter metric
Definition: metrics.hh:474
metrics_registration.hh
holds the metric_groups definition needed by class that reports metrics
seastar::metrics::make_derive
impl::metric_definition_impl make_derive(metric_name_type name, T &&val, description d=description(), std::vector< label_instance > labels={})
Derive are used when a rate is more interesting than the value.
Definition: metrics.hh:430
seastar::metrics::impl::metric_groups_def
Definition: metrics.hh:338
seastar::metrics::label
Class that creates label instances.
Definition: metrics.hh:206
seastar::metrics::metric_name_type
sstring metric_name_type
Definition: metrics.hh:105
seastar::metrics::label_instance::key
const sstring key() const
returns the label key
Definition: metrics.hh:173
seastar::metrics::make_histogram
impl::metric_definition_impl make_histogram(metric_name_type name, T &&val, description d=description(), std::vector< label_instance > labels={})
create a histogram metric.
Definition: metrics.hh:498