storage: allow to specify regaggregation over aggregation retrieval

Currently, when retrieving e.g. 'mean' aggregation of several metrics,
the aggregation of those metrics is always done using 'mean'.
This patches allows to specify a reaggregation methods, which applies on
top of the measures retrieved.

You can know retrieve e.g. the 'max' of the 'mean' of several metrics.

Related-Bug: #1573023
Change-Id: I9ea60de498e6f81c738a7236a392019b47b0c269
This commit is contained in:
Julien Danjou 2016-08-02 15:16:56 +02:00
parent 94d773b0d5
commit c13a21a8ae
4 changed files with 20 additions and 2 deletions

View File

@ -483,6 +483,7 @@ class AggregatedMetricController(rest.RestController):
else:
measures = pecan.request.storage.get_cross_metric_measures(
metrics, start, stop, aggregation,
None,
granularity,
needed_overlap)
# Replace timestamp keys by their string versions

View File

@ -267,6 +267,7 @@ class StorageDriver(object):
@staticmethod
def get_cross_metric_measures(metrics, from_timestamp=None,
to_timestamp=None, aggregation='mean',
reaggregation=None,
granularity=None,
needed_overlap=None):
"""Get aggregated measures of multiple entities.
@ -276,6 +277,8 @@ class StorageDriver(object):
:param to timestamp: The timestamp to get the measure to.
:param granularity: The granularity to retrieve.
:param aggregation: The type of aggregation to retrieve.
:param reaggregation: The type of aggregation to compute
on the retrieved measures.
"""
for metric in metrics:
if aggregation not in metric.archive_policy.aggregation_methods:

View File

@ -418,11 +418,15 @@ class CarbonaraBasedStorage(storage.StorageDriver):
def get_cross_metric_measures(self, metrics, from_timestamp=None,
to_timestamp=None, aggregation='mean',
reaggregation=None,
granularity=None,
needed_overlap=100.0):
super(CarbonaraBasedStorage, self).get_cross_metric_measures(
metrics, from_timestamp, to_timestamp,
aggregation, granularity, needed_overlap)
aggregation, reaggregation, granularity, needed_overlap)
if reaggregation is None:
reaggregation = aggregation
if granularity is None:
granularities = (
@ -452,7 +456,7 @@ class CarbonaraBasedStorage(storage.StorageDriver):
return [(timestamp.replace(tzinfo=iso8601.iso8601.UTC), r, v)
for timestamp, r, v
in carbonara.AggregatedTimeSerie.aggregated(
tss, aggregation, from_timestamp, to_timestamp,
tss, reaggregation, from_timestamp, to_timestamp,
needed_overlap)]
except carbonara.UnAggregableTimeseries as e:
raise storage.MetricUnaggregatable(metrics, e.reason)

View File

@ -425,6 +425,16 @@ class TestStorageDriver(tests_base.TestCase):
(utils.datetime_utc(2014, 1, 1, 12, 10, 0), 300.0, 24.0)
], values)
values = self.storage.get_cross_metric_measures([self.metric, metric2],
reaggregation='max')
self.assertEqual([
(utils.datetime_utc(2014, 1, 1, 0, 0, 0), 86400.0, 39.75),
(utils.datetime_utc(2014, 1, 1, 12, 0, 0), 3600.0, 39.75),
(utils.datetime_utc(2014, 1, 1, 12, 0, 0), 300.0, 69),
(utils.datetime_utc(2014, 1, 1, 12, 5, 0), 300.0, 23),
(utils.datetime_utc(2014, 1, 1, 12, 10, 0), 300.0, 44)
], values)
values = self.storage.get_cross_metric_measures(
[self.metric, metric2],
from_timestamp=utils.to_timestamp('2014-01-01 12:10:00'))