diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/monlib/dynamic_counters/encode.cpp | |
download | ydb-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.cpp | 131 |
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(); + } + +} |