metric_registry.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #include "metric_registry.h"
  2. #include <memory>
  3. namespace NMonitoring {
  4. namespace {
  5. void ConsumeLabels(IMetricConsumer* consumer, const ILabels& labels) {
  6. for (auto&& label: labels) {
  7. consumer->OnLabel(label.Name(), label.Value());
  8. }
  9. }
  10. template <typename TLabelsConsumer>
  11. void ConsumeMetric(TInstant time, IMetricConsumer* consumer, IMetric* metric, TLabelsConsumer&& labelsConsumer) {
  12. consumer->OnMetricBegin(metric->Type());
  13. // (1) add labels
  14. consumer->OnLabelsBegin();
  15. labelsConsumer();
  16. consumer->OnLabelsEnd();
  17. // (2) add time and value
  18. metric->Accept(time, consumer);
  19. consumer->OnMetricEnd();
  20. }
  21. }
  22. void WriteLabels(IMetricConsumer* consumer, const ILabels& labels) {
  23. consumer->OnLabelsBegin();
  24. ConsumeLabels(consumer, labels);
  25. consumer->OnLabelsEnd();
  26. }
  27. TMetricRegistry::TMetricRegistry() = default;
  28. TMetricRegistry::~TMetricRegistry() = default;
  29. TMetricRegistry::TMetricRegistry(const TLabels& commonLabels)
  30. : TMetricRegistry{}
  31. {
  32. CommonLabels_ = commonLabels;
  33. }
  34. TMetricRegistry* TMetricRegistry::Instance() {
  35. return Singleton<TMetricRegistry>();
  36. }
  37. TGauge* TMetricRegistry::Gauge(TLabels labels) {
  38. return Metric<TGauge, EMetricType::GAUGE>(std::move(labels));
  39. }
  40. TGauge* TMetricRegistry::Gauge(ILabelsPtr labels) {
  41. return Metric<TGauge, EMetricType::GAUGE>(std::move(labels));
  42. }
  43. TLazyGauge* TMetricRegistry::LazyGauge(TLabels labels, std::function<double()> supplier) {
  44. return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier));
  45. }
  46. TLazyGauge* TMetricRegistry::LazyGauge(ILabelsPtr labels, std::function<double()> supplier) {
  47. return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier));
  48. }
  49. TIntGauge* TMetricRegistry::IntGauge(TLabels labels) {
  50. return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels));
  51. }
  52. TIntGauge* TMetricRegistry::IntGauge(ILabelsPtr labels) {
  53. return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels));
  54. }
  55. TLazyIntGauge* TMetricRegistry::LazyIntGauge(TLabels labels, std::function<i64()> supplier) {
  56. return Metric<TLazyIntGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier));
  57. }
  58. TLazyIntGauge* TMetricRegistry::LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) {
  59. return Metric<TLazyIntGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier));
  60. }
  61. TCounter* TMetricRegistry::Counter(TLabels labels) {
  62. return Metric<TCounter, EMetricType::COUNTER>(std::move(labels));
  63. }
  64. TCounter* TMetricRegistry::Counter(ILabelsPtr labels) {
  65. return Metric<TCounter, EMetricType::COUNTER>(std::move(labels));
  66. }
  67. TLazyCounter* TMetricRegistry::LazyCounter(TLabels labels, std::function<ui64()> supplier) {
  68. return Metric<TLazyCounter, EMetricType::COUNTER>(std::move(labels), std::move(supplier));
  69. }
  70. TLazyCounter* TMetricRegistry::LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) {
  71. return Metric<TLazyCounter, EMetricType::COUNTER>(std::move(labels), std::move(supplier));
  72. }
  73. TRate* TMetricRegistry::Rate(TLabels labels) {
  74. return Metric<TRate, EMetricType::RATE>(std::move(labels));
  75. }
  76. TRate* TMetricRegistry::Rate(ILabelsPtr labels) {
  77. return Metric<TRate, EMetricType::RATE>(std::move(labels));
  78. }
  79. TLazyRate* TMetricRegistry::LazyRate(TLabels labels, std::function<ui64()> supplier) {
  80. return Metric<TLazyRate, EMetricType::RATE>(std::move(labels), std::move(supplier));
  81. }
  82. TLazyRate* TMetricRegistry::LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) {
  83. return Metric<TLazyRate, EMetricType::RATE>(std::move(labels), std::move(supplier));
  84. }
  85. THistogram* TMetricRegistry::HistogramCounter(TLabels labels, IHistogramCollectorPtr collector) {
  86. return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(collector), false);
  87. }
  88. THistogram* TMetricRegistry::HistogramCounter(ILabelsPtr labels, IHistogramCollectorPtr collector) {
  89. return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(collector), false);
  90. }
  91. THistogram* TMetricRegistry::HistogramRate(TLabels labels, IHistogramCollectorPtr collector) {
  92. return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(collector), true);
  93. }
  94. THistogram* TMetricRegistry::HistogramRate(ILabelsPtr labels, IHistogramCollectorPtr collector) {
  95. return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(collector), true);
  96. }
  97. void TMetricRegistry::Reset() {
  98. TWriteGuard g{Lock_};
  99. for (auto& [label, metric] : Metrics_) {
  100. switch (metric->Type()) {
  101. case EMetricType::GAUGE:
  102. static_cast<TGauge*>(metric.Get())->Set(.0);
  103. break;
  104. case EMetricType::IGAUGE:
  105. static_cast<TIntGauge*>(metric.Get())->Set(0);
  106. break;
  107. case EMetricType::COUNTER:
  108. static_cast<TCounter*>(metric.Get())->Reset();
  109. break;
  110. case EMetricType::RATE:
  111. static_cast<TRate*>(metric.Get())->Reset();
  112. break;
  113. case EMetricType::HIST:
  114. case EMetricType::HIST_RATE:
  115. static_cast<THistogram*>(metric.Get())->Reset();
  116. break;
  117. case EMetricType::UNKNOWN:
  118. case EMetricType::DSUMMARY:
  119. case EMetricType::LOGHIST:
  120. break;
  121. }
  122. }
  123. }
  124. void TMetricRegistry::Clear() {
  125. TWriteGuard g{Lock_};
  126. Metrics_.clear();
  127. }
  128. template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args>
  129. TMetric* TMetricRegistry::Metric(TLabelsType&& labels, Args&&... args) {
  130. {
  131. TReadGuard g{Lock_};
  132. auto it = Metrics_.find(labels);
  133. if (it != Metrics_.end()) {
  134. Y_ENSURE(it->second->Type() == type, "cannot create metric " << labels
  135. << " with type " << MetricTypeToStr(type)
  136. << ", because registry already has same metric with type " << MetricTypeToStr(it->second->Type()));
  137. return static_cast<TMetric*>(it->second.Get());
  138. }
  139. }
  140. {
  141. IMetricPtr metric = MakeHolder<TMetric>(std::forward<Args>(args)...);
  142. TWriteGuard g{Lock_};
  143. // decltype(Metrics_)::iterator breaks build on windows
  144. THashMap<ILabelsPtr, IMetricPtr>::iterator it;
  145. if constexpr (!std::is_convertible_v<TLabelsType, ILabelsPtr>) {
  146. it = Metrics_.emplace(new TLabels{std::forward<TLabelsType>(labels)}, std::move(metric)).first;
  147. } else {
  148. it = Metrics_.emplace(std::forward<TLabelsType>(labels), std::move(metric)).first;
  149. }
  150. return static_cast<TMetric*>(it->second.Get());
  151. }
  152. }
  153. void TMetricRegistry::RemoveMetric(const ILabels& labels) noexcept {
  154. TWriteGuard g{Lock_};
  155. Metrics_.erase(labels);
  156. }
  157. void TMetricRegistry::Accept(TInstant time, IMetricConsumer* consumer) const {
  158. consumer->OnStreamBegin();
  159. if (!CommonLabels_.Empty()) {
  160. consumer->OnLabelsBegin();
  161. ConsumeLabels(consumer, CommonLabels_);
  162. consumer->OnLabelsEnd();
  163. }
  164. {
  165. TReadGuard g{Lock_};
  166. for (const auto& it: Metrics_) {
  167. ILabels* labels = it.first.Get();
  168. IMetric* metric = it.second.Get();
  169. ConsumeMetric(time, consumer, metric, [&]() {
  170. ConsumeLabels(consumer, *labels);
  171. });
  172. }
  173. }
  174. consumer->OnStreamEnd();
  175. }
  176. void TMetricRegistry::Append(TInstant time, IMetricConsumer* consumer) const {
  177. TReadGuard g{Lock_};
  178. for (const auto& it: Metrics_) {
  179. ILabels* labels = it.first.Get();
  180. IMetric* metric = it.second.Get();
  181. ConsumeMetric(time, consumer, metric, [&]() {
  182. ConsumeLabels(consumer, CommonLabels_);
  183. ConsumeLabels(consumer, *labels);
  184. });
  185. }
  186. }
  187. }