diff options
author | msherbakov <msherbakov@yandex-team.ru> | 2022-02-10 16:49:17 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:49:17 +0300 |
commit | a0ffafe83b7d6229709a32fa942c71d672ac989c (patch) | |
tree | 5d5cb817648f650d76cf1076100726fd9b8448e8 /library/cpp/monlib/encode/unistat | |
parent | c224a621661ddd69699f9476922eb316607ef57e (diff) | |
download | ydb-a0ffafe83b7d6229709a32fa942c71d672ac989c.tar.gz |
Restoring authorship annotation for <msherbakov@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/monlib/encode/unistat')
-rw-r--r-- | library/cpp/monlib/encode/unistat/unistat.h | 22 | ||||
-rw-r--r-- | library/cpp/monlib/encode/unistat/unistat_decoder.cpp | 412 | ||||
-rw-r--r-- | library/cpp/monlib/encode/unistat/unistat_ut.cpp | 378 | ||||
-rw-r--r-- | library/cpp/monlib/encode/unistat/ut/ya.make | 28 | ||||
-rw-r--r-- | library/cpp/monlib/encode/unistat/ya.make | 32 |
5 files changed, 436 insertions, 436 deletions
diff --git a/library/cpp/monlib/encode/unistat/unistat.h b/library/cpp/monlib/encode/unistat/unistat.h index 460141b5bc8..1c43b7fa1b7 100644 --- a/library/cpp/monlib/encode/unistat/unistat.h +++ b/library/cpp/monlib/encode/unistat/unistat.h @@ -1,13 +1,13 @@ -#pragma once - -#include <util/generic/fwd.h> -#include <util/datetime/base.h> - -namespace NMonitoring { - /// Decodes unistat-style metrics - /// https://wiki.yandex-team.ru/golovan/stat-handle +#pragma once + +#include <util/generic/fwd.h> +#include <util/datetime/base.h> + +namespace NMonitoring { + /// Decodes unistat-style metrics + /// https://wiki.yandex-team.ru/golovan/stat-handle void DecodeUnistat(TStringBuf data, class IMetricConsumer* c, TInstant ts = TInstant::Zero()); - - /// Assumes consumer's stream is open by the caller + + /// Assumes consumer's stream is open by the caller void DecodeUnistatToStream(TStringBuf data, class IMetricConsumer* c, TInstant = TInstant::Zero()); -} +} diff --git a/library/cpp/monlib/encode/unistat/unistat_decoder.cpp b/library/cpp/monlib/encode/unistat/unistat_decoder.cpp index 8006d340704..b2344b0905c 100644 --- a/library/cpp/monlib/encode/unistat/unistat_decoder.cpp +++ b/library/cpp/monlib/encode/unistat/unistat_decoder.cpp @@ -1,253 +1,253 @@ -#include "unistat.h" - +#include "unistat.h" + #include <library/cpp/monlib/metrics/histogram_collector.h> #include <library/cpp/monlib/metrics/labels.h> #include <library/cpp/monlib/metrics/metric_type.h> #include <library/cpp/monlib/metrics/metric_value.h> #include <library/cpp/monlib/metrics/metric_consumer.h> - + #include <library/cpp/json/json_reader.h> - -#include <util/datetime/base.h> + +#include <util/datetime/base.h> #include <util/string/split.h> - -#include <contrib/libs/re2/re2/re2.h> - -using namespace NJson; - + +#include <contrib/libs/re2/re2/re2.h> + +using namespace NJson; + const re2::RE2 NAME_RE{R"((?:[a-zA-Z0-9\.\-/@_]+_)+(?:[ad][vehmntx]{3}|summ|hgram|max))"}; - -namespace NMonitoring { - namespace { - bool IsNumber(const NJson::TJsonValue& j) { - switch (j.GetType()) { - case EJsonValueType::JSON_INTEGER: - case EJsonValueType::JSON_UINTEGER: - case EJsonValueType::JSON_DOUBLE: - return true; - - default: - return false; - } - } - - template <typename T> - T ExtractNumber(const TJsonValue& val) { - switch (val.GetType()) { - case EJsonValueType::JSON_INTEGER: - return static_cast<T>(val.GetInteger()); - case EJsonValueType::JSON_UINTEGER: - return static_cast<T>(val.GetUInteger()); - case EJsonValueType::JSON_DOUBLE: - return static_cast<T>(val.GetDouble()); - - default: - ythrow yexception() << "Expected number, but found " << val.GetType(); - } - } - - auto ExtractDouble = ExtractNumber<double>; - auto ExtractUi64 = ExtractNumber<ui64>; - + +namespace NMonitoring { + namespace { + bool IsNumber(const NJson::TJsonValue& j) { + switch (j.GetType()) { + case EJsonValueType::JSON_INTEGER: + case EJsonValueType::JSON_UINTEGER: + case EJsonValueType::JSON_DOUBLE: + return true; + + default: + return false; + } + } + + template <typename T> + T ExtractNumber(const TJsonValue& val) { + switch (val.GetType()) { + case EJsonValueType::JSON_INTEGER: + return static_cast<T>(val.GetInteger()); + case EJsonValueType::JSON_UINTEGER: + return static_cast<T>(val.GetUInteger()); + case EJsonValueType::JSON_DOUBLE: + return static_cast<T>(val.GetDouble()); + + default: + ythrow yexception() << "Expected number, but found " << val.GetType(); + } + } + + auto ExtractDouble = ExtractNumber<double>; + auto ExtractUi64 = ExtractNumber<ui64>; + class THistogramBuilder { - public: - void Add(TBucketBound bound, TBucketValue value) { - /// XXX: yasm uses left-closed intervals, while in monlib we use right-closed ones, - /// so (-inf; 0) [0, 100) [100; +inf) - /// becomes (-inf; 0] (0, 100] (100; +inf) - /// but since we've already lost some information these no way to avoid this kind of error here - Bounds_.push_back(bound); - - /// this will always be 0 for the first bucket, - /// since there's no way to make (-inf; N) bucket in yasm - Values_.push_back(NextValue_); - - /// we will write this value into the next bucket so that [[0, 10], [100, 20], [200, 50]] - /// becomes (-inf; 0] -> 0; (0; 100] -> 10; (100; 200] -> 20; (200; +inf) -> 50 - NextValue_ = value; - } - + public: + void Add(TBucketBound bound, TBucketValue value) { + /// XXX: yasm uses left-closed intervals, while in monlib we use right-closed ones, + /// so (-inf; 0) [0, 100) [100; +inf) + /// becomes (-inf; 0] (0, 100] (100; +inf) + /// but since we've already lost some information these no way to avoid this kind of error here + Bounds_.push_back(bound); + + /// this will always be 0 for the first bucket, + /// since there's no way to make (-inf; N) bucket in yasm + Values_.push_back(NextValue_); + + /// we will write this value into the next bucket so that [[0, 10], [100, 20], [200, 50]] + /// becomes (-inf; 0] -> 0; (0; 100] -> 10; (100; 200] -> 20; (200; +inf) -> 50 + NextValue_ = value; + } + IHistogramSnapshotPtr Finalize() { - Bounds_.push_back(std::numeric_limits<TBucketBound>::max()); - Values_.push_back(NextValue_); - + Bounds_.push_back(std::numeric_limits<TBucketBound>::max()); + Values_.push_back(NextValue_); + Y_ENSURE(Bounds_.size() <= HISTOGRAM_MAX_BUCKETS_COUNT, "Histogram is only allowed to have " << HISTOGRAM_MAX_BUCKETS_COUNT << " buckets, but has " << Bounds_.size()); - + return ExplicitHistogramSnapshot(Bounds_, Values_); - } - - public: - TBucketValue NextValue_ {0}; - TBucketBounds Bounds_; - TBucketValues Values_; - }; - - class TDecoderUnistat { - private: - public: + } + + public: + TBucketValue NextValue_ {0}; + TBucketBounds Bounds_; + TBucketValues Values_; + }; + + class TDecoderUnistat { + private: + public: explicit TDecoderUnistat(IMetricConsumer* consumer, IInputStream* is, TInstant ts) - : Consumer_{consumer} - , Timestamp_{ts} { - ReadJsonTree(is, &Json_, /* throw */ true); - } - - void Decode() { - Y_ENSURE(Json_.IsArray(), "Expected array at the top level, but found " << Json_.GetType()); - - for (auto&& metric : Json_.GetArray()) { - Y_ENSURE(metric.IsArray(), "Metric must be an array"); - auto&& arr = metric.GetArray(); - Y_ENSURE(arr.size() == 2, "Metric must be an array of 2 elements"); - auto&& name = arr[0]; - auto&& value = arr[1]; - MetricContext_ = {}; - - ParseName(name.GetString()); - - if (value.IsArray()) { - OnHistogram(value); - } else if (IsNumber(value)) { - OnScalar(value); - } else { - ythrow yexception() << "Expected list or number, but found " << value.GetType(); - } - - WriteValue(); - } - } - - private: - void OnScalar(const TJsonValue& jsonValue) { - if (MetricContext_.IsDeriv) { + : Consumer_{consumer} + , Timestamp_{ts} { + ReadJsonTree(is, &Json_, /* throw */ true); + } + + void Decode() { + Y_ENSURE(Json_.IsArray(), "Expected array at the top level, but found " << Json_.GetType()); + + for (auto&& metric : Json_.GetArray()) { + Y_ENSURE(metric.IsArray(), "Metric must be an array"); + auto&& arr = metric.GetArray(); + Y_ENSURE(arr.size() == 2, "Metric must be an array of 2 elements"); + auto&& name = arr[0]; + auto&& value = arr[1]; + MetricContext_ = {}; + + ParseName(name.GetString()); + + if (value.IsArray()) { + OnHistogram(value); + } else if (IsNumber(value)) { + OnScalar(value); + } else { + ythrow yexception() << "Expected list or number, but found " << value.GetType(); + } + + WriteValue(); + } + } + + private: + void OnScalar(const TJsonValue& jsonValue) { + if (MetricContext_.IsDeriv) { MetricContext_.Type = EMetricType::RATE; MetricContext_.Value = TMetricValue{ExtractUi64(jsonValue)}; - } else { + } else { MetricContext_.Type = EMetricType::GAUGE; MetricContext_.Value = TMetricValue{ExtractDouble(jsonValue)}; - } - } - - void OnHistogram(const TJsonValue& jsonHist) { - if (MetricContext_.IsDeriv) { + } + } + + void OnHistogram(const TJsonValue& jsonHist) { + if (MetricContext_.IsDeriv) { MetricContext_.Type = EMetricType::HIST_RATE; - } else { + } else { MetricContext_.Type = EMetricType::HIST; - } - + } + auto histogramBuilder = THistogramBuilder(); - - for (auto&& bucket : jsonHist.GetArray()) { - Y_ENSURE(bucket.IsArray(), "Expected an array, but found " << bucket.GetType()); - auto&& arr = bucket.GetArray(); - Y_ENSURE(arr.size() == 2, "Histogram bucket must be an array of 2 elements"); - const auto bound = ExtractDouble(arr[0]); - const auto weight = ExtractUi64(arr[1]); + + for (auto&& bucket : jsonHist.GetArray()) { + Y_ENSURE(bucket.IsArray(), "Expected an array, but found " << bucket.GetType()); + auto&& arr = bucket.GetArray(); + Y_ENSURE(arr.size() == 2, "Histogram bucket must be an array of 2 elements"); + const auto bound = ExtractDouble(arr[0]); + const auto weight = ExtractUi64(arr[1]); histogramBuilder.Add(bound, weight); - } - + } + MetricContext_.Histogram = histogramBuilder.Finalize(); MetricContext_.Value = TMetricValue{MetricContext_.Histogram.Get()}; - } - - bool IsDeriv(TStringBuf name) { - TStringBuf ignore, suffix; - name.RSplit('_', ignore, suffix); - - Y_ENSURE(suffix.size() >= 3 && suffix.size() <= 5, "Disallowed suffix value: " << suffix); - + } + + bool IsDeriv(TStringBuf name) { + TStringBuf ignore, suffix; + name.RSplit('_', ignore, suffix); + + Y_ENSURE(suffix.size() >= 3 && suffix.size() <= 5, "Disallowed suffix value: " << suffix); + if (suffix == TStringBuf("summ") || suffix == TStringBuf("hgram")) { - return true; + return true; } else if (suffix == TStringBuf("max")) { - return false; - } - - return suffix[0] == 'd'; - } - - void ParseName(TStringBuf value) { - TVector<TStringBuf> parts; - StringSplitter(value).Split(';').SkipEmpty().Collect(&parts); - - Y_ENSURE(parts.size() >= 1 && parts.size() <= 16); - - TStringBuf name = parts.back(); - parts.pop_back(); - + return false; + } + + return suffix[0] == 'd'; + } + + void ParseName(TStringBuf value) { + TVector<TStringBuf> parts; + StringSplitter(value).Split(';').SkipEmpty().Collect(&parts); + + Y_ENSURE(parts.size() >= 1 && parts.size() <= 16); + + TStringBuf name = parts.back(); + parts.pop_back(); + Y_ENSURE(RE2::FullMatch(re2::StringPiece{name.data(), name.size()}, NAME_RE), - "Metric name " << name << " doesn't match regex " << NAME_RE.pattern()); - - MetricContext_.Name = name; - MetricContext_.IsDeriv = IsDeriv(MetricContext_.Name); - - for (auto tag : parts) { - TStringBuf n, v; - tag.Split('=', n, v); - Y_ENSURE(n && v, "Unexpected tag format in " << tag); - MetricContext_.Labels.Add(n, v); - } - } - - private: - void WriteValue() { + "Metric name " << name << " doesn't match regex " << NAME_RE.pattern()); + + MetricContext_.Name = name; + MetricContext_.IsDeriv = IsDeriv(MetricContext_.Name); + + for (auto tag : parts) { + TStringBuf n, v; + tag.Split('=', n, v); + Y_ENSURE(n && v, "Unexpected tag format in " << tag); + MetricContext_.Labels.Add(n, v); + } + } + + private: + void WriteValue() { Consumer_->OnMetricBegin(MetricContext_.Type); - - Consumer_->OnLabelsBegin(); - Consumer_->OnLabel("sensor", TString{MetricContext_.Name}); - for (auto&& l : MetricContext_.Labels) { - Consumer_->OnLabel(l.Name(), l.Value()); - } - - Consumer_->OnLabelsEnd(); - + + Consumer_->OnLabelsBegin(); + Consumer_->OnLabel("sensor", TString{MetricContext_.Name}); + for (auto&& l : MetricContext_.Labels) { + Consumer_->OnLabel(l.Name(), l.Value()); + } + + Consumer_->OnLabelsEnd(); + switch (MetricContext_.Type) { case EMetricType::GAUGE: - Consumer_->OnDouble(Timestamp_, MetricContext_.Value.AsDouble()); - break; + Consumer_->OnDouble(Timestamp_, MetricContext_.Value.AsDouble()); + break; case EMetricType::RATE: - Consumer_->OnUint64(Timestamp_, MetricContext_.Value.AsUint64()); - break; + Consumer_->OnUint64(Timestamp_, MetricContext_.Value.AsUint64()); + break; case EMetricType::HIST: case EMetricType::HIST_RATE: - Consumer_->OnHistogram(Timestamp_, MetricContext_.Value.AsHistogram()); - break; + Consumer_->OnHistogram(Timestamp_, MetricContext_.Value.AsHistogram()); + break; case EMetricType::LOGHIST: case EMetricType::DSUMMARY: case EMetricType::IGAUGE: case EMetricType::COUNTER: case EMetricType::UNKNOWN: ythrow yexception() << "Unexpected metric type: " << MetricContext_.Type; - } - + } + Consumer_->OnMetricEnd(); - } - - private: + } + + private: IMetricConsumer* Consumer_; - NJson::TJsonValue Json_; - TInstant Timestamp_; - - struct { - TStringBuf Name; + NJson::TJsonValue Json_; + TInstant Timestamp_; + + struct { + TStringBuf Name; EMetricType Type{EMetricType::UNKNOWN}; TMetricValue Value; - bool IsDeriv{false}; - TLabels Labels; + bool IsDeriv{false}; + TLabels Labels; IHistogramSnapshotPtr Histogram; - } MetricContext_; - }; - - } - + } MetricContext_; + }; + + } + void DecodeUnistat(TStringBuf data, IMetricConsumer* c, TInstant ts) { - c->OnStreamBegin(); - DecodeUnistatToStream(data, c, ts); - c->OnStreamEnd(); - } - + c->OnStreamBegin(); + DecodeUnistatToStream(data, c, ts); + c->OnStreamEnd(); + } + void DecodeUnistatToStream(TStringBuf data, IMetricConsumer* c, TInstant ts) { TMemoryInput in{data.data(), data.size()}; - TDecoderUnistat decoder(c, &in, ts); - decoder.Decode(); - } -} + TDecoderUnistat decoder(c, &in, ts); + decoder.Decode(); + } +} diff --git a/library/cpp/monlib/encode/unistat/unistat_ut.cpp b/library/cpp/monlib/encode/unistat/unistat_ut.cpp index e55d41eec39..dbbc238bf32 100644 --- a/library/cpp/monlib/encode/unistat/unistat_ut.cpp +++ b/library/cpp/monlib/encode/unistat/unistat_ut.cpp @@ -1,124 +1,124 @@ -#include "unistat.h" - +#include "unistat.h" + #include <library/cpp/monlib/encode/protobuf/protobuf.h> #include <library/cpp/monlib/metrics/labels.h> - + #include <library/cpp/testing/unittest/registar.h> - -using namespace NMonitoring; - -Y_UNIT_TEST_SUITE(TUnistatDecoderTest) { - Y_UNIT_TEST(ScalarMetric) { + +using namespace NMonitoring; + +Y_UNIT_TEST_SUITE(TUnistatDecoderTest) { + Y_UNIT_TEST(ScalarMetric) { constexpr auto input = TStringBuf(R"([["something_axxx", 42]])"); - - NProto::TMultiSamplesList samples; - auto encoder = EncoderProtobuf(&samples); - - DecodeUnistat(input, encoder.Get()); - - UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); - auto sample = samples.GetSamples(0); + + NProto::TMultiSamplesList samples; + auto encoder = EncoderProtobuf(&samples); + + DecodeUnistat(input, encoder.Get()); + + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); + auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); - UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); - - auto label = sample.GetLabels(0); - auto point = sample.GetPoints(0); - UNIT_ASSERT_VALUES_EQUAL(point.GetFloat64(), 42.); - UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); - UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_axxx"); - } - - Y_UNIT_TEST(OverriddenTags) { + UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); + + auto label = sample.GetLabels(0); + auto point = sample.GetPoints(0); + UNIT_ASSERT_VALUES_EQUAL(point.GetFloat64(), 42.); + UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); + UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_axxx"); + } + + Y_UNIT_TEST(OverriddenTags) { constexpr auto input = TStringBuf(R"([["ctype=foo;prj=bar;custom_tag=qwe;something_axxx", 42]])"); - - NProto::TMultiSamplesList samples; - auto encoder = EncoderProtobuf(&samples); - - DecodeUnistat(input, encoder.Get()); - - UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); - auto sample = samples.GetSamples(0); - UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); + + NProto::TMultiSamplesList samples; + auto encoder = EncoderProtobuf(&samples); + + DecodeUnistat(input, encoder.Get()); + + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); + auto sample = samples.GetSamples(0); + UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 4); - - const auto& labels = sample.GetLabels(); - TLabels actual; - for (auto&& l : labels) { - actual.Add(l.GetName(), l.GetValue()); - } - + + const auto& labels = sample.GetLabels(); + TLabels actual; + for (auto&& l : labels) { + actual.Add(l.GetName(), l.GetValue()); + } + TLabels expected{{"ctype", "foo"}, {"prj", "bar"}, {"custom_tag", "qwe"}, {"sensor", "something_axxx"}}; - - UNIT_ASSERT_VALUES_EQUAL(actual.size(), expected.size()); - for (auto&& l : actual) { - UNIT_ASSERT(expected.Extract(l.Name())->Value() == l.Value()); - } - } - - Y_UNIT_TEST(ThrowsOnTopLevelObject) { + + UNIT_ASSERT_VALUES_EQUAL(actual.size(), expected.size()); + for (auto&& l : actual) { + UNIT_ASSERT(expected.Extract(l.Name())->Value() == l.Value()); + } + } + + Y_UNIT_TEST(ThrowsOnTopLevelObject) { constexpr auto input = TStringBuf(R"({["something_axxx", 42]})"); - - NProto::TMultiSamplesList samples; - auto encoder = EncoderProtobuf(&samples); - - UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); - } - - Y_UNIT_TEST(ThrowsOnUnwrappedMetric) { + + NProto::TMultiSamplesList samples; + auto encoder = EncoderProtobuf(&samples); + + UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); + } + + Y_UNIT_TEST(ThrowsOnUnwrappedMetric) { constexpr auto input = TStringBuf(R"(["something_axxx", 42])"); - - NProto::TMultiSamplesList samples; - auto encoder = EncoderProtobuf(&samples); - - UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); - } - - Y_UNIT_TEST(HistogramMetric) { + + NProto::TMultiSamplesList samples; + auto encoder = EncoderProtobuf(&samples); + + UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); + } + + Y_UNIT_TEST(HistogramMetric) { constexpr auto input = TStringBuf(R"([["something_hgram", [[0, 1], [200, 2], [500, 3]] ]])"); - - NProto::TMultiSamplesList samples; - auto encoder = EncoderProtobuf(&samples); - - DecodeUnistat(input, encoder.Get()); - - auto sample = samples.GetSamples(0); + + NProto::TMultiSamplesList samples; + auto encoder = EncoderProtobuf(&samples); + + DecodeUnistat(input, encoder.Get()); + + auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HIST_RATE); - UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); - UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); - - auto label = sample.GetLabels(0); - const auto point = sample.GetPoints(0); - const auto histogram = point.GetHistogram(); - const auto size = histogram.BoundsSize(); - UNIT_ASSERT_VALUES_EQUAL(size, 4); - - const TVector<double> expectedBounds {0, 200, 500, std::numeric_limits<double>::max()}; - const TVector<ui64> expectedValues {0, 1, 2, 3}; - - for (auto i = 0; i < 4; ++i) { - UNIT_ASSERT_VALUES_EQUAL(histogram.GetBounds(i), expectedBounds[i]); - UNIT_ASSERT_VALUES_EQUAL(histogram.GetValues(i), expectedValues[i]); - } - - UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); - UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_hgram"); - } - - Y_UNIT_TEST(AbsoluteHistogram) { + UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); + + auto label = sample.GetLabels(0); + const auto point = sample.GetPoints(0); + const auto histogram = point.GetHistogram(); + const auto size = histogram.BoundsSize(); + UNIT_ASSERT_VALUES_EQUAL(size, 4); + + const TVector<double> expectedBounds {0, 200, 500, std::numeric_limits<double>::max()}; + const TVector<ui64> expectedValues {0, 1, 2, 3}; + + for (auto i = 0; i < 4; ++i) { + UNIT_ASSERT_VALUES_EQUAL(histogram.GetBounds(i), expectedBounds[i]); + UNIT_ASSERT_VALUES_EQUAL(histogram.GetValues(i), expectedValues[i]); + } + + UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); + UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_hgram"); + } + + Y_UNIT_TEST(AbsoluteHistogram) { constexpr auto input = TStringBuf(R"([["something_ahhh", [[0, 1], [200, 2], [500, 3]] ]])"); - - NProto::TMultiSamplesList samples; - auto encoder = EncoderProtobuf(&samples); - - DecodeUnistat(input, encoder.Get()); - - auto sample = samples.GetSamples(0); + + NProto::TMultiSamplesList samples; + auto encoder = EncoderProtobuf(&samples); + + DecodeUnistat(input, encoder.Get()); + + auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HISTOGRAM); - UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); - UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); - } - + UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); + } + Y_UNIT_TEST(AllowedMetricNames) { NProto::TMultiSamplesList samples; auto encoder = EncoderProtobuf(&samples); @@ -129,95 +129,95 @@ Y_UNIT_TEST_SUITE(TUnistatDecoderTest) { } } - Y_UNIT_TEST(DisallowedMetricNames) { - NProto::TMultiSamplesList samples; - auto encoder = EncoderProtobuf(&samples); - - { + Y_UNIT_TEST(DisallowedMetricNames) { + NProto::TMultiSamplesList samples; + auto encoder = EncoderProtobuf(&samples); + + { constexpr auto input = TStringBuf(R"([["someth!ng_ahhh", [[0, 1], [200, 2], [500, 3]] ]])"); - UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); - } - - { + UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); + } + + { constexpr auto input = TStringBuf(R"([["foo_a", [[0, 1], [200, 2], [500, 3]] ]])"); - UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); - } - - { + UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); + } + + { constexpr auto input = TStringBuf(R"([["foo_ahhh;tag=value", [[0, 1], [200, 2], [500, 3]] ]])"); - UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); - } - } - - Y_UNIT_TEST(MultipleMetrics) { + UNIT_ASSERT_EXCEPTION(DecodeUnistat(input, encoder.Get()), yexception); + } + } + + Y_UNIT_TEST(MultipleMetrics) { constexpr auto input = TStringBuf(R"([["something_axxx", 42], ["some-other_dhhh", 53]])"); - - NProto::TMultiSamplesList samples; - auto encoder = EncoderProtobuf(&samples); - - DecodeUnistat(input, encoder.Get()); - - UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 2); - auto sample = samples.GetSamples(0); + + NProto::TMultiSamplesList samples; + auto encoder = EncoderProtobuf(&samples); + + DecodeUnistat(input, encoder.Get()); + + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 2); + auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); - UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); - - auto label = sample.GetLabels(0); - auto point = sample.GetPoints(0); - UNIT_ASSERT_VALUES_EQUAL(point.GetFloat64(), 42.); - UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); - UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_axxx"); - - sample = samples.GetSamples(1); + UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); + + auto label = sample.GetLabels(0); + auto point = sample.GetPoints(0); + UNIT_ASSERT_VALUES_EQUAL(point.GetFloat64(), 42.); + UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); + UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_axxx"); + + sample = samples.GetSamples(1); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::RATE); - UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); - UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); - - label = sample.GetLabels(0); - point = sample.GetPoints(0); - UNIT_ASSERT_VALUES_EQUAL(point.GetUint64(), 53); - UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); - UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "some-other_dhhh"); - } - - Y_UNIT_TEST(UnderscoreName) { + UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); + + label = sample.GetLabels(0); + point = sample.GetPoints(0); + UNIT_ASSERT_VALUES_EQUAL(point.GetUint64(), 53); + UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); + UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "some-other_dhhh"); + } + + Y_UNIT_TEST(UnderscoreName) { constexpr auto input = TStringBuf(R"([["something_anything_dmmm", 42]])"); - - NProto::TMultiSamplesList samples; - auto encoder = EncoderProtobuf(&samples); - DecodeUnistat(input, encoder.Get()); - - UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); - auto sample = samples.GetSamples(0); + + NProto::TMultiSamplesList samples; + auto encoder = EncoderProtobuf(&samples); + DecodeUnistat(input, encoder.Get()); + + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); + auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::RATE); - UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); - UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); - - auto label = sample.GetLabels(0); - auto point = sample.GetPoints(0); - UNIT_ASSERT_VALUES_EQUAL(point.GetUint64(), 42); - UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); - UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_anything_dmmm"); - } - - Y_UNIT_TEST(MaxAggr) { + UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); + + auto label = sample.GetLabels(0); + auto point = sample.GetPoints(0); + UNIT_ASSERT_VALUES_EQUAL(point.GetUint64(), 42); + UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); + UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_anything_dmmm"); + } + + Y_UNIT_TEST(MaxAggr) { constexpr auto input = TStringBuf(R"([["something_anything_max", 42]])"); - - NProto::TMultiSamplesList samples; - auto encoder = EncoderProtobuf(&samples); - DecodeUnistat(input, encoder.Get()); - - UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); - auto sample = samples.GetSamples(0); + + NProto::TMultiSamplesList samples; + auto encoder = EncoderProtobuf(&samples); + DecodeUnistat(input, encoder.Get()); + + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); + auto sample = samples.GetSamples(0); UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); - UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); - - auto label = sample.GetLabels(0); - auto point = sample.GetPoints(0); - UNIT_ASSERT_VALUES_EQUAL(point.GetFloat64(), 42.); - UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); - UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_anything_max"); - } -} + UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); + UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); + + auto label = sample.GetLabels(0); + auto point = sample.GetPoints(0); + UNIT_ASSERT_VALUES_EQUAL(point.GetFloat64(), 42.); + UNIT_ASSERT_VALUES_EQUAL(label.GetName(), "sensor"); + UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_anything_max"); + } +} diff --git a/library/cpp/monlib/encode/unistat/ut/ya.make b/library/cpp/monlib/encode/unistat/ut/ya.make index 4beba988637..a652139f45f 100644 --- a/library/cpp/monlib/encode/unistat/ut/ya.make +++ b/library/cpp/monlib/encode/unistat/ut/ya.make @@ -1,16 +1,16 @@ UNITTEST_FOR(library/cpp/monlib/encode/unistat) - -OWNER( - msherbakov - g:solomon -) - -SRCS( - unistat_ut.cpp -) - -PEERDIR( + +OWNER( + msherbakov + g:solomon +) + +SRCS( + unistat_ut.cpp +) + +PEERDIR( library/cpp/monlib/encode/protobuf -) - -END() +) + +END() diff --git a/library/cpp/monlib/encode/unistat/ya.make b/library/cpp/monlib/encode/unistat/ya.make index c6ec66ca400..4ac2edadf40 100644 --- a/library/cpp/monlib/encode/unistat/ya.make +++ b/library/cpp/monlib/encode/unistat/ya.make @@ -1,18 +1,18 @@ -LIBRARY() - -OWNER( - msherbakov - g:solomon -) - -PEERDIR( - contrib/libs/re2 +LIBRARY() + +OWNER( + msherbakov + g:solomon +) + +PEERDIR( + contrib/libs/re2 library/cpp/json library/cpp/monlib/metrics -) - -SRCS( - unistat_decoder.cpp -) - -END() +) + +SRCS( + unistat_decoder.cpp +) + +END() |