aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/monlib/encode/json
diff options
context:
space:
mode:
authorivanzhukov <ivanzhukov@yandex-team.ru>2022-02-10 16:49:40 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:49:40 +0300
commit0892d79ab411592ad25175c4bdadbcb09b466cf5 (patch)
tree98dfdd45463c9bd747101748a9ca25d2917390fd /library/cpp/monlib/encode/json
parent1b7466cb957659079ebebbb5d76e64e51f3306f0 (diff)
downloadydb-0892d79ab411592ad25175c4bdadbcb09b466cf5.tar.gz
Restoring authorship annotation for <ivanzhukov@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/monlib/encode/json')
-rw-r--r--library/cpp/monlib/encode/json/json.h10
-rw-r--r--library/cpp/monlib/encode/json/json_decoder.cpp2142
-rw-r--r--library/cpp/monlib/encode/json/json_decoder_ut.cpp228
-rw-r--r--library/cpp/monlib/encode/json/json_encoder.cpp40
-rw-r--r--library/cpp/monlib/encode/json/json_ut.cpp44
-rw-r--r--library/cpp/monlib/encode/json/typed_point.h4
-rw-r--r--library/cpp/monlib/encode/json/ut/buffered_ts_merge.json2
-rw-r--r--library/cpp/monlib/encode/json/ut/histogram_value_inf_before_bounds.json64
-rw-r--r--library/cpp/monlib/encode/json/ut/test_decode_to_encode.json30
-rw-r--r--library/cpp/monlib/encode/json/ut/ya.make8
-rw-r--r--library/cpp/monlib/encode/json/ya.make6
11 files changed, 1289 insertions, 1289 deletions
diff --git a/library/cpp/monlib/encode/json/json.h b/library/cpp/monlib/encode/json/json.h
index 21530f20c3..b76900b8ab 100644
--- a/library/cpp/monlib/encode/json/json.h
+++ b/library/cpp/monlib/encode/json/json.h
@@ -3,14 +3,14 @@
#include <library/cpp/monlib/encode/encoder.h>
#include <library/cpp/monlib/encode/format.h>
-
+
class IOutputStream;
namespace NMonitoring {
-
- class TJsonDecodeError: public yexception {
- };
-
+
+ class TJsonDecodeError: public yexception {
+ };
+
IMetricEncoderPtr EncoderJson(IOutputStream* out, int indentation = 0);
/// Buffered encoder will merge series with same labels into one.
diff --git a/library/cpp/monlib/encode/json/json_decoder.cpp b/library/cpp/monlib/encode/json/json_decoder.cpp
index d44ff5fd28..7f0d83e018 100644
--- a/library/cpp/monlib/encode/json/json_decoder.cpp
+++ b/library/cpp/monlib/encode/json/json_decoder.cpp
@@ -1,8 +1,8 @@
#include "json.h"
#include "typed_point.h"
-
-#include <library/cpp/monlib/exception/exception.h>
+
+#include <library/cpp/monlib/exception/exception.h>
#include <library/cpp/monlib/metrics/labels.h>
#include <library/cpp/monlib/metrics/metric_value.h>
@@ -14,1149 +14,1149 @@
#include <limits>
namespace NMonitoring {
-
-#define DECODE_ENSURE(COND, ...) MONLIB_ENSURE_EX(COND, TJsonDecodeError() << __VA_ARGS__)
-
-namespace {
-
-///////////////////////////////////////////////////////////////////////
-// THistogramBuilder
-///////////////////////////////////////////////////////////////////////
-class THistogramBuilder {
-public:
- void AddBound(TBucketBound bound) {
- if (!Bounds_.empty()) {
- DECODE_ENSURE(Bounds_.back() < bound,
- "non sorted bounds, " << Bounds_.back() <<
- " >= " << bound);
- }
- Bounds_.push_back(bound);
- }
-
- void AddValue(TBucketValue value) {
- Values_.push_back(value);
- }
-
- void AddInf(TBucketValue value) {
- InfPresented_ = true;
- InfValue_ = value;
- }
-
- IHistogramSnapshotPtr Build() {
- if (InfPresented_) {
- Bounds_.push_back(Max<TBucketBound>());
- Values_.push_back(InfValue_);
- }
-
- auto snapshot = ExplicitHistogramSnapshot(Bounds_, Values_);
-
- Bounds_.clear();
- Values_.clear();
+
+#define DECODE_ENSURE(COND, ...) MONLIB_ENSURE_EX(COND, TJsonDecodeError() << __VA_ARGS__)
+
+namespace {
+
+///////////////////////////////////////////////////////////////////////
+// THistogramBuilder
+///////////////////////////////////////////////////////////////////////
+class THistogramBuilder {
+public:
+ void AddBound(TBucketBound bound) {
+ if (!Bounds_.empty()) {
+ DECODE_ENSURE(Bounds_.back() < bound,
+ "non sorted bounds, " << Bounds_.back() <<
+ " >= " << bound);
+ }
+ Bounds_.push_back(bound);
+ }
+
+ void AddValue(TBucketValue value) {
+ Values_.push_back(value);
+ }
+
+ void AddInf(TBucketValue value) {
+ InfPresented_ = true;
+ InfValue_ = value;
+ }
+
+ IHistogramSnapshotPtr Build() {
+ if (InfPresented_) {
+ Bounds_.push_back(Max<TBucketBound>());
+ Values_.push_back(InfValue_);
+ }
+
+ auto snapshot = ExplicitHistogramSnapshot(Bounds_, Values_);
+
+ Bounds_.clear();
+ Values_.clear();
InfPresented_ = false;
- return snapshot;
- }
-
- bool Empty() const noexcept {
- return Bounds_.empty() && Values_.empty();
- }
-
- void Clear() {
- Bounds_.clear();
- Values_.clear();
- }
-
-private:
- TBucketBounds Bounds_;
- TBucketValues Values_;
-
- bool InfPresented_ = false;
- TBucketValue InfValue_;
-};
-
-class TSummaryDoubleBuilder {
-public:
- ISummaryDoubleSnapshotPtr Build() const {
- return MakeIntrusive<TSummaryDoubleSnapshot>(Sum_, Min_, Max_, Last_, Count_);
- }
-
- void SetSum(double sum) {
- Empty_ = false;
- Sum_ = sum;
- }
-
- void SetMin(double min) {
- Empty_ = false;
- Min_ = min;
- }
-
- void SetMax(double max) {
- Empty_ = false;
- Max_ = max;
- }
-
- void SetLast(double last) {
- Empty_ = false;
- Last_ = last;
- }
-
- void SetCount(ui64 count) {
- Empty_ = false;
- Count_ = count;
- }
-
- void Clear() {
- Empty_ = true;
- Sum_ = 0;
- Min_ = 0;
- Max_ = 0;
- Last_ = 0;
- Count_ = 0;
- }
-
- bool Empty() const {
- return Empty_;
- }
-
-private:
- double Sum_ = 0;
- double Min_ = 0;
- double Max_ = 0;
- double Last_ = 0;
- ui64 Count_ = 0;
- bool Empty_ = true;
-};
-
-class TLogHistogramBuilder {
-public:
- void SetBase(double base) {
- DECODE_ENSURE(base > 0, "base must be positive");
- Base_ = base;
- }
-
- void SetZerosCount(ui64 zerosCount) {
- DECODE_ENSURE(zerosCount >= 0, "zeros count must be positive");
- ZerosCount_ = zerosCount;
- }
-
- void SetStartPower(int startPower) {
- StartPower_ = startPower;
- }
-
- void AddBucketValue(double value) {
- DECODE_ENSURE(value > 0.0, "bucket values must be positive");
- DECODE_ENSURE(value < std::numeric_limits<double>::max(), "bucket values must be finite");
- Buckets_.push_back(value);
- }
-
- void Clear() {
- Buckets_.clear();
- Base_ = 1.5;
- ZerosCount_ = 0;
- StartPower_ = 0;
- }
-
- bool Empty() const {
- return Buckets_.empty() && ZerosCount_ == 0;
- }
-
- TLogHistogramSnapshotPtr Build() {
- return MakeIntrusive<TLogHistogramSnapshot>(Base_, ZerosCount_, StartPower_, std::move(Buckets_));
- }
-
-private:
- double Base_ = 1.5;
- ui64 ZerosCount_ = 0;
- int StartPower_ = 0;
- TVector<double> Buckets_;
-};
-
-std::pair<double, bool> ParseSpecDouble(TStringBuf string) {
+ return snapshot;
+ }
+
+ bool Empty() const noexcept {
+ return Bounds_.empty() && Values_.empty();
+ }
+
+ void Clear() {
+ Bounds_.clear();
+ Values_.clear();
+ }
+
+private:
+ TBucketBounds Bounds_;
+ TBucketValues Values_;
+
+ bool InfPresented_ = false;
+ TBucketValue InfValue_;
+};
+
+class TSummaryDoubleBuilder {
+public:
+ ISummaryDoubleSnapshotPtr Build() const {
+ return MakeIntrusive<TSummaryDoubleSnapshot>(Sum_, Min_, Max_, Last_, Count_);
+ }
+
+ void SetSum(double sum) {
+ Empty_ = false;
+ Sum_ = sum;
+ }
+
+ void SetMin(double min) {
+ Empty_ = false;
+ Min_ = min;
+ }
+
+ void SetMax(double max) {
+ Empty_ = false;
+ Max_ = max;
+ }
+
+ void SetLast(double last) {
+ Empty_ = false;
+ Last_ = last;
+ }
+
+ void SetCount(ui64 count) {
+ Empty_ = false;
+ Count_ = count;
+ }
+
+ void Clear() {
+ Empty_ = true;
+ Sum_ = 0;
+ Min_ = 0;
+ Max_ = 0;
+ Last_ = 0;
+ Count_ = 0;
+ }
+
+ bool Empty() const {
+ return Empty_;
+ }
+
+private:
+ double Sum_ = 0;
+ double Min_ = 0;
+ double Max_ = 0;
+ double Last_ = 0;
+ ui64 Count_ = 0;
+ bool Empty_ = true;
+};
+
+class TLogHistogramBuilder {
+public:
+ void SetBase(double base) {
+ DECODE_ENSURE(base > 0, "base must be positive");
+ Base_ = base;
+ }
+
+ void SetZerosCount(ui64 zerosCount) {
+ DECODE_ENSURE(zerosCount >= 0, "zeros count must be positive");
+ ZerosCount_ = zerosCount;
+ }
+
+ void SetStartPower(int startPower) {
+ StartPower_ = startPower;
+ }
+
+ void AddBucketValue(double value) {
+ DECODE_ENSURE(value > 0.0, "bucket values must be positive");
+ DECODE_ENSURE(value < std::numeric_limits<double>::max(), "bucket values must be finite");
+ Buckets_.push_back(value);
+ }
+
+ void Clear() {
+ Buckets_.clear();
+ Base_ = 1.5;
+ ZerosCount_ = 0;
+ StartPower_ = 0;
+ }
+
+ bool Empty() const {
+ return Buckets_.empty() && ZerosCount_ == 0;
+ }
+
+ TLogHistogramSnapshotPtr Build() {
+ return MakeIntrusive<TLogHistogramSnapshot>(Base_, ZerosCount_, StartPower_, std::move(Buckets_));
+ }
+
+private:
+ double Base_ = 1.5;
+ ui64 ZerosCount_ = 0;
+ int StartPower_ = 0;
+ TVector<double> Buckets_;
+};
+
+std::pair<double, bool> ParseSpecDouble(TStringBuf string) {
if (string == TStringBuf("nan") || string == TStringBuf("NaN")) {
- return {std::numeric_limits<double>::quiet_NaN(), true};
+ return {std::numeric_limits<double>::quiet_NaN(), true};
} else if (string == TStringBuf("inf") || string == TStringBuf("Infinity")) {
- return {std::numeric_limits<double>::infinity(), true};
+ return {std::numeric_limits<double>::infinity(), true};
} else if (string == TStringBuf("-inf") || string == TStringBuf("-Infinity")) {
- return {-std::numeric_limits<double>::infinity(), true};
- } else {
- return {0, false};
- }
-}
-
-///////////////////////////////////////////////////////////////////////
-// TMetricCollector
-///////////////////////////////////////////////////////////////////////
-struct TMetricCollector {
- EMetricType Type = EMetricType::UNKNOWN;
- TLabels Labels;
- THistogramBuilder HistogramBuilder;
- TSummaryDoubleBuilder SummaryBuilder;
- TLogHistogramBuilder LogHistBuilder;
- TTypedPoint LastPoint;
- TVector<TTypedPoint> TimeSeries;
-
- bool SeenTsOrValue = false;
- bool SeenTimeseries = false;
-
- void Clear() {
- Type = EMetricType::UNKNOWN;
- Labels.Clear();
- SeenTsOrValue = false;
- SeenTimeseries = false;
- TimeSeries.clear();
- LastPoint = {};
- HistogramBuilder.Clear();
- SummaryBuilder.Clear();
- LogHistBuilder.Clear();
- }
-
- void AddLabel(const TLabel& label) {
- Labels.Add(label.Name(), label.Value());
- }
-
- void SetLastTime(TInstant time) {
- LastPoint.SetTime(time);
- }
-
- template <typename T>
- void SetLastValue(T value) {
- LastPoint.SetValue(value);
- }
-
- void SaveLastPoint() {
- DECODE_ENSURE(LastPoint.GetTime() != TInstant::Zero(),
- "cannot add point without or zero timestamp");
- if (!HistogramBuilder.Empty()) {
- auto histogram = HistogramBuilder.Build();
- TimeSeries.emplace_back(LastPoint.GetTime(), histogram.Get());
- } else if (!SummaryBuilder.Empty()) {
- auto summary = SummaryBuilder.Build();
- TimeSeries.emplace_back(LastPoint.GetTime(), summary.Get());
- } else if (!LogHistBuilder.Empty()) {
- auto logHist = LogHistBuilder.Build();
- TimeSeries.emplace_back(LastPoint.GetTime(), logHist.Get());
- } else {
- TimeSeries.push_back(std::move(LastPoint));
- }
- }
-
- template <typename TConsumer>
- void Consume(TConsumer&& consumer) {
- if (TimeSeries.empty()) {
- const auto& p = LastPoint;
- consumer(p.GetTime(), p.GetValueType(), p.GetValue());
- } else {
- for (const auto& p: TimeSeries) {
- consumer(p.GetTime(), p.GetValueType(), p.GetValue());
+ return {-std::numeric_limits<double>::infinity(), true};
+ } else {
+ return {0, false};
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+// TMetricCollector
+///////////////////////////////////////////////////////////////////////
+struct TMetricCollector {
+ EMetricType Type = EMetricType::UNKNOWN;
+ TLabels Labels;
+ THistogramBuilder HistogramBuilder;
+ TSummaryDoubleBuilder SummaryBuilder;
+ TLogHistogramBuilder LogHistBuilder;
+ TTypedPoint LastPoint;
+ TVector<TTypedPoint> TimeSeries;
+
+ bool SeenTsOrValue = false;
+ bool SeenTimeseries = false;
+
+ void Clear() {
+ Type = EMetricType::UNKNOWN;
+ Labels.Clear();
+ SeenTsOrValue = false;
+ SeenTimeseries = false;
+ TimeSeries.clear();
+ LastPoint = {};
+ HistogramBuilder.Clear();
+ SummaryBuilder.Clear();
+ LogHistBuilder.Clear();
+ }
+
+ void AddLabel(const TLabel& label) {
+ Labels.Add(label.Name(), label.Value());
+ }
+
+ void SetLastTime(TInstant time) {
+ LastPoint.SetTime(time);
+ }
+
+ template <typename T>
+ void SetLastValue(T value) {
+ LastPoint.SetValue(value);
+ }
+
+ void SaveLastPoint() {
+ DECODE_ENSURE(LastPoint.GetTime() != TInstant::Zero(),
+ "cannot add point without or zero timestamp");
+ if (!HistogramBuilder.Empty()) {
+ auto histogram = HistogramBuilder.Build();
+ TimeSeries.emplace_back(LastPoint.GetTime(), histogram.Get());
+ } else if (!SummaryBuilder.Empty()) {
+ auto summary = SummaryBuilder.Build();
+ TimeSeries.emplace_back(LastPoint.GetTime(), summary.Get());
+ } else if (!LogHistBuilder.Empty()) {
+ auto logHist = LogHistBuilder.Build();
+ TimeSeries.emplace_back(LastPoint.GetTime(), logHist.Get());
+ } else {
+ TimeSeries.push_back(std::move(LastPoint));
+ }
+ }
+
+ template <typename TConsumer>
+ void Consume(TConsumer&& consumer) {
+ if (TimeSeries.empty()) {
+ const auto& p = LastPoint;
+ consumer(p.GetTime(), p.GetValueType(), p.GetValue());
+ } else {
+ for (const auto& p: TimeSeries) {
+ consumer(p.GetTime(), p.GetValueType(), p.GetValue());
}
- }
- }
-};
-
-struct TCommonParts {
- TInstant CommonTime;
- TLabels CommonLabels;
-};
-
-class IHaltableMetricConsumer: public IMetricConsumer {
-public:
- virtual bool NeedToStop() const = 0;
-};
-
-// TODO(ivanzhukov@): check all states for cases when a json document is invalid
-// e.g. "metrics" or "commonLabels" keys are specified multiple times
-class TCommonPartsCollector: public IHaltableMetricConsumer {
-public:
- TCommonParts&& CommonParts() {
- return std::move(CommonParts_);
- }
-
-private:
- bool NeedToStop() const override {
- return TInstant::Zero() != CommonParts_.CommonTime && !CommonParts_.CommonLabels.Empty();
- }
-
- void OnStreamBegin() override {
- }
-
- void OnStreamEnd() override {
- }
-
- void OnCommonTime(TInstant time) override {
- CommonParts_.CommonTime = time;
- }
-
- void OnMetricBegin(EMetricType) override {
- IsMetric_ = true;
- }
-
- void OnMetricEnd() override {
- IsMetric_ = false;
- }
-
- void OnLabelsBegin() override {
- }
-
- void OnLabelsEnd() override {
- }
-
- void OnLabel(TStringBuf name, TStringBuf value) override {
- if (!IsMetric_) {
- CommonParts_.CommonLabels.Add(std::move(name), std::move(value));
- }
- }
-
- void OnDouble(TInstant, double) override {
- }
-
- void OnInt64(TInstant, i64) override {
- }
-
- void OnUint64(TInstant, ui64) override {
- }
-
- void OnHistogram(TInstant, IHistogramSnapshotPtr) override {
- }
-
- void OnLogHistogram(TInstant, TLogHistogramSnapshotPtr) override {
- }
-
- void OnSummaryDouble(TInstant, ISummaryDoubleSnapshotPtr) override {
- }
-
-private:
- TCommonParts CommonParts_;
- bool IsMetric_{false};
-};
-
-class TCommonPartsProxy: public IHaltableMetricConsumer {
-public:
- TCommonPartsProxy(TCommonParts&& commonParts, IMetricConsumer* c)
- : CommonParts_{std::move(commonParts)}
- , Consumer_{c}
- {}
-
-private:
- bool NeedToStop() const override {
- return false;
- }
-
- void OnStreamBegin() override {
- Consumer_->OnStreamBegin();
-
- if (!CommonParts_.CommonLabels.Empty()) {
- Consumer_->OnLabelsBegin();
-
- for (auto&& label : CommonParts_.CommonLabels) {
- Consumer_->OnLabel(label.Name(), label.Value());
- }
-
- Consumer_->OnLabelsEnd();
- }
-
- if (TInstant::Zero() != CommonParts_.CommonTime) {
- Consumer_->OnCommonTime(CommonParts_.CommonTime);
- }
- }
-
- void OnStreamEnd() override {
- Consumer_->OnStreamEnd();
- }
-
- void OnCommonTime(TInstant) override {
- }
-
- void OnMetricBegin(EMetricType type) override {
- IsMetric_ = true;
-
- Consumer_->OnMetricBegin(type);
- }
-
- void OnMetricEnd() override {
- IsMetric_ = false;
-
- Consumer_->OnMetricEnd();
- }
-
- void OnLabelsBegin() override {
- if (IsMetric_) {
- Consumer_->OnLabelsBegin();
- }
- }
-
- void OnLabelsEnd() override {
- if (IsMetric_) {
- Consumer_->OnLabelsEnd();
- }
- }
-
- void OnLabel(TStringBuf name, TStringBuf value) override {
- if (IsMetric_) {
- Consumer_->OnLabel(std::move(name), std::move(value));
- }
- }
-
- void OnDouble(TInstant time, double value) override {
- Consumer_->OnDouble(time, value);
- }
-
- void OnInt64(TInstant time, i64 value) override {
- Consumer_->OnInt64(time, value);
- }
-
- void OnUint64(TInstant time, ui64 value) override {
- Consumer_->OnUint64(time, value);
- }
-
- void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override {
- Consumer_->OnHistogram(time, std::move(snapshot));
- }
-
- void OnLogHistogram(TInstant time, TLogHistogramSnapshotPtr snapshot) override {
- Consumer_->OnLogHistogram(time, std::move(snapshot));
- }
-
- void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) override {
- Consumer_->OnSummaryDouble(time, std::move(snapshot));
- }
-
-private:
- const TCommonParts CommonParts_;
- IMetricConsumer* Consumer_;
- bool IsMetric_{false};
-};
-
-///////////////////////////////////////////////////////////////////////
-// TDecoderJson
-///////////////////////////////////////////////////////////////////////
-class TDecoderJson final: public NJson::TJsonCallbacks {
- struct TState {
- enum EState {
- ROOT_OBJECT = 0x01,
-
- COMMON_LABELS,
- COMMON_TS,
- METRICS_ARRAY,
-
- METRIC_OBJECT,
+ }
+ }
+};
+
+struct TCommonParts {
+ TInstant CommonTime;
+ TLabels CommonLabels;
+};
+
+class IHaltableMetricConsumer: public IMetricConsumer {
+public:
+ virtual bool NeedToStop() const = 0;
+};
+
+// TODO(ivanzhukov@): check all states for cases when a json document is invalid
+// e.g. "metrics" or "commonLabels" keys are specified multiple times
+class TCommonPartsCollector: public IHaltableMetricConsumer {
+public:
+ TCommonParts&& CommonParts() {
+ return std::move(CommonParts_);
+ }
+
+private:
+ bool NeedToStop() const override {
+ return TInstant::Zero() != CommonParts_.CommonTime && !CommonParts_.CommonLabels.Empty();
+ }
+
+ void OnStreamBegin() override {
+ }
+
+ void OnStreamEnd() override {
+ }
+
+ void OnCommonTime(TInstant time) override {
+ CommonParts_.CommonTime = time;
+ }
+
+ void OnMetricBegin(EMetricType) override {
+ IsMetric_ = true;
+ }
+
+ void OnMetricEnd() override {
+ IsMetric_ = false;
+ }
+
+ void OnLabelsBegin() override {
+ }
+
+ void OnLabelsEnd() override {
+ }
+
+ void OnLabel(TStringBuf name, TStringBuf value) override {
+ if (!IsMetric_) {
+ CommonParts_.CommonLabels.Add(std::move(name), std::move(value));
+ }
+ }
+
+ void OnDouble(TInstant, double) override {
+ }
+
+ void OnInt64(TInstant, i64) override {
+ }
+
+ void OnUint64(TInstant, ui64) override {
+ }
+
+ void OnHistogram(TInstant, IHistogramSnapshotPtr) override {
+ }
+
+ void OnLogHistogram(TInstant, TLogHistogramSnapshotPtr) override {
+ }
+
+ void OnSummaryDouble(TInstant, ISummaryDoubleSnapshotPtr) override {
+ }
+
+private:
+ TCommonParts CommonParts_;
+ bool IsMetric_{false};
+};
+
+class TCommonPartsProxy: public IHaltableMetricConsumer {
+public:
+ TCommonPartsProxy(TCommonParts&& commonParts, IMetricConsumer* c)
+ : CommonParts_{std::move(commonParts)}
+ , Consumer_{c}
+ {}
+
+private:
+ bool NeedToStop() const override {
+ return false;
+ }
+
+ void OnStreamBegin() override {
+ Consumer_->OnStreamBegin();
+
+ if (!CommonParts_.CommonLabels.Empty()) {
+ Consumer_->OnLabelsBegin();
+
+ for (auto&& label : CommonParts_.CommonLabels) {
+ Consumer_->OnLabel(label.Name(), label.Value());
+ }
+
+ Consumer_->OnLabelsEnd();
+ }
+
+ if (TInstant::Zero() != CommonParts_.CommonTime) {
+ Consumer_->OnCommonTime(CommonParts_.CommonTime);
+ }
+ }
+
+ void OnStreamEnd() override {
+ Consumer_->OnStreamEnd();
+ }
+
+ void OnCommonTime(TInstant) override {
+ }
+
+ void OnMetricBegin(EMetricType type) override {
+ IsMetric_ = true;
+
+ Consumer_->OnMetricBegin(type);
+ }
+
+ void OnMetricEnd() override {
+ IsMetric_ = false;
+
+ Consumer_->OnMetricEnd();
+ }
+
+ void OnLabelsBegin() override {
+ if (IsMetric_) {
+ Consumer_->OnLabelsBegin();
+ }
+ }
+
+ void OnLabelsEnd() override {
+ if (IsMetric_) {
+ Consumer_->OnLabelsEnd();
+ }
+ }
+
+ void OnLabel(TStringBuf name, TStringBuf value) override {
+ if (IsMetric_) {
+ Consumer_->OnLabel(std::move(name), std::move(value));
+ }
+ }
+
+ void OnDouble(TInstant time, double value) override {
+ Consumer_->OnDouble(time, value);
+ }
+
+ void OnInt64(TInstant time, i64 value) override {
+ Consumer_->OnInt64(time, value);
+ }
+
+ void OnUint64(TInstant time, ui64 value) override {
+ Consumer_->OnUint64(time, value);
+ }
+
+ void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override {
+ Consumer_->OnHistogram(time, std::move(snapshot));
+ }
+
+ void OnLogHistogram(TInstant time, TLogHistogramSnapshotPtr snapshot) override {
+ Consumer_->OnLogHistogram(time, std::move(snapshot));
+ }
+
+ void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) override {
+ Consumer_->OnSummaryDouble(time, std::move(snapshot));
+ }
+
+private:
+ const TCommonParts CommonParts_;
+ IMetricConsumer* Consumer_;
+ bool IsMetric_{false};
+};
+
+///////////////////////////////////////////////////////////////////////
+// TDecoderJson
+///////////////////////////////////////////////////////////////////////
+class TDecoderJson final: public NJson::TJsonCallbacks {
+ struct TState {
+ enum EState {
+ ROOT_OBJECT = 0x01,
+
+ COMMON_LABELS,
+ COMMON_TS,
+ METRICS_ARRAY,
+
+ METRIC_OBJECT,
METRIC_NAME,
- METRIC_LABELS,
- METRIC_TYPE,
- METRIC_MODE, // TODO: must be deleted
- METRIC_TIMESERIES,
- METRIC_TS,
- METRIC_VALUE,
- METRIC_HIST,
- METRIC_HIST_BOUNDS,
- METRIC_HIST_BUCKETS,
- METRIC_HIST_INF,
- METRIC_DSUMMARY,
- METRIC_DSUMMARY_SUM,
- METRIC_DSUMMARY_MIN,
- METRIC_DSUMMARY_MAX,
- METRIC_DSUMMARY_LAST,
- METRIC_DSUMMARY_COUNT,
- METRIC_LOG_HIST,
- METRIC_LOG_HIST_BASE,
- METRIC_LOG_HIST_ZEROS,
- METRIC_LOG_HIST_START_POWER,
- METRIC_LOG_HIST_BUCKETS,
- };
-
- constexpr EState Current() const noexcept {
- return static_cast<EState>(State_ & 0xFF);
- }
-
- void ToNext(EState state) noexcept {
- constexpr auto bitSize = 8 * sizeof(ui8);
- State_ = (State_ << bitSize) | static_cast<ui8>(state);
- }
-
- void ToPrev() noexcept {
- constexpr auto bitSize = 8 * sizeof(ui8);
- State_ = State_ >> bitSize;
- }
-
- private:
- ui64 State_ = static_cast<ui64>(ROOT_OBJECT);
- };
-
-public:
+ METRIC_LABELS,
+ METRIC_TYPE,
+ METRIC_MODE, // TODO: must be deleted
+ METRIC_TIMESERIES,
+ METRIC_TS,
+ METRIC_VALUE,
+ METRIC_HIST,
+ METRIC_HIST_BOUNDS,
+ METRIC_HIST_BUCKETS,
+ METRIC_HIST_INF,
+ METRIC_DSUMMARY,
+ METRIC_DSUMMARY_SUM,
+ METRIC_DSUMMARY_MIN,
+ METRIC_DSUMMARY_MAX,
+ METRIC_DSUMMARY_LAST,
+ METRIC_DSUMMARY_COUNT,
+ METRIC_LOG_HIST,
+ METRIC_LOG_HIST_BASE,
+ METRIC_LOG_HIST_ZEROS,
+ METRIC_LOG_HIST_START_POWER,
+ METRIC_LOG_HIST_BUCKETS,
+ };
+
+ constexpr EState Current() const noexcept {
+ return static_cast<EState>(State_ & 0xFF);
+ }
+
+ void ToNext(EState state) noexcept {
+ constexpr auto bitSize = 8 * sizeof(ui8);
+ State_ = (State_ << bitSize) | static_cast<ui8>(state);
+ }
+
+ void ToPrev() noexcept {
+ constexpr auto bitSize = 8 * sizeof(ui8);
+ State_ = State_ >> bitSize;
+ }
+
+ private:
+ ui64 State_ = static_cast<ui64>(ROOT_OBJECT);
+ };
+
+public:
TDecoderJson(TStringBuf data, IHaltableMetricConsumer* metricConsumer, TStringBuf metricNameLabel)
- : Data_(data)
- , MetricConsumer_(metricConsumer)
+ : Data_(data)
+ , MetricConsumer_(metricConsumer)
, MetricNameLabel_(metricNameLabel)
- {
- }
-
-private:
-#define PARSE_ENSURE(CONDITION, ...) \
-do { \
-if (Y_UNLIKELY(!(CONDITION))) { \
- ErrorMsg_ = TStringBuilder() << __VA_ARGS__; \
- return false; \
-} \
-} while (false)
-
- bool OnInteger(long long value) override {
- switch (State_.Current()) {
- case TState::COMMON_TS:
- PARSE_ENSURE(value >= 0, "unexpected negative number in a common timestamp: " << value);
- MetricConsumer_->OnCommonTime(TInstant::Seconds(value));
- State_.ToPrev();
-
- if (MetricConsumer_->NeedToStop()) {
- IsIntentionallyHalted_ = true;
- return false;
- }
-
- break;
-
- case TState::METRIC_TS:
- PARSE_ENSURE(value >= 0, "unexpected negative number in a metric timestamp: " << value);
- LastMetric_.SetLastTime(TInstant::Seconds(value));
- State_.ToPrev();
- break;
-
- case TState::METRIC_VALUE:
- LastMetric_.SetLastValue(static_cast<i64>(value));
- State_.ToPrev();
- break;
-
- case TState::METRIC_HIST_BOUNDS:
- LastMetric_.HistogramBuilder.AddBound(static_cast<double>(value));
- break;
-
- case TState::METRIC_HIST_BUCKETS:
- PARSE_ENSURE(value >= 0 && static_cast<ui64>(value) <= Max<TBucketValues::value_type>(), "value is out of bounds " << value);
- LastMetric_.HistogramBuilder.AddValue(value);
- break;
-
- case TState::METRIC_HIST_INF:
- PARSE_ENSURE(value >= 0, "unexpected negative number in histogram inf: " << value);
- LastMetric_.HistogramBuilder.AddInf(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_DSUMMARY_COUNT:
- LastMetric_.SummaryBuilder.SetCount(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_DSUMMARY_SUM:
- LastMetric_.SummaryBuilder.SetSum(value);
- State_.ToPrev();
- break;
- case TState::METRIC_DSUMMARY_MIN:
- LastMetric_.SummaryBuilder.SetMin(value);
- State_.ToPrev();
- break;
- case TState::METRIC_DSUMMARY_MAX:
- LastMetric_.SummaryBuilder.SetMax(value);
- State_.ToPrev();
- break;
- case TState::METRIC_DSUMMARY_LAST:
- LastMetric_.SummaryBuilder.SetLast(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_LOG_HIST_BASE:
- LastMetric_.LogHistBuilder.SetBase(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_LOG_HIST_ZEROS:
- LastMetric_.LogHistBuilder.SetZerosCount(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_LOG_HIST_START_POWER:
- LastMetric_.LogHistBuilder.SetStartPower(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_LOG_HIST_BUCKETS:
- LastMetric_.LogHistBuilder.AddBucketValue(value);
- break;
-
- default:
- return false;
- }
- return true;
- }
-
- bool OnUInteger(unsigned long long value) override {
- switch (State_.Current()) {
- case TState::COMMON_TS:
- MetricConsumer_->OnCommonTime(TInstant::Seconds(value));
- State_.ToPrev();
-
- if (MetricConsumer_->NeedToStop()) {
- IsIntentionallyHalted_ = true;
- return false;
- }
-
- break;
-
- case TState::METRIC_TS:
- LastMetric_.SetLastTime(TInstant::Seconds(value));
- State_.ToPrev();
- break;
-
- case TState::METRIC_VALUE:
- PARSE_ENSURE(value <= Max<ui64>(), "Metric value is out of bounds: " << value);
- LastMetric_.SetLastValue(static_cast<ui64>(value));
- State_.ToPrev();
- break;
-
- case TState::METRIC_HIST_BOUNDS:
- LastMetric_.HistogramBuilder.AddBound(static_cast<double>(value));
- break;
-
- case TState::METRIC_HIST_BUCKETS:
- PARSE_ENSURE(value <= Max<TBucketValues::value_type>(), "Histogram bucket value is out of bounds: " << value);
- LastMetric_.HistogramBuilder.AddValue(value);
- break;
-
- case TState::METRIC_HIST_INF:
- LastMetric_.HistogramBuilder.AddInf(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_DSUMMARY_COUNT:
- LastMetric_.SummaryBuilder.SetCount(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_DSUMMARY_SUM:
- LastMetric_.SummaryBuilder.SetSum(value);
- State_.ToPrev();
- break;
- case TState::METRIC_DSUMMARY_MIN:
- LastMetric_.SummaryBuilder.SetMin(value);
- State_.ToPrev();
- break;
- case TState::METRIC_DSUMMARY_MAX:
- LastMetric_.SummaryBuilder.SetMax(value);
- State_.ToPrev();
- break;
- case TState::METRIC_DSUMMARY_LAST:
- LastMetric_.SummaryBuilder.SetLast(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_LOG_HIST_BASE:
- LastMetric_.LogHistBuilder.SetBase(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_LOG_HIST_ZEROS:
- LastMetric_.LogHistBuilder.SetZerosCount(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_LOG_HIST_START_POWER:
- LastMetric_.LogHistBuilder.SetStartPower(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_LOG_HIST_BUCKETS:
- LastMetric_.LogHistBuilder.AddBucketValue(value);
- break;
-
- default:
- return false;
- }
- return true;
- }
-
- bool OnDouble(double value) override {
- switch (State_.Current()) {
- case TState::METRIC_VALUE:
- LastMetric_.SetLastValue(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_HIST_BOUNDS:
- LastMetric_.HistogramBuilder.AddBound(value);
- break;
-
- case TState::METRIC_DSUMMARY_SUM:
- LastMetric_.SummaryBuilder.SetSum(value);
- State_.ToPrev();
- break;
- case TState::METRIC_DSUMMARY_MIN:
- LastMetric_.SummaryBuilder.SetMin(value);
- State_.ToPrev();
- break;
- case TState::METRIC_DSUMMARY_MAX:
- LastMetric_.SummaryBuilder.SetMax(value);
- State_.ToPrev();
- break;
- case TState::METRIC_DSUMMARY_LAST:
- LastMetric_.SummaryBuilder.SetLast(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_LOG_HIST_BASE:
- LastMetric_.LogHistBuilder.SetBase(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_LOG_HIST_BUCKETS:
- LastMetric_.LogHistBuilder.AddBucketValue(value);
- break;
-
- default:
- return false;
- }
- return true;
- }
-
- bool OnString(const TStringBuf& value) override {
- switch (State_.Current()) {
- case TState::COMMON_LABELS:
- PARSE_ENSURE(!LastLabelName_.empty(), "empty label name in common labels");
- MetricConsumer_->OnLabel(LastLabelName_, TString{value});
- break;
-
- case TState::METRIC_LABELS:
- PARSE_ENSURE(!LastLabelName_.empty(), "empty label name in metric labels");
- LastMetric_.Labels.Add(LastLabelName_, TString{value});
- break;
-
+ {
+ }
+
+private:
+#define PARSE_ENSURE(CONDITION, ...) \
+do { \
+if (Y_UNLIKELY(!(CONDITION))) { \
+ ErrorMsg_ = TStringBuilder() << __VA_ARGS__; \
+ return false; \
+} \
+} while (false)
+
+ bool OnInteger(long long value) override {
+ switch (State_.Current()) {
+ case TState::COMMON_TS:
+ PARSE_ENSURE(value >= 0, "unexpected negative number in a common timestamp: " << value);
+ MetricConsumer_->OnCommonTime(TInstant::Seconds(value));
+ State_.ToPrev();
+
+ if (MetricConsumer_->NeedToStop()) {
+ IsIntentionallyHalted_ = true;
+ return false;
+ }
+
+ break;
+
+ case TState::METRIC_TS:
+ PARSE_ENSURE(value >= 0, "unexpected negative number in a metric timestamp: " << value);
+ LastMetric_.SetLastTime(TInstant::Seconds(value));
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_VALUE:
+ LastMetric_.SetLastValue(static_cast<i64>(value));
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_HIST_BOUNDS:
+ LastMetric_.HistogramBuilder.AddBound(static_cast<double>(value));
+ break;
+
+ case TState::METRIC_HIST_BUCKETS:
+ PARSE_ENSURE(value >= 0 && static_cast<ui64>(value) <= Max<TBucketValues::value_type>(), "value is out of bounds " << value);
+ LastMetric_.HistogramBuilder.AddValue(value);
+ break;
+
+ case TState::METRIC_HIST_INF:
+ PARSE_ENSURE(value >= 0, "unexpected negative number in histogram inf: " << value);
+ LastMetric_.HistogramBuilder.AddInf(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_DSUMMARY_COUNT:
+ LastMetric_.SummaryBuilder.SetCount(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_DSUMMARY_SUM:
+ LastMetric_.SummaryBuilder.SetSum(value);
+ State_.ToPrev();
+ break;
+ case TState::METRIC_DSUMMARY_MIN:
+ LastMetric_.SummaryBuilder.SetMin(value);
+ State_.ToPrev();
+ break;
+ case TState::METRIC_DSUMMARY_MAX:
+ LastMetric_.SummaryBuilder.SetMax(value);
+ State_.ToPrev();
+ break;
+ case TState::METRIC_DSUMMARY_LAST:
+ LastMetric_.SummaryBuilder.SetLast(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_LOG_HIST_BASE:
+ LastMetric_.LogHistBuilder.SetBase(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_LOG_HIST_ZEROS:
+ LastMetric_.LogHistBuilder.SetZerosCount(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_LOG_HIST_START_POWER:
+ LastMetric_.LogHistBuilder.SetStartPower(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_LOG_HIST_BUCKETS:
+ LastMetric_.LogHistBuilder.AddBucketValue(value);
+ break;
+
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ bool OnUInteger(unsigned long long value) override {
+ switch (State_.Current()) {
+ case TState::COMMON_TS:
+ MetricConsumer_->OnCommonTime(TInstant::Seconds(value));
+ State_.ToPrev();
+
+ if (MetricConsumer_->NeedToStop()) {
+ IsIntentionallyHalted_ = true;
+ return false;
+ }
+
+ break;
+
+ case TState::METRIC_TS:
+ LastMetric_.SetLastTime(TInstant::Seconds(value));
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_VALUE:
+ PARSE_ENSURE(value <= Max<ui64>(), "Metric value is out of bounds: " << value);
+ LastMetric_.SetLastValue(static_cast<ui64>(value));
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_HIST_BOUNDS:
+ LastMetric_.HistogramBuilder.AddBound(static_cast<double>(value));
+ break;
+
+ case TState::METRIC_HIST_BUCKETS:
+ PARSE_ENSURE(value <= Max<TBucketValues::value_type>(), "Histogram bucket value is out of bounds: " << value);
+ LastMetric_.HistogramBuilder.AddValue(value);
+ break;
+
+ case TState::METRIC_HIST_INF:
+ LastMetric_.HistogramBuilder.AddInf(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_DSUMMARY_COUNT:
+ LastMetric_.SummaryBuilder.SetCount(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_DSUMMARY_SUM:
+ LastMetric_.SummaryBuilder.SetSum(value);
+ State_.ToPrev();
+ break;
+ case TState::METRIC_DSUMMARY_MIN:
+ LastMetric_.SummaryBuilder.SetMin(value);
+ State_.ToPrev();
+ break;
+ case TState::METRIC_DSUMMARY_MAX:
+ LastMetric_.SummaryBuilder.SetMax(value);
+ State_.ToPrev();
+ break;
+ case TState::METRIC_DSUMMARY_LAST:
+ LastMetric_.SummaryBuilder.SetLast(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_LOG_HIST_BASE:
+ LastMetric_.LogHistBuilder.SetBase(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_LOG_HIST_ZEROS:
+ LastMetric_.LogHistBuilder.SetZerosCount(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_LOG_HIST_START_POWER:
+ LastMetric_.LogHistBuilder.SetStartPower(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_LOG_HIST_BUCKETS:
+ LastMetric_.LogHistBuilder.AddBucketValue(value);
+ break;
+
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ bool OnDouble(double value) override {
+ switch (State_.Current()) {
+ case TState::METRIC_VALUE:
+ LastMetric_.SetLastValue(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_HIST_BOUNDS:
+ LastMetric_.HistogramBuilder.AddBound(value);
+ break;
+
+ case TState::METRIC_DSUMMARY_SUM:
+ LastMetric_.SummaryBuilder.SetSum(value);
+ State_.ToPrev();
+ break;
+ case TState::METRIC_DSUMMARY_MIN:
+ LastMetric_.SummaryBuilder.SetMin(value);
+ State_.ToPrev();
+ break;
+ case TState::METRIC_DSUMMARY_MAX:
+ LastMetric_.SummaryBuilder.SetMax(value);
+ State_.ToPrev();
+ break;
+ case TState::METRIC_DSUMMARY_LAST:
+ LastMetric_.SummaryBuilder.SetLast(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_LOG_HIST_BASE:
+ LastMetric_.LogHistBuilder.SetBase(value);
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_LOG_HIST_BUCKETS:
+ LastMetric_.LogHistBuilder.AddBucketValue(value);
+ break;
+
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ bool OnString(const TStringBuf& value) override {
+ switch (State_.Current()) {
+ case TState::COMMON_LABELS:
+ PARSE_ENSURE(!LastLabelName_.empty(), "empty label name in common labels");
+ MetricConsumer_->OnLabel(LastLabelName_, TString{value});
+ break;
+
+ case TState::METRIC_LABELS:
+ PARSE_ENSURE(!LastLabelName_.empty(), "empty label name in metric labels");
+ LastMetric_.Labels.Add(LastLabelName_, TString{value});
+ break;
+
case TState::METRIC_NAME:
PARSE_ENSURE(!value.empty(), "empty metric name");
LastMetric_.Labels.Add(MetricNameLabel_, TString{value});
State_.ToPrev();
break;
- case TState::COMMON_TS:
- MetricConsumer_->OnCommonTime(TInstant::ParseIso8601(value));
- State_.ToPrev();
-
- if (MetricConsumer_->NeedToStop()) {
- IsIntentionallyHalted_ = true;
- return false;
+ case TState::COMMON_TS:
+ MetricConsumer_->OnCommonTime(TInstant::ParseIso8601(value));
+ State_.ToPrev();
+
+ if (MetricConsumer_->NeedToStop()) {
+ IsIntentionallyHalted_ = true;
+ return false;
+ }
+
+ break;
+
+ case TState::METRIC_TS:
+ LastMetric_.SetLastTime(TInstant::ParseIso8601(value));
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_VALUE:
+ if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) {
+ LastMetric_.SetLastValue(doubleValue);
+ } else {
+ return false;
}
+ State_.ToPrev();
+ break;
- break;
-
- case TState::METRIC_TS:
- LastMetric_.SetLastTime(TInstant::ParseIso8601(value));
- State_.ToPrev();
- break;
+ case TState::METRIC_TYPE:
+ LastMetric_.Type = MetricTypeFromStr(value);
+ State_.ToPrev();
+ break;
- case TState::METRIC_VALUE:
- if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) {
- LastMetric_.SetLastValue(doubleValue);
- } else {
- return false;
- }
- State_.ToPrev();
- break;
-
- case TState::METRIC_TYPE:
- LastMetric_.Type = MetricTypeFromStr(value);
- State_.ToPrev();
- break;
-
- case TState::METRIC_MODE:
+ case TState::METRIC_MODE:
if (value == TStringBuf("deriv")) {
- LastMetric_.Type = EMetricType::RATE;
- }
- State_.ToPrev();
- break;
-
- case TState::METRIC_DSUMMARY_SUM:
- if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) {
- LastMetric_.SummaryBuilder.SetSum(doubleValue);
- } else {
- return false;
- }
- State_.ToPrev();
- break;
-
- case TState::METRIC_DSUMMARY_MIN:
- if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) {
- LastMetric_.SummaryBuilder.SetMin(doubleValue);
- } else {
- return false;
- }
- State_.ToPrev();
- break;
-
- case TState::METRIC_DSUMMARY_MAX:
- if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) {
- LastMetric_.SummaryBuilder.SetMax(doubleValue);
- } else {
- return false;
- }
- State_.ToPrev();
- break;
-
- case TState::METRIC_DSUMMARY_LAST:
- if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) {
- LastMetric_.SummaryBuilder.SetLast(doubleValue);
- } else {
- return false;
- }
- State_.ToPrev();
- break;
-
- default:
- return false;
- }
-
- return true;
- }
-
- bool OnMapKey(const TStringBuf& key) override {
- switch (State_.Current()) {
- case TState::ROOT_OBJECT:
+ LastMetric_.Type = EMetricType::RATE;
+ }
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_DSUMMARY_SUM:
+ if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) {
+ LastMetric_.SummaryBuilder.SetSum(doubleValue);
+ } else {
+ return false;
+ }
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_DSUMMARY_MIN:
+ if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) {
+ LastMetric_.SummaryBuilder.SetMin(doubleValue);
+ } else {
+ return false;
+ }
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_DSUMMARY_MAX:
+ if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) {
+ LastMetric_.SummaryBuilder.SetMax(doubleValue);
+ } else {
+ return false;
+ }
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_DSUMMARY_LAST:
+ if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) {
+ LastMetric_.SummaryBuilder.SetLast(doubleValue);
+ } else {
+ return false;
+ }
+ State_.ToPrev();
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+ }
+
+ bool OnMapKey(const TStringBuf& key) override {
+ switch (State_.Current()) {
+ case TState::ROOT_OBJECT:
if (key == TStringBuf("commonLabels") || key == TStringBuf("labels")) {
- State_.ToNext(TState::COMMON_LABELS);
+ State_.ToNext(TState::COMMON_LABELS);
} else if (key == TStringBuf("ts")) {
- State_.ToNext(TState::COMMON_TS);
+ State_.ToNext(TState::COMMON_TS);
} else if (key == TStringBuf("sensors") || key == TStringBuf("metrics")) {
- State_.ToNext(TState::METRICS_ARRAY);
- }
- break;
+ State_.ToNext(TState::METRICS_ARRAY);
+ }
+ break;
- case TState::COMMON_LABELS:
- case TState::METRIC_LABELS:
- LastLabelName_ = key;
- break;
+ case TState::COMMON_LABELS:
+ case TState::METRIC_LABELS:
+ LastLabelName_ = key;
+ break;
- case TState::METRIC_OBJECT:
+ case TState::METRIC_OBJECT:
if (key == TStringBuf("labels")) {
- State_.ToNext(TState::METRIC_LABELS);
+ State_.ToNext(TState::METRIC_LABELS);
} else if (key == TStringBuf("name")) {
State_.ToNext(TState::METRIC_NAME);
} else if (key == TStringBuf("ts")) {
- PARSE_ENSURE(!LastMetric_.SeenTimeseries,
- "mixed timeseries and ts attributes");
- LastMetric_.SeenTsOrValue = true;
- State_.ToNext(TState::METRIC_TS);
+ PARSE_ENSURE(!LastMetric_.SeenTimeseries,
+ "mixed timeseries and ts attributes");
+ LastMetric_.SeenTsOrValue = true;
+ State_.ToNext(TState::METRIC_TS);
} else if (key == TStringBuf("value")) {
- PARSE_ENSURE(!LastMetric_.SeenTimeseries,
- "mixed timeseries and value attributes");
- LastMetric_.SeenTsOrValue = true;
- State_.ToNext(TState::METRIC_VALUE);
+ PARSE_ENSURE(!LastMetric_.SeenTimeseries,
+ "mixed timeseries and value attributes");
+ LastMetric_.SeenTsOrValue = true;
+ State_.ToNext(TState::METRIC_VALUE);
} else if (key == TStringBuf("timeseries")) {
- PARSE_ENSURE(!LastMetric_.SeenTsOrValue,
- "mixed timeseries and ts/value attributes");
- LastMetric_.SeenTimeseries = true;
- State_.ToNext(TState::METRIC_TIMESERIES);
+ PARSE_ENSURE(!LastMetric_.SeenTsOrValue,
+ "mixed timeseries and ts/value attributes");
+ LastMetric_.SeenTimeseries = true;
+ State_.ToNext(TState::METRIC_TIMESERIES);
} else if (key == TStringBuf("mode")) {
- State_.ToNext(TState::METRIC_MODE);
+ State_.ToNext(TState::METRIC_MODE);
} else if (key == TStringBuf("kind") || key == TStringBuf("type")) {
- State_.ToNext(TState::METRIC_TYPE);
+ State_.ToNext(TState::METRIC_TYPE);
} else if (key == TStringBuf("hist")) {
- State_.ToNext(TState::METRIC_HIST);
+ State_.ToNext(TState::METRIC_HIST);
} else if (key == TStringBuf("summary")) {
- State_.ToNext(TState::METRIC_DSUMMARY);
+ State_.ToNext(TState::METRIC_DSUMMARY);
} else if (key == TStringBuf("log_hist")) {
- State_.ToNext(TState::METRIC_LOG_HIST);
+ State_.ToNext(TState::METRIC_LOG_HIST);
} else if (key == TStringBuf("memOnly")) {
- // deprecated. Skip it without errors for backward compatibility
- } else {
- ErrorMsg_ = TStringBuilder() << "unexpected key \"" << key << "\" in a metric schema";
- return false;
- }
- break;
-
- case TState::METRIC_TIMESERIES:
+ // deprecated. Skip it without errors for backward compatibility
+ } else {
+ ErrorMsg_ = TStringBuilder() << "unexpected key \"" << key << "\" in a metric schema";
+ return false;
+ }
+ break;
+
+ case TState::METRIC_TIMESERIES:
if (key == TStringBuf("ts")) {
- State_.ToNext(TState::METRIC_TS);
+ State_.ToNext(TState::METRIC_TS);
} else if (key == TStringBuf("value")) {
- State_.ToNext(TState::METRIC_VALUE);
+ State_.ToNext(TState::METRIC_VALUE);
} else if (key == TStringBuf("hist")) {
- State_.ToNext(TState::METRIC_HIST);
+ State_.ToNext(TState::METRIC_HIST);
} else if (key == TStringBuf("summary")) {
- State_.ToNext(TState::METRIC_DSUMMARY);
+ State_.ToNext(TState::METRIC_DSUMMARY);
} else if (key == TStringBuf("log_hist")) {
- State_.ToNext(TState::METRIC_LOG_HIST);
+ State_.ToNext(TState::METRIC_LOG_HIST);
}
- break;
+ break;
- case TState::METRIC_HIST:
+ case TState::METRIC_HIST:
if (key == TStringBuf("bounds")) {
- State_.ToNext(TState::METRIC_HIST_BOUNDS);
+ State_.ToNext(TState::METRIC_HIST_BOUNDS);
} else if (key == TStringBuf("buckets")) {
- State_.ToNext(TState::METRIC_HIST_BUCKETS);
+ State_.ToNext(TState::METRIC_HIST_BUCKETS);
} else if (key == TStringBuf("inf")) {
- State_.ToNext(TState::METRIC_HIST_INF);
- }
- break;
+ State_.ToNext(TState::METRIC_HIST_INF);
+ }
+ break;
- case TState::METRIC_LOG_HIST:
+ case TState::METRIC_LOG_HIST:
if (key == TStringBuf("base")) {
- State_.ToNext(TState::METRIC_LOG_HIST_BASE);
+ State_.ToNext(TState::METRIC_LOG_HIST_BASE);
} else if (key == TStringBuf("zeros_count")) {
- State_.ToNext(TState::METRIC_LOG_HIST_ZEROS);
+ State_.ToNext(TState::METRIC_LOG_HIST_ZEROS);
} else if (key == TStringBuf("start_power")) {
- State_.ToNext(TState::METRIC_LOG_HIST_START_POWER);
+ State_.ToNext(TState::METRIC_LOG_HIST_START_POWER);
} else if (key == TStringBuf("buckets")) {
- State_.ToNext(TState::METRIC_LOG_HIST_BUCKETS);
- }
- break;
+ State_.ToNext(TState::METRIC_LOG_HIST_BUCKETS);
+ }
+ break;
- case TState::METRIC_DSUMMARY:
+ case TState::METRIC_DSUMMARY:
if (key == TStringBuf("sum")) {
- State_.ToNext(TState::METRIC_DSUMMARY_SUM);
+ State_.ToNext(TState::METRIC_DSUMMARY_SUM);
} else if (key == TStringBuf("min")) {
- State_.ToNext(TState::METRIC_DSUMMARY_MIN);
+ State_.ToNext(TState::METRIC_DSUMMARY_MIN);
} else if (key == TStringBuf("max")) {
- State_.ToNext(TState::METRIC_DSUMMARY_MAX);
+ State_.ToNext(TState::METRIC_DSUMMARY_MAX);
} else if (key == TStringBuf("last")) {
- State_.ToNext(TState::METRIC_DSUMMARY_LAST);
+ State_.ToNext(TState::METRIC_DSUMMARY_LAST);
} else if (key == TStringBuf("count")) {
- State_.ToNext(TState::METRIC_DSUMMARY_COUNT);
- }
-
- break;
-
-
- default:
- return false;
- }
-
- return true;
- }
-
- bool OnOpenMap() override {
- switch (State_.Current()) {
- case TState::ROOT_OBJECT:
- MetricConsumer_->OnStreamBegin();
- break;
-
- case TState::COMMON_LABELS:
- MetricConsumer_->OnLabelsBegin();
- break;
-
- case TState::METRICS_ARRAY:
- State_.ToNext(TState::METRIC_OBJECT);
- LastMetric_.Clear();
- break;
-
- default:
- break;
- }
- return true;
- }
-
- bool OnCloseMap() override {
- switch (State_.Current()) {
- case TState::ROOT_OBJECT:
- MetricConsumer_->OnStreamEnd();
- break;
-
- case TState::METRIC_LABELS:
- State_.ToPrev();
- break;
-
- case TState::COMMON_LABELS:
- MetricConsumer_->OnLabelsEnd();
- State_.ToPrev();
-
- if (MetricConsumer_->NeedToStop()) {
- IsIntentionallyHalted_ = true;
- return false;
- }
-
- break;
-
- case TState::METRIC_OBJECT:
- ConsumeMetric();
- State_.ToPrev();
- break;
-
- case TState::METRIC_TIMESERIES:
- LastMetric_.SaveLastPoint();
- break;
-
- case TState::METRIC_HIST:
- case TState::METRIC_DSUMMARY:
- case TState::METRIC_LOG_HIST:
- State_.ToPrev();
- break;
-
- default:
- break;
- }
- return true;
- }
-
- bool OnOpenArray() override {
- auto currentState = State_.Current();
- PARSE_ENSURE(
- currentState == TState::METRICS_ARRAY ||
- currentState == TState::METRIC_TIMESERIES ||
- currentState == TState::METRIC_HIST_BOUNDS ||
- currentState == TState::METRIC_HIST_BUCKETS ||
- currentState == TState::METRIC_LOG_HIST_BUCKETS,
- "unexpected array begin");
- return true;
- }
-
- bool OnCloseArray() override {
- switch (State_.Current()) {
- case TState::METRICS_ARRAY:
- case TState::METRIC_TIMESERIES:
- case TState::METRIC_HIST_BOUNDS:
- case TState::METRIC_HIST_BUCKETS:
- case TState::METRIC_LOG_HIST_BUCKETS:
- State_.ToPrev();
- break;
-
- default:
- return false;
- }
- return true;
- }
-
- void OnError(size_t off, TStringBuf reason) override {
- if (IsIntentionallyHalted_) {
- return;
- }
-
- size_t snippetBeg = (off < 20) ? 0 : (off - 20);
- TStringBuf snippet = Data_.SubStr(snippetBeg, 40);
-
- throw TJsonDecodeError()
- << "cannot parse JSON, error at: " << off
- << ", reason: " << (ErrorMsg_.empty() ? reason : TStringBuf{ErrorMsg_})
- << "\nsnippet: ..." << snippet << "...";
- }
-
- bool OnEnd() override {
- return true;
- }
-
- void ConsumeMetric() {
- // for backwad compatibility all unknown metrics treated as gauges
- if (LastMetric_.Type == EMetricType::UNKNOWN) {
- if (LastMetric_.HistogramBuilder.Empty()) {
- LastMetric_.Type = EMetricType::GAUGE;
- } else {
- LastMetric_.Type = EMetricType::HIST;
+ State_.ToNext(TState::METRIC_DSUMMARY_COUNT);
+ }
+
+ break;
+
+
+ default:
+ return false;
+ }
+
+ return true;
+ }
+
+ bool OnOpenMap() override {
+ switch (State_.Current()) {
+ case TState::ROOT_OBJECT:
+ MetricConsumer_->OnStreamBegin();
+ break;
+
+ case TState::COMMON_LABELS:
+ MetricConsumer_->OnLabelsBegin();
+ break;
+
+ case TState::METRICS_ARRAY:
+ State_.ToNext(TState::METRIC_OBJECT);
+ LastMetric_.Clear();
+ break;
+
+ default:
+ break;
+ }
+ return true;
+ }
+
+ bool OnCloseMap() override {
+ switch (State_.Current()) {
+ case TState::ROOT_OBJECT:
+ MetricConsumer_->OnStreamEnd();
+ break;
+
+ case TState::METRIC_LABELS:
+ State_.ToPrev();
+ break;
+
+ case TState::COMMON_LABELS:
+ MetricConsumer_->OnLabelsEnd();
+ State_.ToPrev();
+
+ if (MetricConsumer_->NeedToStop()) {
+ IsIntentionallyHalted_ = true;
+ return false;
+ }
+
+ break;
+
+ case TState::METRIC_OBJECT:
+ ConsumeMetric();
+ State_.ToPrev();
+ break;
+
+ case TState::METRIC_TIMESERIES:
+ LastMetric_.SaveLastPoint();
+ break;
+
+ case TState::METRIC_HIST:
+ case TState::METRIC_DSUMMARY:
+ case TState::METRIC_LOG_HIST:
+ State_.ToPrev();
+ break;
+
+ default:
+ break;
+ }
+ return true;
+ }
+
+ bool OnOpenArray() override {
+ auto currentState = State_.Current();
+ PARSE_ENSURE(
+ currentState == TState::METRICS_ARRAY ||
+ currentState == TState::METRIC_TIMESERIES ||
+ currentState == TState::METRIC_HIST_BOUNDS ||
+ currentState == TState::METRIC_HIST_BUCKETS ||
+ currentState == TState::METRIC_LOG_HIST_BUCKETS,
+ "unexpected array begin");
+ return true;
+ }
+
+ bool OnCloseArray() override {
+ switch (State_.Current()) {
+ case TState::METRICS_ARRAY:
+ case TState::METRIC_TIMESERIES:
+ case TState::METRIC_HIST_BOUNDS:
+ case TState::METRIC_HIST_BUCKETS:
+ case TState::METRIC_LOG_HIST_BUCKETS:
+ State_.ToPrev();
+ break;
+
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ void OnError(size_t off, TStringBuf reason) override {
+ if (IsIntentionallyHalted_) {
+ return;
+ }
+
+ size_t snippetBeg = (off < 20) ? 0 : (off - 20);
+ TStringBuf snippet = Data_.SubStr(snippetBeg, 40);
+
+ throw TJsonDecodeError()
+ << "cannot parse JSON, error at: " << off
+ << ", reason: " << (ErrorMsg_.empty() ? reason : TStringBuf{ErrorMsg_})
+ << "\nsnippet: ..." << snippet << "...";
+ }
+
+ bool OnEnd() override {
+ return true;
+ }
+
+ void ConsumeMetric() {
+ // for backwad compatibility all unknown metrics treated as gauges
+ if (LastMetric_.Type == EMetricType::UNKNOWN) {
+ if (LastMetric_.HistogramBuilder.Empty()) {
+ LastMetric_.Type = EMetricType::GAUGE;
+ } else {
+ LastMetric_.Type = EMetricType::HIST;
}
- }
+ }
- // (1) begin metric
- MetricConsumer_->OnMetricBegin(LastMetric_.Type);
+ // (1) begin metric
+ MetricConsumer_->OnMetricBegin(LastMetric_.Type);
- // (2) labels
- if (!LastMetric_.Labels.empty()) {
- MetricConsumer_->OnLabelsBegin();
- for (auto&& label : LastMetric_.Labels) {
- MetricConsumer_->OnLabel(label.Name(), label.Value());
+ // (2) labels
+ if (!LastMetric_.Labels.empty()) {
+ MetricConsumer_->OnLabelsBegin();
+ for (auto&& label : LastMetric_.Labels) {
+ MetricConsumer_->OnLabel(label.Name(), label.Value());
}
- MetricConsumer_->OnLabelsEnd();
- }
-
- // (3) values
- switch (LastMetric_.Type) {
- case EMetricType::GAUGE:
- LastMetric_.Consume([this](TInstant time, EMetricValueType valueType, TMetricValue value) {
- MetricConsumer_->OnDouble(time, value.AsDouble(valueType));
- });
- break;
-
- case EMetricType::IGAUGE:
- LastMetric_.Consume([this](TInstant time, EMetricValueType valueType, TMetricValue value) {
- MetricConsumer_->OnInt64(time, value.AsInt64(valueType));
- });
- break;
-
- case EMetricType::COUNTER:
- case EMetricType::RATE:
- LastMetric_.Consume([this](TInstant time, EMetricValueType valueType, TMetricValue value) {
- MetricConsumer_->OnUint64(time, value.AsUint64(valueType));
- });
- break;
-
- case EMetricType::HIST:
- case EMetricType::HIST_RATE:
- if (LastMetric_.TimeSeries.empty()) {
- auto time = LastMetric_.LastPoint.GetTime();
- auto histogram = LastMetric_.HistogramBuilder.Build();
- MetricConsumer_->OnHistogram(time, histogram);
- } else {
- for (const auto& p : LastMetric_.TimeSeries) {
- DECODE_ENSURE(p.GetValueType() == EMetricValueType::HISTOGRAM, "Value is not a histogram");
- MetricConsumer_->OnHistogram(p.GetTime(), p.GetValue().AsHistogram());
+ MetricConsumer_->OnLabelsEnd();
+ }
+
+ // (3) values
+ switch (LastMetric_.Type) {
+ case EMetricType::GAUGE:
+ LastMetric_.Consume([this](TInstant time, EMetricValueType valueType, TMetricValue value) {
+ MetricConsumer_->OnDouble(time, value.AsDouble(valueType));
+ });
+ break;
+
+ case EMetricType::IGAUGE:
+ LastMetric_.Consume([this](TInstant time, EMetricValueType valueType, TMetricValue value) {
+ MetricConsumer_->OnInt64(time, value.AsInt64(valueType));
+ });
+ break;
+
+ case EMetricType::COUNTER:
+ case EMetricType::RATE:
+ LastMetric_.Consume([this](TInstant time, EMetricValueType valueType, TMetricValue value) {
+ MetricConsumer_->OnUint64(time, value.AsUint64(valueType));
+ });
+ break;
+
+ case EMetricType::HIST:
+ case EMetricType::HIST_RATE:
+ if (LastMetric_.TimeSeries.empty()) {
+ auto time = LastMetric_.LastPoint.GetTime();
+ auto histogram = LastMetric_.HistogramBuilder.Build();
+ MetricConsumer_->OnHistogram(time, histogram);
+ } else {
+ for (const auto& p : LastMetric_.TimeSeries) {
+ DECODE_ENSURE(p.GetValueType() == EMetricValueType::HISTOGRAM, "Value is not a histogram");
+ MetricConsumer_->OnHistogram(p.GetTime(), p.GetValue().AsHistogram());
}
}
- break;
-
- case EMetricType::DSUMMARY:
- if (LastMetric_.TimeSeries.empty()) {
- auto time = LastMetric_.LastPoint.GetTime();
- auto summary = LastMetric_.SummaryBuilder.Build();
- MetricConsumer_->OnSummaryDouble(time, summary);
- } else {
- for (const auto& p : LastMetric_.TimeSeries) {
- DECODE_ENSURE(p.GetValueType() == EMetricValueType::SUMMARY, "Value is not a summary");
- MetricConsumer_->OnSummaryDouble(p.GetTime(), p.GetValue().AsSummaryDouble());
+ break;
+
+ case EMetricType::DSUMMARY:
+ if (LastMetric_.TimeSeries.empty()) {
+ auto time = LastMetric_.LastPoint.GetTime();
+ auto summary = LastMetric_.SummaryBuilder.Build();
+ MetricConsumer_->OnSummaryDouble(time, summary);
+ } else {
+ for (const auto& p : LastMetric_.TimeSeries) {
+ DECODE_ENSURE(p.GetValueType() == EMetricValueType::SUMMARY, "Value is not a summary");
+ MetricConsumer_->OnSummaryDouble(p.GetTime(), p.GetValue().AsSummaryDouble());
+ }
+ }
+ break;
+
+ case EMetricType::LOGHIST:
+ if (LastMetric_.TimeSeries.empty()) {
+ auto time = LastMetric_.LastPoint.GetTime();
+ auto logHist = LastMetric_.LogHistBuilder.Build();
+ MetricConsumer_->OnLogHistogram(time, logHist);
+ } else {
+ for (const auto& p : LastMetric_.TimeSeries) {
+ DECODE_ENSURE(p.GetValueType() == EMetricValueType::LOGHISTOGRAM, "Value is not a log_histogram");
+ MetricConsumer_->OnLogHistogram(p.GetTime(), p.GetValue().AsLogHistogram());
}
}
- break;
+ break;
- case EMetricType::LOGHIST:
- if (LastMetric_.TimeSeries.empty()) {
- auto time = LastMetric_.LastPoint.GetTime();
- auto logHist = LastMetric_.LogHistBuilder.Build();
- MetricConsumer_->OnLogHistogram(time, logHist);
- } else {
- for (const auto& p : LastMetric_.TimeSeries) {
- DECODE_ENSURE(p.GetValueType() == EMetricValueType::LOGHISTOGRAM, "Value is not a log_histogram");
- MetricConsumer_->OnLogHistogram(p.GetTime(), p.GetValue().AsLogHistogram());
- }
- }
- break;
+ case EMetricType::UNKNOWN:
+ // TODO: output metric labels
+ ythrow yexception() << "unknown metric type";
+ }
- case EMetricType::UNKNOWN:
- // TODO: output metric labels
- ythrow yexception() << "unknown metric type";
- }
+ // (4) end metric
+ MetricConsumer_->OnMetricEnd();
+ }
- // (4) end metric
- MetricConsumer_->OnMetricEnd();
- }
-
-private:
- TStringBuf Data_;
- IHaltableMetricConsumer* MetricConsumer_;
+private:
+ TStringBuf Data_;
+ IHaltableMetricConsumer* MetricConsumer_;
TString MetricNameLabel_;
- TState State_;
- TString LastLabelName_;
- TMetricCollector LastMetric_;
- TString ErrorMsg_;
- bool IsIntentionallyHalted_{false};
-};
+ TState State_;
+ TString LastLabelName_;
+ TMetricCollector LastMetric_;
+ TString ErrorMsg_;
+ bool IsIntentionallyHalted_{false};
+};
-} // namespace
+} // namespace
void DecodeJson(TStringBuf data, IMetricConsumer* c, TStringBuf metricNameLabel) {
- TCommonPartsCollector commonPartsCollector;
- {
- TMemoryInput memIn(data);
+ TCommonPartsCollector commonPartsCollector;
+ {
+ TMemoryInput memIn(data);
TDecoderJson decoder(data, &commonPartsCollector, metricNameLabel);
- // no need to check a return value. If there is an error, a TJsonDecodeError is thrown
- NJson::ReadJson(&memIn, &decoder);
- }
+ // no need to check a return value. If there is an error, a TJsonDecodeError is thrown
+ NJson::ReadJson(&memIn, &decoder);
+ }
- TCommonPartsProxy commonPartsProxy(std::move(commonPartsCollector.CommonParts()), c);
- {
- TMemoryInput memIn(data);
+ TCommonPartsProxy commonPartsProxy(std::move(commonPartsCollector.CommonParts()), c);
+ {
+ TMemoryInput memIn(data);
TDecoderJson decoder(data, &commonPartsProxy, metricNameLabel);
- // no need to check a return value. If there is an error, a TJsonDecodeError is thrown
- NJson::ReadJson(&memIn, &decoder);
- }
-}
-
-#undef DECODE_ENSURE
+ // no need to check a return value. If there is an error, a TJsonDecodeError is thrown
+ NJson::ReadJson(&memIn, &decoder);
+ }
+}
+#undef DECODE_ENSURE
+
}
diff --git a/library/cpp/monlib/encode/json/json_decoder_ut.cpp b/library/cpp/monlib/encode/json/json_decoder_ut.cpp
index 4464e1d26a..1f9513664a 100644
--- a/library/cpp/monlib/encode/json/json_decoder_ut.cpp
+++ b/library/cpp/monlib/encode/json/json_decoder_ut.cpp
@@ -1,125 +1,125 @@
-#include "json_decoder.cpp"
-
-#include <library/cpp/monlib/consumers/collecting_consumer.h>
-#include <library/cpp/testing/unittest/registar.h>
-
-#include <array>
-
-
-using namespace NMonitoring;
-
-enum EJsonPart : ui8 {
- METRICS = 0,
- COMMON_TS = 1,
- COMMON_LABELS = 2,
-};
-
-constexpr std::array<TStringBuf, 3> JSON_PARTS = {
+#include "json_decoder.cpp"
+
+#include <library/cpp/monlib/consumers/collecting_consumer.h>
+#include <library/cpp/testing/unittest/registar.h>
+
+#include <array>
+
+
+using namespace NMonitoring;
+
+enum EJsonPart : ui8 {
+ METRICS = 0,
+ COMMON_TS = 1,
+ COMMON_LABELS = 2,
+};
+
+constexpr std::array<TStringBuf, 3> JSON_PARTS = {
TStringBuf(R"("metrics": [{
- "labels": { "key": "value" },
- "type": "GAUGE",
- "value": 123
- }])"),
-
+ "labels": { "key": "value" },
+ "type": "GAUGE",
+ "value": 123
+ }])"),
+
TStringBuf(R"("ts": 1)"),
-
+
TStringBuf(R"("commonLabels": {
- "key1": "value1",
- "key2": "value2"
- })"),
-};
-
-TString BuildJson(std::initializer_list<EJsonPart> parts) {
- TString data = "{";
-
- for (auto it = parts.begin(); it != parts.end(); ++it) {
- data += JSON_PARTS[*it];
-
- if (it + 1 != parts.end()) {
- data += ",";
- }
- }
-
- data += "}";
- return data;
-}
-
-void ValidateCommonParts(TCommonParts&& commonParts, bool checkLabels, bool checkTs) {
- if (checkTs) {
- UNIT_ASSERT_VALUES_EQUAL(commonParts.CommonTime.MilliSeconds(), 1000);
- }
-
- if (checkLabels) {
- auto& labels = commonParts.CommonLabels;
- UNIT_ASSERT_VALUES_EQUAL(labels.Size(), 2);
+ "key1": "value1",
+ "key2": "value2"
+ })"),
+};
+
+TString BuildJson(std::initializer_list<EJsonPart> parts) {
+ TString data = "{";
+
+ for (auto it = parts.begin(); it != parts.end(); ++it) {
+ data += JSON_PARTS[*it];
+
+ if (it + 1 != parts.end()) {
+ data += ",";
+ }
+ }
+
+ data += "}";
+ return data;
+}
+
+void ValidateCommonParts(TCommonParts&& commonParts, bool checkLabels, bool checkTs) {
+ if (checkTs) {
+ UNIT_ASSERT_VALUES_EQUAL(commonParts.CommonTime.MilliSeconds(), 1000);
+ }
+
+ if (checkLabels) {
+ auto& labels = commonParts.CommonLabels;
+ UNIT_ASSERT_VALUES_EQUAL(labels.Size(), 2);
UNIT_ASSERT(labels.Has(TStringBuf("key1")));
UNIT_ASSERT(labels.Has(TStringBuf("key2")));
UNIT_ASSERT_VALUES_EQUAL(labels.Get(TStringBuf("key1")).value()->Value(), "value1");
UNIT_ASSERT_VALUES_EQUAL(labels.Get(TStringBuf("key2")).value()->Value(), "value2");
- }
-}
-
-void ValidateMetrics(const TVector<TMetricData>& metrics) {
- UNIT_ASSERT_VALUES_EQUAL(metrics.size(), 1);
-
- auto& m = metrics[0];
- UNIT_ASSERT_VALUES_EQUAL(m.Kind, EMetricType::GAUGE);
- auto& l = m.Labels;
- UNIT_ASSERT_VALUES_EQUAL(l.Size(), 1);
- UNIT_ASSERT_VALUES_EQUAL(l.Get(0)->Name(), "key");
- UNIT_ASSERT_VALUES_EQUAL(l.Get(0)->Value(), "value");
-
- UNIT_ASSERT_VALUES_EQUAL(m.Values->Size(), 1);
- UNIT_ASSERT_VALUES_EQUAL((*m.Values)[0].GetValue().AsDouble(), 123);
-}
-
+ }
+}
+
+void ValidateMetrics(const TVector<TMetricData>& metrics) {
+ UNIT_ASSERT_VALUES_EQUAL(metrics.size(), 1);
+
+ auto& m = metrics[0];
+ UNIT_ASSERT_VALUES_EQUAL(m.Kind, EMetricType::GAUGE);
+ auto& l = m.Labels;
+ UNIT_ASSERT_VALUES_EQUAL(l.Size(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(l.Get(0)->Name(), "key");
+ UNIT_ASSERT_VALUES_EQUAL(l.Get(0)->Value(), "value");
+
+ UNIT_ASSERT_VALUES_EQUAL(m.Values->Size(), 1);
+ UNIT_ASSERT_VALUES_EQUAL((*m.Values)[0].GetValue().AsDouble(), 123);
+}
+
void CheckCommonPartsCollector(TString data, bool shouldBeStopped, bool checkLabels = true, bool checkTs = true, TStringBuf metricNameLabel = "name") {
- TCommonPartsCollector commonPartsCollector;
- TMemoryInput memIn(data);
+ TCommonPartsCollector commonPartsCollector;
+ TMemoryInput memIn(data);
TDecoderJson decoder(data, &commonPartsCollector, metricNameLabel);
-
- bool isOk{false};
- UNIT_ASSERT_NO_EXCEPTION(isOk = NJson::ReadJson(&memIn, &decoder));
- UNIT_ASSERT_VALUES_EQUAL(isOk, !shouldBeStopped);
-
- ValidateCommonParts(commonPartsCollector.CommonParts(), checkLabels, checkTs);
-}
-
-Y_UNIT_TEST_SUITE(TJsonDecoderTest) {
- Y_UNIT_TEST(FullCommonParts) {
- CheckCommonPartsCollector(BuildJson({COMMON_LABELS, COMMON_TS, METRICS}), true);
- CheckCommonPartsCollector(BuildJson({COMMON_TS, COMMON_LABELS, METRICS}), true);
-
- CheckCommonPartsCollector(BuildJson({METRICS, COMMON_TS, COMMON_LABELS}), true);
- CheckCommonPartsCollector(BuildJson({METRICS, COMMON_LABELS, COMMON_TS}), true);
-
- CheckCommonPartsCollector(BuildJson({COMMON_LABELS, METRICS, COMMON_TS}), true);
- CheckCommonPartsCollector(BuildJson({COMMON_TS, METRICS, COMMON_LABELS}), true);
- }
-
- Y_UNIT_TEST(PartialCommonParts) {
- CheckCommonPartsCollector(BuildJson({COMMON_TS, METRICS}), false, false, true);
- CheckCommonPartsCollector(BuildJson({COMMON_LABELS, METRICS}), false, true, false);
-
- CheckCommonPartsCollector(BuildJson({METRICS, COMMON_LABELS}), false, true, false);
- CheckCommonPartsCollector(BuildJson({METRICS, COMMON_TS}), false, false, true);
-
- CheckCommonPartsCollector(BuildJson({METRICS}), false, false, false);
- }
-
- Y_UNIT_TEST(CheckCommonPartsAndMetrics) {
- auto data = BuildJson({COMMON_LABELS, COMMON_TS, METRICS});
- TCollectingConsumer collector;
-
- DecodeJson(data, &collector);
-
- TCommonParts commonParts;
- commonParts.CommonTime = collector.CommonTime;
- commonParts.CommonLabels = collector.CommonLabels;
-
- ValidateCommonParts(std::move(commonParts), true, true);
- ValidateMetrics(collector.Metrics);
- }
+
+ bool isOk{false};
+ UNIT_ASSERT_NO_EXCEPTION(isOk = NJson::ReadJson(&memIn, &decoder));
+ UNIT_ASSERT_VALUES_EQUAL(isOk, !shouldBeStopped);
+
+ ValidateCommonParts(commonPartsCollector.CommonParts(), checkLabels, checkTs);
+}
+
+Y_UNIT_TEST_SUITE(TJsonDecoderTest) {
+ Y_UNIT_TEST(FullCommonParts) {
+ CheckCommonPartsCollector(BuildJson({COMMON_LABELS, COMMON_TS, METRICS}), true);
+ CheckCommonPartsCollector(BuildJson({COMMON_TS, COMMON_LABELS, METRICS}), true);
+
+ CheckCommonPartsCollector(BuildJson({METRICS, COMMON_TS, COMMON_LABELS}), true);
+ CheckCommonPartsCollector(BuildJson({METRICS, COMMON_LABELS, COMMON_TS}), true);
+
+ CheckCommonPartsCollector(BuildJson({COMMON_LABELS, METRICS, COMMON_TS}), true);
+ CheckCommonPartsCollector(BuildJson({COMMON_TS, METRICS, COMMON_LABELS}), true);
+ }
+
+ Y_UNIT_TEST(PartialCommonParts) {
+ CheckCommonPartsCollector(BuildJson({COMMON_TS, METRICS}), false, false, true);
+ CheckCommonPartsCollector(BuildJson({COMMON_LABELS, METRICS}), false, true, false);
+
+ CheckCommonPartsCollector(BuildJson({METRICS, COMMON_LABELS}), false, true, false);
+ CheckCommonPartsCollector(BuildJson({METRICS, COMMON_TS}), false, false, true);
+
+ CheckCommonPartsCollector(BuildJson({METRICS}), false, false, false);
+ }
+
+ Y_UNIT_TEST(CheckCommonPartsAndMetrics) {
+ auto data = BuildJson({COMMON_LABELS, COMMON_TS, METRICS});
+ TCollectingConsumer collector;
+
+ DecodeJson(data, &collector);
+
+ TCommonParts commonParts;
+ commonParts.CommonTime = collector.CommonTime;
+ commonParts.CommonLabels = collector.CommonLabels;
+
+ ValidateCommonParts(std::move(commonParts), true, true);
+ ValidateMetrics(collector.Metrics);
+ }
Y_UNIT_TEST(CanParseHistogramsWithInf) {
const char* metricsData = R"({
@@ -176,4 +176,4 @@ Y_UNIT_TEST_SUITE(TJsonDecoderTest) {
UNIT_ASSERT_VALUES_EQUAL(histogram->Value(0), 21);
}
}
-}
+}
diff --git a/library/cpp/monlib/encode/json/json_encoder.cpp b/library/cpp/monlib/encode/json/json_encoder.cpp
index 20d2bb6283..db39a2a910 100644
--- a/library/cpp/monlib/encode/json/json_encoder.cpp
+++ b/library/cpp/monlib/encode/json/json_encoder.cpp
@@ -9,7 +9,7 @@
#include <library/cpp/json/writer/json.h>
-#include <util/charset/utf8.h>
+#include <util/charset/utf8.h>
#include <util/generic/algorithm.h>
namespace NMonitoring {
@@ -245,12 +245,12 @@ namespace NMonitoring {
private:
void OnStreamBegin() override {
- State_.Expect(TEncoderState::EState::ROOT);
+ State_.Expect(TEncoderState::EState::ROOT);
Buf_.BeginObject();
}
void OnStreamEnd() override {
- State_.Expect(TEncoderState::EState::ROOT);
+ State_.Expect(TEncoderState::EState::ROOT);
if (!Buf_.KeyExpected()) {
// not closed metrics array
Buf_.EndList();
@@ -259,7 +259,7 @@ namespace NMonitoring {
}
void OnCommonTime(TInstant time) override {
- State_.Expect(TEncoderState::EState::ROOT);
+ State_.Expect(TEncoderState::EState::ROOT);
WriteTime(time);
}
@@ -298,8 +298,8 @@ namespace NMonitoring {
// not closed metrics or timeseries array if labels go after values
Buf_.EndList();
}
- if (State_ == TEncoderState::EState::ROOT) {
- State_ = TEncoderState::EState::COMMON_LABELS;
+ if (State_ == TEncoderState::EState::ROOT) {
+ State_ = TEncoderState::EState::COMMON_LABELS;
Buf_.WriteKey(TStringBuf(Style_ == EJsonStyle::Solomon ? "commonLabels" : "labels"));
} else if (State_ == TEncoderState::EState::METRIC) {
State_ = TEncoderState::EState::METRIC_LABELS;
@@ -315,8 +315,8 @@ namespace NMonitoring {
void OnLabelsEnd() override {
if (State_ == TEncoderState::EState::METRIC_LABELS) {
State_ = TEncoderState::EState::METRIC;
- } else if (State_ == TEncoderState::EState::COMMON_LABELS) {
- State_ = TEncoderState::EState::ROOT;
+ } else if (State_ == TEncoderState::EState::COMMON_LABELS) {
+ State_ = TEncoderState::EState::ROOT;
} else {
State_.ThrowInvalid("expected LABELS or COMMON_LABELS");
}
@@ -430,16 +430,16 @@ namespace NMonitoring {
Close();
}
- void OnLabelsBegin() override {
- TBufferedEncoderBase::OnLabelsBegin();
- EmptyLabels_ = true;
- }
-
+ void OnLabelsBegin() override {
+ TBufferedEncoderBase::OnLabelsBegin();
+ EmptyLabels_ = true;
+ }
+
void OnLabel(TStringBuf name, TStringBuf value) override {
- TBufferedEncoderBase::OnLabel(name, value);
- EmptyLabels_ = false;
- }
-
+ TBufferedEncoderBase::OnLabel(name, value);
+ EmptyLabels_ = false;
+ }
+
void OnLabel(ui32 name, ui32 value) override {
TBufferedEncoderBase::OnLabel(name, value);
EmptyLabels_ = false;
@@ -447,10 +447,10 @@ namespace NMonitoring {
void OnLabelsEnd() override {
TBufferedEncoderBase::OnLabelsEnd();
- Y_ENSURE(!EmptyLabels_, "Labels cannot be empty");
+ Y_ENSURE(!EmptyLabels_, "Labels cannot be empty");
}
- void Close() final {
+ void Close() final {
if (Closed_) {
return;
}
@@ -534,7 +534,7 @@ namespace NMonitoring {
private:
bool Closed_{false};
- bool EmptyLabels_ = false;
+ bool EmptyLabels_ = false;
};
}
diff --git a/library/cpp/monlib/encode/json/json_ut.cpp b/library/cpp/monlib/encode/json/json_ut.cpp
index 09e7909289..5de8470fcf 100644
--- a/library/cpp/monlib/encode/json/json_ut.cpp
+++ b/library/cpp/monlib/encode/json/json_ut.cpp
@@ -559,21 +559,21 @@ Y_UNIT_TEST_SUITE(TJsonTest) {
}
}
- Y_UNIT_TEST(DecodeToEncoder) {
- auto testJson = NResource::Find("/test_decode_to_encode.json");
-
- TStringStream Stream_;
- auto encoder = BufferedEncoderJson(&Stream_, 4);
- DecodeJson(testJson, encoder.Get());
-
- encoder->Close();
-
- auto val1 = NJson::ReadJsonFastTree(testJson, true);
- auto val2 = NJson::ReadJsonFastTree(Stream_.Str(), true);
-
- UNIT_ASSERT_VALUES_EQUAL(val1, val2);
- }
-
+ Y_UNIT_TEST(DecodeToEncoder) {
+ auto testJson = NResource::Find("/test_decode_to_encode.json");
+
+ TStringStream Stream_;
+ auto encoder = BufferedEncoderJson(&Stream_, 4);
+ DecodeJson(testJson, encoder.Get());
+
+ encoder->Close();
+
+ auto val1 = NJson::ReadJsonFastTree(testJson, true);
+ auto val2 = NJson::ReadJsonFastTree(Stream_.Str(), true);
+
+ UNIT_ASSERT_VALUES_EQUAL(val1, val2);
+ }
+
void WriteEmptySeries(const IMetricEncoderPtr& e) {
e->OnStreamBegin();
{
@@ -1033,12 +1033,12 @@ Y_UNIT_TEST_SUITE(TJsonTest) {
AssertPointEqual(s.GetPoints(1), now + TDuration::Seconds(15), *logHist);
}
- void HistogramValueDecode(const TString& filePath) {
+ void HistogramValueDecode(const TString& filePath) {
NProto::TMultiSamplesList samples;
{
IMetricEncoderPtr e = EncoderProtobuf(&samples);
- TString testJson = NResource::Find(filePath);
+ TString testJson = NResource::Find(filePath);
DecodeJson(testJson, e.Get());
}
@@ -1059,11 +1059,11 @@ Y_UNIT_TEST_SUITE(TJsonTest) {
AssertPointEqual(s.GetPoints(0), now, *h->Snapshot());
}
- Y_UNIT_TEST(HistogramValueDecode) {
- HistogramValueDecode("/histogram_value.json");
- HistogramValueDecode("/histogram_value_inf_before_bounds.json");
- }
-
+ Y_UNIT_TEST(HistogramValueDecode) {
+ HistogramValueDecode("/histogram_value.json");
+ HistogramValueDecode("/histogram_value_inf_before_bounds.json");
+ }
+
Y_UNIT_TEST(HistogramTimeSeriesEncode) {
auto writeDocument = [](IMetricEncoder* e) {
e->OnStreamBegin();
diff --git a/library/cpp/monlib/encode/json/typed_point.h b/library/cpp/monlib/encode/json/typed_point.h
index fbaa840c4b..8da50217f0 100644
--- a/library/cpp/monlib/encode/json/typed_point.h
+++ b/library/cpp/monlib/encode/json/typed_point.h
@@ -45,7 +45,7 @@ namespace NMonitoring {
return *this;
}
- TTypedPoint(TTypedPoint&& rhs) noexcept
+ TTypedPoint(TTypedPoint&& rhs) noexcept
: Time_(rhs.Time_)
, ValueType_(rhs.ValueType_)
, Value_(rhs.Value_)
@@ -54,7 +54,7 @@ namespace NMonitoring {
rhs.Value_ = {};
}
- TTypedPoint& operator=(TTypedPoint&& rhs) noexcept {
+ TTypedPoint& operator=(TTypedPoint&& rhs) noexcept {
UnRef();
Time_ = rhs.Time_;
diff --git a/library/cpp/monlib/encode/json/ut/buffered_ts_merge.json b/library/cpp/monlib/encode/json/ut/buffered_ts_merge.json
index 1d27efacb0..cdcca789fe 100644
--- a/library/cpp/monlib/encode/json/ut/buffered_ts_merge.json
+++ b/library/cpp/monlib/encode/json/ut/buffered_ts_merge.json
@@ -7,7 +7,7 @@
{
"foo":"bar"
},
- "value":45
+ "value":45
}
]
}
diff --git a/library/cpp/monlib/encode/json/ut/histogram_value_inf_before_bounds.json b/library/cpp/monlib/encode/json/ut/histogram_value_inf_before_bounds.json
index f8a17c8831..7fb99fe768 100644
--- a/library/cpp/monlib/encode/json/ut/histogram_value_inf_before_bounds.json
+++ b/library/cpp/monlib/encode/json/ut/histogram_value_inf_before_bounds.json
@@ -1,33 +1,33 @@
-{
- "sensors":
- [
- {
- "kind":"HIST",
- "labels":
- {
+{
+ "sensors":
+ [
+ {
+ "kind":"HIST",
+ "labels":
+ {
"metric":"responseTimeMillis"
- },
- "ts":1509843723,
- "hist":
- {
- "inf":83,
- "bounds":
- [
- 1,
- 2,
- 4,
- 8,
- 16
- ],
- "buckets":
- [
- 1,
- 1,
- 2,
- 4,
- 8
- ]
- }
- }
- ]
-}
+ },
+ "ts":1509843723,
+ "hist":
+ {
+ "inf":83,
+ "bounds":
+ [
+ 1,
+ 2,
+ 4,
+ 8,
+ 16
+ ],
+ "buckets":
+ [
+ 1,
+ 1,
+ 2,
+ 4,
+ 8
+ ]
+ }
+ }
+ ]
+}
diff --git a/library/cpp/monlib/encode/json/ut/test_decode_to_encode.json b/library/cpp/monlib/encode/json/ut/test_decode_to_encode.json
index 65f0c5c6e2..d127981c97 100644
--- a/library/cpp/monlib/encode/json/ut/test_decode_to_encode.json
+++ b/library/cpp/monlib/encode/json/ut/test_decode_to_encode.json
@@ -1,16 +1,16 @@
-{
- "commonLabels": {
- "project": "solomon",
- "cluster": "man",
- "service": "stockpile"
- },
- "sensors": [
- {
- "kind": "GAUGE",
+{
+ "commonLabels": {
+ "project": "solomon",
+ "cluster": "man",
+ "service": "stockpile"
+ },
+ "sensors": [
+ {
+ "kind": "GAUGE",
"labels": { "export": "Oxygen", "metric": "QueueSize" },
- "ts": 1509885296,
- "value": 3.14159
- }
- ],
- "ts": 1503837296
-}
+ "ts": 1509885296,
+ "value": 3.14159
+ }
+ ],
+ "ts": 1503837296
+}
diff --git a/library/cpp/monlib/encode/json/ut/ya.make b/library/cpp/monlib/encode/json/ut/ya.make
index e50c4f4903..bfa12d159e 100644
--- a/library/cpp/monlib/encode/json/ut/ya.make
+++ b/library/cpp/monlib/encode/json/ut/ya.make
@@ -6,7 +6,7 @@ OWNER(
)
SRCS(
- json_decoder_ut.cpp
+ json_decoder_ut.cpp
json_ut.cpp
)
@@ -21,12 +21,12 @@ RESOURCE(
merged.json /merged.json
histogram_timeseries.json /histogram_timeseries.json
histogram_value.json /histogram_value.json
- histogram_value_inf_before_bounds.json /histogram_value_inf_before_bounds.json
+ histogram_value_inf_before_bounds.json /histogram_value_inf_before_bounds.json
int_gauge.json /int_gauge.json
sensors.json /sensors.json
metrics.json /metrics.json
named_metrics.json /named_metrics.json
- test_decode_to_encode.json /test_decode_to_encode.json
+ test_decode_to_encode.json /test_decode_to_encode.json
crash.json /crash.json
hist_crash.json /hist_crash.json
summary_value.json /summary_value.json
@@ -38,7 +38,7 @@ RESOURCE(
PEERDIR(
library/cpp/json
- library/cpp/monlib/consumers
+ library/cpp/monlib/consumers
library/cpp/monlib/encode/protobuf
library/cpp/resource
)
diff --git a/library/cpp/monlib/encode/json/ya.make b/library/cpp/monlib/encode/json/ya.make
index a50fc412a9..9229ff1292 100644
--- a/library/cpp/monlib/encode/json/ya.make
+++ b/library/cpp/monlib/encode/json/ya.make
@@ -11,9 +11,9 @@ SRCS(
)
PEERDIR(
- library/cpp/monlib/encode
- library/cpp/monlib/encode/buffered
- library/cpp/monlib/exception
+ library/cpp/monlib/encode
+ library/cpp/monlib/encode/buffered
+ library/cpp/monlib/exception
library/cpp/json
library/cpp/json/writer
)