Skip to content

Commit 1203bcf

Browse files
authored
[SDK] Support empty histogram buckets (#3027)
* support empty buckets * Update histogram_test.cc * Update histogram_test.cc * test for negative values * fix count
1 parent 9e062b5 commit 1203bcf

File tree

2 files changed

+122
-2
lines changed

2 files changed

+122
-2
lines changed

sdk/src/metrics/aggregation/histogram_aggregation.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace metrics
2828
LongHistogramAggregation::LongHistogramAggregation(const AggregationConfig *aggregation_config)
2929
{
3030
auto ac = static_cast<const HistogramAggregationConfig *>(aggregation_config);
31-
if (ac && ac->boundaries_.size())
31+
if (ac)
3232
{
3333
point_data_.boundaries_ = ac->boundaries_;
3434
}
@@ -109,7 +109,7 @@ PointType LongHistogramAggregation::ToPoint() const noexcept
109109
DoubleHistogramAggregation::DoubleHistogramAggregation(const AggregationConfig *aggregation_config)
110110
{
111111
auto ac = static_cast<const HistogramAggregationConfig *>(aggregation_config);
112-
if (ac && ac->boundaries_.size())
112+
if (ac)
113113
{
114114
point_data_.boundaries_ = ac->boundaries_;
115115
}

sdk/test/metrics/histogram_test.cc

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,66 @@ TEST(Histogram, DoubleCustomBuckets)
134134
ASSERT_EQ(std::vector<double>({10, 20, 30, 40}), actual.boundaries_);
135135
ASSERT_EQ(std::vector<uint64_t>({2, 2, 2, 2, 2}), actual.counts_);
136136
}
137+
138+
TEST(Histogram, DoubleEmptyBuckets)
139+
{
140+
MeterProvider mp;
141+
auto m = mp.GetMeter("meter1", "version1", "schema1");
142+
std::string instrument_unit = "ms";
143+
std::string instrument_name = "historgram1";
144+
std::string instrument_desc = "histogram metrics";
145+
146+
std::unique_ptr<MockMetricExporter> exporter(new MockMetricExporter());
147+
std::shared_ptr<MetricReader> reader{new MockMetricReader(std::move(exporter))};
148+
mp.AddMetricReader(reader);
149+
150+
std::shared_ptr<HistogramAggregationConfig> config(new HistogramAggregationConfig());
151+
config->boundaries_ = {};
152+
std::unique_ptr<View> view{
153+
new View("view1", "view1_description", instrument_unit, AggregationType::kHistogram, config)};
154+
std::unique_ptr<InstrumentSelector> instrument_selector{
155+
new InstrumentSelector(InstrumentType::kHistogram, instrument_name, instrument_unit)};
156+
std::unique_ptr<MeterSelector> meter_selector{new MeterSelector("meter1", "version1", "schema1")};
157+
mp.AddView(std::move(instrument_selector), std::move(meter_selector), std::move(view));
158+
159+
auto h = m->CreateDoubleHistogram(instrument_name, instrument_desc, instrument_unit);
160+
161+
h->Record(-5, {});
162+
h->Record(10, {});
163+
h->Record(15, {});
164+
h->Record(20, {});
165+
h->Record(25, {});
166+
h->Record(30, {});
167+
h->Record(35, {});
168+
h->Record(40, {});
169+
h->Record(45, {});
170+
h->Record(50, {});
171+
172+
std::vector<HistogramPointData> actuals;
173+
reader->Collect([&](ResourceMetrics &rm) {
174+
for (const ScopeMetrics &smd : rm.scope_metric_data_)
175+
{
176+
for (const MetricData &md : smd.metric_data_)
177+
{
178+
for (const PointDataAttributes &dp : md.point_data_attr_)
179+
{
180+
actuals.push_back(opentelemetry::nostd::get<HistogramPointData>(dp.point_data));
181+
}
182+
}
183+
}
184+
return true;
185+
});
186+
187+
ASSERT_EQ(1, actuals.size());
188+
189+
const auto &actual = actuals.at(0);
190+
ASSERT_EQ(270.0, opentelemetry::nostd::get<double>(actual.sum_));
191+
ASSERT_EQ(9, actual.count_);
192+
ASSERT_EQ(10.0, opentelemetry::nostd::get<double>(actual.min_));
193+
ASSERT_EQ(50.0, opentelemetry::nostd::get<double>(actual.max_));
194+
ASSERT_EQ(std::vector<double>({}), actual.boundaries_);
195+
ASSERT_EQ(std::vector<uint64_t>({9}), actual.counts_);
196+
}
137197
#endif
138198

139199
TEST(Histogram, UInt64)
@@ -249,4 +309,64 @@ TEST(Histogram, UInt64CustomBuckets)
249309
ASSERT_EQ(std::vector<double>({10, 20, 30, 40}), actual.boundaries_);
250310
ASSERT_EQ(std::vector<uint64_t>({2, 2, 2, 2, 2}), actual.counts_);
251311
}
312+
313+
TEST(Histogram, UInt64EmptyBuckets)
314+
{
315+
MeterProvider mp;
316+
auto m = mp.GetMeter("meter1", "version1", "schema1");
317+
std::string instrument_name = "historgram1";
318+
std::string instrument_desc = "histogram metrics";
319+
std::string instrument_unit = "ms";
320+
321+
std::unique_ptr<MockMetricExporter> exporter(new MockMetricExporter());
322+
std::shared_ptr<MetricReader> reader{new MockMetricReader(std::move(exporter))};
323+
mp.AddMetricReader(reader);
324+
325+
std::shared_ptr<HistogramAggregationConfig> config(new HistogramAggregationConfig());
326+
config->boundaries_ = {};
327+
std::unique_ptr<View> view{
328+
new View("view1", "view1_description", "ms", AggregationType::kHistogram, config)};
329+
std::unique_ptr<InstrumentSelector> instrument_selector{
330+
new InstrumentSelector(InstrumentType::kHistogram, instrument_name, instrument_unit)};
331+
std::unique_ptr<MeterSelector> meter_selector{new MeterSelector("meter1", "version1", "schema1")};
332+
mp.AddView(std::move(instrument_selector), std::move(meter_selector), std::move(view));
333+
334+
auto h = m->CreateUInt64Histogram(instrument_name, instrument_desc, instrument_unit);
335+
336+
h->Record(5, {});
337+
h->Record(10, {});
338+
h->Record(15, {});
339+
h->Record(20, {});
340+
h->Record(25, {});
341+
h->Record(30, {});
342+
h->Record(35, {});
343+
h->Record(40, {});
344+
h->Record(45, {});
345+
h->Record(50, {});
346+
347+
std::vector<HistogramPointData> actuals;
348+
reader->Collect([&](ResourceMetrics &rm) {
349+
for (const ScopeMetrics &smd : rm.scope_metric_data_)
350+
{
351+
for (const MetricData &md : smd.metric_data_)
352+
{
353+
for (const PointDataAttributes &dp : md.point_data_attr_)
354+
{
355+
actuals.push_back(opentelemetry::nostd::get<HistogramPointData>(dp.point_data));
356+
}
357+
}
358+
}
359+
return true;
360+
});
361+
362+
ASSERT_EQ(1, actuals.size());
363+
364+
const auto &actual = actuals.at(0);
365+
ASSERT_EQ(275, opentelemetry::nostd::get<int64_t>(actual.sum_));
366+
ASSERT_EQ(10, actual.count_);
367+
ASSERT_EQ(5, opentelemetry::nostd::get<int64_t>(actual.min_));
368+
ASSERT_EQ(50, opentelemetry::nostd::get<int64_t>(actual.max_));
369+
ASSERT_EQ(std::vector<double>({}), actual.boundaries_);
370+
ASSERT_EQ(std::vector<uint64_t>({10}), actual.counts_);
371+
}
252372
#endif

0 commit comments

Comments
 (0)