metric_registry.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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(TMetricRegistry&& other) = default;
  29. TMetricRegistry::~TMetricRegistry() = default;
  30. TMetricRegistry::TMetricRegistry(const TLabels& commonLabels)
  31. : TMetricRegistry{}
  32. {
  33. CommonLabels_ = commonLabels;
  34. }
  35. TMetricRegistry& TMetricRegistry::operator=(TMetricRegistry&& other) = default;
  36. TMetricRegistry* TMetricRegistry::Instance() {
  37. //return SharedInstance().get();
  38. return Singleton<TMetricRegistry>();
  39. }
  40. std::shared_ptr<TMetricRegistry> TMetricRegistry::SharedInstance() {
  41. static auto instance(std::make_shared<TMetricRegistry>());
  42. return instance;
  43. }
  44. TGauge* TMetricRegistry::Gauge(TLabels labels) {
  45. return Metric<TGauge, EMetricType::GAUGE>(std::move(labels));
  46. }
  47. TGauge* TMetricRegistry::Gauge(ILabelsPtr labels) {
  48. return Metric<TGauge, EMetricType::GAUGE>(std::move(labels));
  49. }
  50. TLazyGauge* TMetricRegistry::LazyGauge(TLabels labels, std::function<double()> supplier) {
  51. return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier));
  52. }
  53. TLazyGauge* TMetricRegistry::LazyGauge(ILabelsPtr labels, std::function<double()> supplier) {
  54. return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier));
  55. }
  56. TIntGauge* TMetricRegistry::IntGauge(TLabels labels) {
  57. return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels));
  58. }
  59. TIntGauge* TMetricRegistry::IntGauge(ILabelsPtr labels) {
  60. return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels));
  61. }
  62. TLazyIntGauge* TMetricRegistry::LazyIntGauge(TLabels labels, std::function<i64()> supplier) {
  63. return Metric<TLazyIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(supplier));
  64. }
  65. TLazyIntGauge* TMetricRegistry::LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) {
  66. return Metric<TLazyIntGauge, EMetricType::IGAUGE>(std::move(labels), std::move(supplier));
  67. }
  68. TCounter* TMetricRegistry::Counter(TLabels labels) {
  69. return Metric<TCounter, EMetricType::COUNTER>(std::move(labels));
  70. }
  71. TCounter* TMetricRegistry::Counter(ILabelsPtr labels) {
  72. return Metric<TCounter, EMetricType::COUNTER>(std::move(labels));
  73. }
  74. TLazyCounter* TMetricRegistry::LazyCounter(TLabels labels, std::function<ui64()> supplier) {
  75. return Metric<TLazyCounter, EMetricType::COUNTER>(std::move(labels), std::move(supplier));
  76. }
  77. TLazyCounter* TMetricRegistry::LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) {
  78. return Metric<TLazyCounter, EMetricType::COUNTER>(std::move(labels), std::move(supplier));
  79. }
  80. TRate* TMetricRegistry::Rate(TLabels labels) {
  81. return Metric<TRate, EMetricType::RATE>(std::move(labels));
  82. }
  83. TRate* TMetricRegistry::Rate(ILabelsPtr labels) {
  84. return Metric<TRate, EMetricType::RATE>(std::move(labels));
  85. }
  86. TLazyRate* TMetricRegistry::LazyRate(TLabels labels, std::function<ui64()> supplier) {
  87. return Metric<TLazyRate, EMetricType::RATE>(std::move(labels), std::move(supplier));
  88. }
  89. TLazyRate* TMetricRegistry::LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) {
  90. return Metric<TLazyRate, EMetricType::RATE>(std::move(labels), std::move(supplier));
  91. }
  92. THistogram* TMetricRegistry::HistogramCounter(TLabels labels, IHistogramCollectorPtr collector) {
  93. return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(collector), false);
  94. }
  95. THistogram* TMetricRegistry::HistogramCounter(ILabelsPtr labels, IHistogramCollectorPtr collector) {
  96. return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(collector), false);
  97. }
  98. THistogram* TMetricRegistry::HistogramCounter(TLabels labels, std::function<IHistogramCollectorPtr()> supplier) {
  99. return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(supplier), false);
  100. }
  101. THistogram* TMetricRegistry::HistogramCounter(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> supplier) {
  102. return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(supplier), false);
  103. }
  104. THistogram* TMetricRegistry::HistogramRate(TLabels labels, IHistogramCollectorPtr collector) {
  105. return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(collector), true);
  106. }
  107. THistogram* TMetricRegistry::HistogramRate(ILabelsPtr labels, IHistogramCollectorPtr collector) {
  108. return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(collector), true);
  109. }
  110. THistogram* TMetricRegistry::HistogramRate(TLabels labels, std::function<IHistogramCollectorPtr()> supplier) {
  111. return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(supplier), true);
  112. }
  113. THistogram* TMetricRegistry::HistogramRate(ILabelsPtr labels, std::function<IHistogramCollectorPtr()> supplier) {
  114. return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(supplier), true);
  115. }
  116. void TMetricRegistry::Reset() {
  117. TWriteGuard g{*Lock_};
  118. for (auto& [label, metric] : Metrics_) {
  119. switch (metric->Type()) {
  120. case EMetricType::GAUGE:
  121. static_cast<TGauge*>(metric.Get())->Set(.0);
  122. break;
  123. case EMetricType::IGAUGE:
  124. static_cast<TIntGauge*>(metric.Get())->Set(0);
  125. break;
  126. case EMetricType::COUNTER:
  127. static_cast<TCounter*>(metric.Get())->Reset();
  128. break;
  129. case EMetricType::RATE:
  130. static_cast<TRate*>(metric.Get())->Reset();
  131. break;
  132. case EMetricType::HIST:
  133. case EMetricType::HIST_RATE:
  134. static_cast<THistogram*>(metric.Get())->Reset();
  135. break;
  136. case EMetricType::UNKNOWN:
  137. case EMetricType::DSUMMARY:
  138. case EMetricType::LOGHIST:
  139. break;
  140. }
  141. }
  142. }
  143. void TMetricRegistry::Clear() {
  144. TWriteGuard g{*Lock_};
  145. Metrics_.clear();
  146. }
  147. template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args>
  148. TMetric* TMetricRegistry::Metric(TLabelsType&& labels, Args&&... args) {
  149. {
  150. TReadGuard g{*Lock_};
  151. auto it = Metrics_.find(labels);
  152. if (it != Metrics_.end()) {
  153. Y_ENSURE(it->second->Type() == type, "cannot create metric " << labels
  154. << " with type " << MetricTypeToStr(type)
  155. << ", because registry already has same metric with type " << MetricTypeToStr(it->second->Type()));
  156. return static_cast<TMetric*>(it->second.Get());
  157. }
  158. }
  159. {
  160. IMetricPtr metric = MakeIntrusive<TMetric>(std::forward<Args>(args)...);
  161. TWriteGuard g{*Lock_};
  162. // decltype(Metrics_)::iterator breaks build on windows
  163. THashMap<ILabelsPtr, IMetricPtr>::iterator it;
  164. if constexpr (!std::is_convertible_v<TLabelsType, ILabelsPtr>) {
  165. it = Metrics_.emplace(new TLabels{std::forward<TLabelsType>(labels)}, std::move(metric)).first;
  166. } else {
  167. it = Metrics_.emplace(std::forward<TLabelsType>(labels), std::move(metric)).first;
  168. }
  169. return static_cast<TMetric*>(it->second.Get());
  170. }
  171. }
  172. void TMetricRegistry::RemoveMetric(const ILabels& labels) noexcept {
  173. TWriteGuard g{*Lock_};
  174. Metrics_.erase(labels);
  175. }
  176. void TMetricRegistry::Accept(TInstant time, IMetricConsumer* consumer) const {
  177. consumer->OnStreamBegin();
  178. if (!CommonLabels_.Empty()) {
  179. consumer->OnLabelsBegin();
  180. ConsumeLabels(consumer, CommonLabels_);
  181. consumer->OnLabelsEnd();
  182. }
  183. TVector<std::pair<ILabelsPtr, IMetricPtr>> tmpMetrics;
  184. {
  185. TReadGuard g{*Lock_};
  186. tmpMetrics.reserve(Metrics_.size());
  187. for (const auto& it: Metrics_) {
  188. tmpMetrics.push_back(it);
  189. }
  190. }
  191. for (const auto& it: tmpMetrics) {
  192. ILabels* labels = it.first.Get();
  193. IMetric* metric = it.second.Get();
  194. ConsumeMetric(time, consumer, metric, [&]() {
  195. ConsumeLabels(consumer, *labels);
  196. });
  197. }
  198. consumer->OnStreamEnd();
  199. }
  200. void TMetricRegistry::Append(TInstant time, IMetricConsumer* consumer) const {
  201. TReadGuard g{*Lock_};
  202. for (const auto& it: Metrics_) {
  203. ILabels* labels = it.first.Get();
  204. IMetric* metric = it.second.Get();
  205. ConsumeMetric(time, consumer, metric, [&]() {
  206. ConsumeLabels(consumer, CommonLabels_);
  207. ConsumeLabels(consumer, *labels);
  208. });
  209. }
  210. }
  211. }