diff --git a/ceilometer/api/controllers/v2.py b/ceilometer/api/controllers/v2.py index 8b50d78de..82cb4e727 100644 --- a/ceilometer/api/controllers/v2.py +++ b/ceilometer/api/controllers/v2.py @@ -364,6 +364,9 @@ class Statistics(_Base): """Computed statistics for a query. """ + unit = wtypes.text + "The unit type of the data set" + min = float "The minimum volume seen in the data" @@ -435,7 +438,8 @@ class Statistics(_Base): @classmethod def sample(cls): - return cls(min=1, + return cls(unit='GiB', + min=1, max=9, avg=4.5, sum=45, diff --git a/ceilometer/storage/impl_hbase.py b/ceilometer/storage/impl_hbase.py index 991edb07f..059828586 100644 --- a/ceilometer/storage/impl_hbase.py +++ b/ceilometer/storage/impl_hbase.py @@ -472,6 +472,7 @@ class Connection(base.Connection): """ vol = int(meter['f:counter_volume']) ts = timeutils.parse_strtime(meter['f:timestamp']) + stat.unit = meter['f:counter_unit'] stat.min = min(vol, stat.min or vol) stat.max = max(vol, stat.max) stat.sum = vol + (stat.sum or 0) @@ -541,7 +542,8 @@ class Connection(base.Connection): period_end = period_start + datetime.timedelta( 0, period) results.append( - models.Statistics(count=0, + models.Statistics(unit='', + count=0, min=0, max=0, avg=0, diff --git a/ceilometer/storage/impl_mongodb.py b/ceilometer/storage/impl_mongodb.py index 057a29997..439f5098a 100644 --- a/ceilometer/storage/impl_mongodb.py +++ b/ceilometer/storage/impl_mongodb.py @@ -175,7 +175,8 @@ class Connection(base.Connection): MAP_STATS = bson.code.Code(""" function () { - emit('statistics', { min : this.counter_volume, + emit('statistics', { unit: this.counter_unit, + min : this.counter_volume, max : this.counter_volume, sum : this.counter_volume, count : NumberInt(1), @@ -195,7 +196,8 @@ class Connection(base.Connection): - period_first) / period) * period); emit(period_start, - { min : this.counter_volume, + { unit: this.counter_unit, + min : this.counter_volume, max : this.counter_volume, sum : this.counter_volume, count : NumberInt(1), @@ -208,7 +210,8 @@ class Connection(base.Connection): REDUCE_STATS = bson.code.Code(""" function (key, values) { - var res = { min: values[0].min, + var res = { unit: values[0].unit, + min: values[0].min, max: values[0].max, count: values[0].count, sum: values[0].sum, diff --git a/ceilometer/storage/impl_sqlalchemy.py b/ceilometer/storage/impl_sqlalchemy.py index e44a2ae4d..1875990c6 100644 --- a/ceilometer/storage/impl_sqlalchemy.py +++ b/ceilometer/storage/impl_sqlalchemy.py @@ -434,6 +434,7 @@ class Connection(base.Connection): def _make_stats_query(sample_filter): session = sqlalchemy_session.get_session() query = session.query( + Meter.counter_unit.label('unit'), func.min(Meter.timestamp).label('tsmin'), func.max(Meter.timestamp).label('tsmax'), func.avg(Meter.counter_volume).label('avg'), @@ -450,6 +451,7 @@ class Connection(base.Connection): if result.tsmin is not None and result.tsmax is not None else None) return api_models.Statistics( + unit=result.unit, count=int(result.count), min=result.min, max=result.max, diff --git a/ceilometer/storage/models.py b/ceilometer/storage/models.py index 9c65c39ff..7d5c23ad9 100644 --- a/ceilometer/storage/models.py +++ b/ceilometer/storage/models.py @@ -209,12 +209,13 @@ class Sample(Model): class Statistics(Model): """Computed statistics based on a set of sample data. """ - def __init__(self, + def __init__(self, unit, min, max, avg, sum, count, period, period_start, period_end, duration, duration_start, duration_end): """Create a new statistics object. + :param unit: The unit type of the data set :param min: The smallest volume found :param max: The largest volume found :param avg: The average of all volumes found @@ -227,7 +228,7 @@ class Statistics(Model): :param duration_start: The earliest time for the matching samples :param duration_end: The latest time for the matching samples """ - Model.__init__(self, + Model.__init__(self, unit=unit, min=min, max=max, avg=avg, sum=sum, count=count, period=period, period_start=period_start, period_end=period_end, duration=duration, diff --git a/tests/api/v1/test_compute_duration_by_resource_scenarios.py b/tests/api/v1/test_compute_duration_by_resource_scenarios.py index 3656fc0d3..8b70b617b 100644 --- a/tests/api/v1/test_compute_duration_by_resource_scenarios.py +++ b/tests/api/v1/test_compute_duration_by_resource_scenarios.py @@ -57,6 +57,7 @@ class TestComputeDurationByResource(tests_api.TestBase, def _set_stats(self, start, end): def get_meter_statistics(event_filter): return models.Statistics( + unit='', min=0, max=0, avg=0, sum=0, count=0, period=None, period_start=None, diff --git a/tests/api/v2/test_compute_duration_by_resource_scenarios.py b/tests/api/v2/test_compute_duration_by_resource_scenarios.py index 736bfa1ab..1ad4e2b24 100644 --- a/tests/api/v2/test_compute_duration_by_resource_scenarios.py +++ b/tests/api/v2/test_compute_duration_by_resource_scenarios.py @@ -68,6 +68,7 @@ class TestComputeDurationByResource(FunctionalTest, duration = timeutils.delta_seconds(duration_start, duration_end) return [ models.Statistics( + unit='', min=0, max=0, avg=0, @@ -142,6 +143,7 @@ class TestComputeDurationByResource(FunctionalTest, def get_interval(ignore_self, event_filter, period): return [ models.Statistics( + unit=None, count=0, min=None, max=None, @@ -171,6 +173,7 @@ class TestComputeDurationByResource(FunctionalTest, def get_interval(ignore_self, event_filter, period): return [ models.Statistics( + unit=None, count=0, min=None, max=None, diff --git a/tests/storage/base.py b/tests/storage/base.py index a9ff5581d..f418c15b3 100644 --- a/tests/storage/base.py +++ b/tests/storage/base.py @@ -707,6 +707,7 @@ class StatisticsTest(DBTestBase): (datetime.datetime(2012, 9, 25, 12, 32) - datetime.datetime(2012, 9, 25, 10, 30)).seconds) assert results.count == 3 + assert results.unit == 'GiB' assert results.min == 8 assert results.max == 10 assert results.sum == 27 @@ -746,6 +747,7 @@ class StatisticsTest(DBTestBase): self.assertEqual(r.period_start, datetime.datetime(2012, 9, 25, 10, 28)) self.assertEqual(r.count, 2) + self.assertEqual(r.unit, 'GiB') self.assertEqual(r.avg, 8.5) self.assertEqual(r.min, 8) self.assertEqual(r.max, 9) @@ -814,6 +816,7 @@ class StatisticsTest(DBTestBase): self.assertEqual(r.period_start, datetime.datetime(2012, 9, 25, 10, 28)) self.assertEqual(r.count, 1) + self.assertEqual(r.unit, 'GiB') self.assertEqual(r.avg, 8) self.assertEqual(r.min, 8) self.assertEqual(r.max, 8) @@ -838,6 +841,7 @@ class StatisticsTest(DBTestBase): results = list(self.conn.get_meter_statistics(f))[0] self.assertEqual(results.duration, 0) assert results.count == 1 + assert results.unit == 'GiB' assert results.min == 6 assert results.max == 6 assert results.sum == 6 @@ -853,6 +857,7 @@ class StatisticsTest(DBTestBase): (datetime.datetime(2012, 9, 25, 12, 32) - datetime.datetime(2012, 9, 25, 10, 30)).seconds) assert results.count == 3 + assert results.unit == 'GiB' assert results.min == 5 assert results.max == 7 assert results.sum == 18