aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/monlib/dynamic_counters/encode.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/monlib/dynamic_counters/encode.cpp
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/monlib/dynamic_counters/encode.cpp')
-rw-r--r--library/cpp/monlib/dynamic_counters/encode.cpp131
1 files changed, 131 insertions, 0 deletions
diff --git a/library/cpp/monlib/dynamic_counters/encode.cpp b/library/cpp/monlib/dynamic_counters/encode.cpp
new file mode 100644
index 0000000000..ffa48d276e
--- /dev/null
+++ b/library/cpp/monlib/dynamic_counters/encode.cpp
@@ -0,0 +1,131 @@
+#include "encode.h"
+
+#include <library/cpp/monlib/encode/encoder.h>
+#include <library/cpp/monlib/encode/json/json.h>
+#include <library/cpp/monlib/encode/spack/spack_v1.h>
+#include <library/cpp/monlib/encode/prometheus/prometheus.h>
+
+#include <util/stream/str.h>
+
+namespace NMonitoring {
+ namespace {
+ constexpr TInstant ZERO_TIME = TInstant::Zero();
+
+ class TConsumer final: public ICountableConsumer {
+ using TLabel = std::pair<TString, TString>; // name, value
+
+ public:
+ explicit TConsumer(NMonitoring::IMetricEncoderPtr encoderImpl, TCountableBase::EVisibility vis)
+ : EncoderImpl_(std::move(encoderImpl))
+ , Visibility_{vis}
+ {
+ }
+
+ void OnCounter(
+ const TString& labelName, const TString& labelValue,
+ const TCounterForPtr* counter) override {
+ NMonitoring::EMetricType metricType = counter->ForDerivative()
+ ? NMonitoring::EMetricType::RATE
+ : NMonitoring::EMetricType::GAUGE;
+ EncoderImpl_->OnMetricBegin(metricType);
+ EncodeLabels(labelName, labelValue);
+
+ if (metricType == NMonitoring::EMetricType::GAUGE) {
+ EncoderImpl_->OnDouble(ZERO_TIME, static_cast<double>(counter->Val()));
+ } else {
+ EncoderImpl_->OnUint64(ZERO_TIME, counter->Val());
+ }
+
+ EncoderImpl_->OnMetricEnd();
+ }
+
+ void OnHistogram(
+ const TString& labelName, const TString& labelValue,
+ IHistogramSnapshotPtr snapshot, bool derivative) override {
+ NMonitoring::EMetricType metricType = derivative ? EMetricType::HIST_RATE : EMetricType::HIST;
+
+ EncoderImpl_->OnMetricBegin(metricType);
+ EncodeLabels(labelName, labelValue);
+ EncoderImpl_->OnHistogram(ZERO_TIME, snapshot);
+ EncoderImpl_->OnMetricEnd();
+ }
+
+ void OnGroupBegin(
+ const TString& labelName, const TString& labelValue,
+ const TDynamicCounters*) override {
+ if (labelName.empty() && labelValue.empty()) {
+ // root group has empty label name and value
+ EncoderImpl_->OnStreamBegin();
+ } else {
+ ParentLabels_.emplace_back(labelName, labelValue);
+ }
+ }
+
+ void OnGroupEnd(
+ const TString& labelName, const TString& labelValue,
+ const TDynamicCounters*) override {
+ if (labelName.empty() && labelValue.empty()) {
+ // root group has empty label name and value
+ EncoderImpl_->OnStreamEnd();
+ EncoderImpl_->Close();
+ } else {
+ ParentLabels_.pop_back();
+ }
+ }
+
+ TCountableBase::EVisibility Visibility() const override {
+ return Visibility_;
+ }
+
+ private:
+ void EncodeLabels(const TString& labelName, const TString& labelValue) {
+ EncoderImpl_->OnLabelsBegin();
+ for (const auto& label : ParentLabels_) {
+ EncoderImpl_->OnLabel(label.first, label.second);
+ }
+ EncoderImpl_->OnLabel(labelName, labelValue);
+ EncoderImpl_->OnLabelsEnd();
+ }
+
+ private:
+ NMonitoring::IMetricEncoderPtr EncoderImpl_;
+ TVector<TLabel> ParentLabels_;
+ TCountableBase::EVisibility Visibility_;
+ };
+
+ }
+
+ THolder<ICountableConsumer> CreateEncoder(IOutputStream* out, EFormat format, TCountableBase::EVisibility vis) {
+ switch (format) {
+ case EFormat::JSON:
+ return MakeHolder<TConsumer>(NMonitoring::EncoderJson(out), vis);
+ case EFormat::SPACK:
+ return MakeHolder<TConsumer>(NMonitoring::EncoderSpackV1(
+ out,
+ NMonitoring::ETimePrecision::SECONDS,
+ NMonitoring::ECompression::ZSTD), vis);
+ case EFormat::PROMETHEUS:
+ return MakeHolder<TConsumer>(NMonitoring::EncoderPrometheus(
+ out), vis);
+ default:
+ ythrow yexception() << "unsupported metric encoding format: " << format;
+ break;
+ }
+ }
+
+ THolder<ICountableConsumer> AsCountableConsumer(IMetricEncoderPtr encoder, TCountableBase::EVisibility visibility) {
+ return MakeHolder<TConsumer>(std::move(encoder), visibility);
+ }
+
+ void ToJson(const TDynamicCounters& counters, IOutputStream* out) {
+ TConsumer consumer{EncoderJson(out), TCountableBase::EVisibility::Public};
+ counters.Accept(TString{}, TString{}, consumer);
+ }
+
+ TString ToJson(const TDynamicCounters& counters) {
+ TStringStream ss;
+ ToJson(counters, &ss);
+ return ss.Str();
+ }
+
+}