Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDK] Support empty histogram buckets #3027

Merged
merged 6 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions sdk/src/metrics/aggregation/histogram_aggregation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace metrics
LongHistogramAggregation::LongHistogramAggregation(const AggregationConfig *aggregation_config)
{
auto ac = static_cast<const HistogramAggregationConfig *>(aggregation_config);
if (ac && ac->boundaries_.size())
if (ac)
{
point_data_.boundaries_ = ac->boundaries_;
}
Expand Down Expand Up @@ -109,7 +109,7 @@ PointType LongHistogramAggregation::ToPoint() const noexcept
DoubleHistogramAggregation::DoubleHistogramAggregation(const AggregationConfig *aggregation_config)
{
auto ac = static_cast<const HistogramAggregationConfig *>(aggregation_config);
if (ac && ac->boundaries_.size())
if (ac)
{
point_data_.boundaries_ = ac->boundaries_;
}
Expand Down
120 changes: 120 additions & 0 deletions sdk/test/metrics/histogram_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,66 @@ TEST(Histogram, DoubleCustomBuckets)
ASSERT_EQ(std::vector<double>({10, 20, 30, 40}), actual.boundaries_);
ASSERT_EQ(std::vector<uint64_t>({2, 2, 2, 2, 2}), actual.counts_);
}

TEST(Histogram, DoubleEmptyBuckets)
{
MeterProvider mp;
auto m = mp.GetMeter("meter1", "version1", "schema1");
std::string instrument_unit = "ms";
std::string instrument_name = "historgram1";
std::string instrument_desc = "histogram metrics";

std::unique_ptr<MockMetricExporter> exporter(new MockMetricExporter());
std::shared_ptr<MetricReader> reader{new MockMetricReader(std::move(exporter))};
mp.AddMetricReader(reader);

std::shared_ptr<HistogramAggregationConfig> config(new HistogramAggregationConfig());
config->boundaries_ = {};
std::unique_ptr<View> view{
new View("view1", "view1_description", instrument_unit, AggregationType::kHistogram, config)};
std::unique_ptr<InstrumentSelector> instrument_selector{
new InstrumentSelector(InstrumentType::kHistogram, instrument_name, instrument_unit)};
std::unique_ptr<MeterSelector> meter_selector{new MeterSelector("meter1", "version1", "schema1")};
mp.AddView(std::move(instrument_selector), std::move(meter_selector), std::move(view));

auto h = m->CreateDoubleHistogram(instrument_name, instrument_desc, instrument_unit);

h->Record(-5, {});
h->Record(10, {});
h->Record(15, {});
h->Record(20, {});
h->Record(25, {});
h->Record(30, {});
h->Record(35, {});
h->Record(40, {});
h->Record(45, {});
h->Record(50, {});

std::vector<HistogramPointData> actuals;
reader->Collect([&](ResourceMetrics &rm) {
for (const ScopeMetrics &smd : rm.scope_metric_data_)
{
for (const MetricData &md : smd.metric_data_)
{
for (const PointDataAttributes &dp : md.point_data_attr_)
{
actuals.push_back(opentelemetry::nostd::get<HistogramPointData>(dp.point_data));
}
}
}
return true;
});

ASSERT_EQ(1, actuals.size());

const auto &actual = actuals.at(0);
ASSERT_EQ(270.0, opentelemetry::nostd::get<double>(actual.sum_));
ASSERT_EQ(9, actual.count_);
ASSERT_EQ(10.0, opentelemetry::nostd::get<double>(actual.min_));
ASSERT_EQ(50.0, opentelemetry::nostd::get<double>(actual.max_));
ASSERT_EQ(std::vector<double>({}), actual.boundaries_);
ASSERT_EQ(std::vector<uint64_t>({9}), actual.counts_);
}
#endif

TEST(Histogram, UInt64)
Expand Down Expand Up @@ -249,4 +309,64 @@ TEST(Histogram, UInt64CustomBuckets)
ASSERT_EQ(std::vector<double>({10, 20, 30, 40}), actual.boundaries_);
ASSERT_EQ(std::vector<uint64_t>({2, 2, 2, 2, 2}), actual.counts_);
}

TEST(Histogram, UInt64EmptyBuckets)
{
MeterProvider mp;
auto m = mp.GetMeter("meter1", "version1", "schema1");
std::string instrument_name = "historgram1";
std::string instrument_desc = "histogram metrics";
std::string instrument_unit = "ms";

std::unique_ptr<MockMetricExporter> exporter(new MockMetricExporter());
std::shared_ptr<MetricReader> reader{new MockMetricReader(std::move(exporter))};
mp.AddMetricReader(reader);

std::shared_ptr<HistogramAggregationConfig> config(new HistogramAggregationConfig());
config->boundaries_ = {};
std::unique_ptr<View> view{
new View("view1", "view1_description", "ms", AggregationType::kHistogram, config)};
std::unique_ptr<InstrumentSelector> instrument_selector{
new InstrumentSelector(InstrumentType::kHistogram, instrument_name, instrument_unit)};
std::unique_ptr<MeterSelector> meter_selector{new MeterSelector("meter1", "version1", "schema1")};
mp.AddView(std::move(instrument_selector), std::move(meter_selector), std::move(view));

auto h = m->CreateUInt64Histogram(instrument_name, instrument_desc, instrument_unit);

h->Record(5, {});
h->Record(10, {});
h->Record(15, {});
h->Record(20, {});
h->Record(25, {});
h->Record(30, {});
h->Record(35, {});
h->Record(40, {});
h->Record(45, {});
h->Record(50, {});

std::vector<HistogramPointData> actuals;
reader->Collect([&](ResourceMetrics &rm) {
for (const ScopeMetrics &smd : rm.scope_metric_data_)
{
for (const MetricData &md : smd.metric_data_)
{
for (const PointDataAttributes &dp : md.point_data_attr_)
{
actuals.push_back(opentelemetry::nostd::get<HistogramPointData>(dp.point_data));
}
}
}
return true;
});

ASSERT_EQ(1, actuals.size());

const auto &actual = actuals.at(0);
ASSERT_EQ(275, opentelemetry::nostd::get<int64_t>(actual.sum_));
ASSERT_EQ(10, actual.count_);
ASSERT_EQ(5, opentelemetry::nostd::get<int64_t>(actual.min_));
ASSERT_EQ(50, opentelemetry::nostd::get<int64_t>(actual.max_));
ASSERT_EQ(std::vector<double>({}), actual.boundaries_);
ASSERT_EQ(std::vector<uint64_t>({10}), actual.counts_);
}
#endif
Loading