gauge.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #pragma once
  2. #include "prometheus/atomic_floating.h"
  3. #include "prometheus/metric.h"
  4. #include "prometheus/family.h"
  5. #include "prometheus/builder.h"
  6. #include <atomic>
  7. #include <ctime>
  8. namespace prometheus {
  9. /// \brief A gauge metric to represent a value that can arbitrarily go up and
  10. /// down.
  11. ///
  12. /// The class represents the metric type gauge:
  13. /// https://prometheus.io/docs/concepts/metric_types/#gauge
  14. ///
  15. /// Gauges are typically used for measured values like temperatures or current
  16. /// memory usage, but also "counts" that can go up and down, like the number of
  17. /// running processes.
  18. ///
  19. /// The class is thread-safe. No concurrent call to any API of this type causes
  20. /// a data race.
  21. #include <stdint.h>
  22. #if UINTPTR_MAX == 0xffFFffFF
  23. // 32-bit
  24. template <typename Value_ = uint32_t>
  25. #elif UINTPTR_MAX == 0xffFFffFFffFFffFF
  26. // 64-bit
  27. template <typename Value_ = uint64_t>
  28. #else
  29. #error Unknown platform - does not look either like 32-bit or 64-bit
  30. #endif
  31. class Gauge : public Metric {
  32. std::atomic<Value_> value { 0 };
  33. public:
  34. using Value = Value_;
  35. using Family = CustomFamily<Gauge<Value>>;
  36. static const Metric::Type static_type = Metric::Type::Gauge;
  37. Gauge() : Metric (static_type) {} ///< \brief Create a gauge that starts at 0.
  38. Gauge(const Value value_) : Metric(static_type), value{ value_ } {} ///< \brief Create a gauge that starts at the given amount.
  39. Gauge(const Gauge<Value_> &rhs) : Metric(rhs.static_type), value{rhs.value.load()} {}
  40. // original API
  41. void Increment() { ++value; } ///< \brief Increment the gauge by 1.
  42. void Increment(const Value& val) { value += val; } ///< \brief Increment the gauge by the given amount.
  43. void Decrement() { --value; } ///< \brief Decrement the gauge by 1.
  44. void Decrement(const Value& val) { value -= val; } ///< \brief Decrement the gauge by the given amount.
  45. void SetToCurrentTime() { ///< \brief Set the gauge to the current unixtime in seconds.
  46. const time_t time = std::time(nullptr);
  47. value = static_cast<Value>(time);
  48. }
  49. void Set(const Value& val) { value = val; } ///< \brief Set the gauge to the given value.
  50. const Value Get() const { return value; } ///< \brief Get the current value of the gauge.
  51. virtual ClientMetric Collect() const { ///< \brief Get the current value of the gauge. Collect is called by the Registry when collecting metrics.
  52. ClientMetric metric;
  53. metric.gauge.value = static_cast<double>(value);
  54. return metric;
  55. }
  56. // new API
  57. Gauge& operator ++() {
  58. ++value;
  59. return *this;
  60. }
  61. Gauge& operator++ (int) {
  62. ++value;
  63. return *this;
  64. }
  65. Gauge& operator --() {
  66. --value;
  67. return *this;
  68. }
  69. Gauge& operator-- (int) {
  70. --value;
  71. return *this;
  72. }
  73. Gauge& operator+=(const Value& val) {
  74. value += val;
  75. return *this;
  76. }
  77. Gauge& operator-=(const Value& val) {
  78. value -= val;
  79. return *this;
  80. }
  81. };
  82. /// \brief Return a builder to configure and register a Gauge metric.
  83. ///
  84. /// @copydetails Family<>::Family()
  85. ///
  86. /// Example usage:
  87. ///
  88. /// \code
  89. /// auto registry = std::make_shared<Registry>();
  90. /// auto& gauge_family = prometheus::BuildGauge()
  91. /// .Name("some_name")
  92. /// .Help("Additional description.")
  93. /// .Labels({{"key", "value"}})
  94. /// .Register(*registry);
  95. ///
  96. /// ...
  97. /// \endcode
  98. ///
  99. /// \return An object of unspecified type T, i.e., an implementation detail
  100. /// except that it has the following members:
  101. ///
  102. /// - Name(const std::string&) to set the metric name,
  103. /// - Help(const std::string&) to set an additional description.
  104. /// - Label(const std::map<std::string, std::string>&) to assign a set of
  105. /// key-value pairs (= labels) to the metric.
  106. ///
  107. /// To finish the configuration of the Gauge metric register it with
  108. /// Register(Registry&).
  109. using BuildGauge = Builder<Gauge<double>>;
  110. } // namespace prometheus