Skip to content
This repository was archived by the owner on Sep 17, 2025. It is now read-only.

Commit a711a17

Browse files
authored
Add stackdriver underflow bucket (#406)
1 parent ae419b6 commit a711a17

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

opencensus/stats/aggregation_data.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,14 @@ def __init__(self,
133133
bounds = []
134134
else:
135135
assert bounds == list(sorted(set(bounds)))
136+
assert all(bb > 0 for bb in bounds)
136137

137138
if counts_per_bucket is None:
138139
counts_per_bucket = [0 for ii in range(len(bounds) + 1)]
139140
else:
140141
assert all(cc >= 0 for cc in counts_per_bucket)
141142
assert len(counts_per_bucket) == len(bounds) + 1
142143

143-
assert bounds == sorted(bounds)
144-
assert all(bb > 0 for bb in bounds)
145-
146144
self._counts_per_bucket = counts_per_bucket
147145
self._bounds = bucket_boundaries.BucketBoundaries(
148146
boundaries=bounds).boundaries

opencensus/stats/exporters/stackdriver_exporter.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,14 @@ def create_time_series_list(self, v_data, option_resource_type,
219219
# point.value.distribution_value.range.min = agg_data.min
220220
# point.value.distribution_value.range.max = agg_data.max
221221
bounds = dist_value.bucket_options.explicit_buckets.bounds
222-
bounds.extend(list(map(float, agg_data.bounds)))
223-
224222
buckets = dist_value.bucket_counts
223+
224+
# Stackdriver expects a first bucket for samples in (-inf, 0),
225+
# but we record positive samples only, and our first bucket is
226+
# [0, first_bound).
227+
bounds.extend([0])
228+
buckets.extend([0])
229+
bounds.extend(list(map(float, agg_data.bounds)))
225230
buckets.extend(list(map(int, agg_data.counts_per_bucket)))
226231
else:
227232
convFloat, isFloat = as_float(tag_value[0])

tests/unit/stats/exporter/test_stackdriver_stats.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
from opencensus.__version__ import __version__
2121
from opencensus.stats import aggregation as aggregation_module
22+
from opencensus.stats import aggregation_data as aggregation_data_module
2223
from opencensus.stats import measure as measure_module
2324
from opencensus.stats import stats as stats_module
2425
from opencensus.stats import view as view_module
@@ -621,6 +622,43 @@ def test_create_timeseries_float_tagvalue(self, monitor_resource_mock):
621622
"custom.googleapis.com/opencensus/view-name2")
622623
self.assertIsNotNone(time_series)
623624

625+
def test_create_timeseries_from_distribution(self):
626+
"""Check for explicit 0-bound bucket for SD export."""
627+
628+
v_data = mock.Mock(spec=view_data_module.ViewData)
629+
v_data.view.name = "example.org/test_view"
630+
v_data.start_time = '2018-11-21T00:12:34.56Z'
631+
v_data.end_time = '2018-11-21T00:23:45.67Z'
632+
633+
# Aggregation over (10 * range(10)) for buckets [2, 4, 6, 8]
634+
dad = aggregation_data_module.DistributionAggregationData(
635+
mean_data=4.5,
636+
count_data=100,
637+
min_=0,
638+
max_=9,
639+
sum_of_sqd_deviations=825,
640+
counts_per_bucket=[20, 20, 20, 20, 20],
641+
bounds=[2, 4, 6, 8],
642+
exemplars={mock.Mock() for ii in range(5)}
643+
)
644+
v_data.tag_value_aggregation_data_map = ({'tag_key': dad})
645+
646+
exporter = stackdriver.StackdriverStatsExporter(
647+
options=mock.Mock(),
648+
client=mock.Mock(),
649+
)
650+
time_series = exporter.create_time_series_list(v_data, "", "")
651+
652+
self.assertEqual(len(time_series.points), 1)
653+
[point] = time_series.points
654+
dv = point.value.distribution_value
655+
self.assertEqual(100, dv.count)
656+
self.assertEqual(4.5, dv.mean)
657+
self.assertEqual(825.0, dv.sum_of_squared_deviation)
658+
self.assertEqual([0, 20, 20, 20, 20, 20], dv.bucket_counts)
659+
self.assertEqual([0, 2, 4, 6, 8],
660+
dv.bucket_options.explicit_buckets.bounds)
661+
624662
def test_create_metric_descriptor_count(self):
625663
client = mock.Mock()
626664
option = stackdriver.Options(

0 commit comments

Comments
 (0)