Added start/end date params on ceilometer queries

In this changeset, I added the start_time and end_time params
to the Ceilometer helper which can drastically reduce the execution
time of the queries.

Change-Id: I39cb3eef584acfca1b50ff6ec1b65f38750802d2
This commit is contained in:
Vincent Françoise
2016-08-22 10:12:37 +02:00
committed by David TARDIVEL
parent 5f205d5602
commit c61793811e
2 changed files with 47 additions and 12 deletions

View File

@@ -15,11 +15,15 @@
# implied. # implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
#
import datetime
from ceilometerclient import exc from ceilometerclient import exc
from oslo_utils import timeutils
from watcher._i18n import _
from watcher.common import clients from watcher.common import clients
from watcher.common import exception
class CeilometerHelper(object): class CeilometerHelper(object):
@@ -29,18 +33,20 @@ class CeilometerHelper(object):
self.ceilometer = self.osc.ceilometer() self.ceilometer = self.osc.ceilometer()
def build_query(self, user_id=None, tenant_id=None, resource_id=None, def build_query(self, user_id=None, tenant_id=None, resource_id=None,
user_ids=None, tenant_ids=None, resource_ids=None): user_ids=None, tenant_ids=None, resource_ids=None,
start_time=None, end_time=None):
"""Returns query built from given parameters. """Returns query built from given parameters.
This query can be then used for querying resources, meters and This query can be then used for querying resources, meters and
statistics. statistics.
:Parameters: :param user_id: user_id, has a priority over list of ids
- `user_id`: user_id, has a priority over list of ids :param tenant_id: tenant_id, has a priority over list of ids
- `tenant_id`: tenant_id, has a priority over list of ids :param resource_id: resource_id, has a priority over list of ids
- `resource_id`: resource_id, has a priority over list of ids :param user_ids: list of user_ids
- `user_ids`: list of user_ids :param tenant_ids: list of tenant_ids
- `tenant_ids`: list of tenant_ids :param resource_ids: list of resource_ids
- `resource_ids`: list of resource_ids :param start_time: datetime from which measurements should be collected
:param end_time: datetime until which measurements should be collected
""" """
user_ids = user_ids or [] user_ids = user_ids or []
@@ -63,6 +69,32 @@ class CeilometerHelper(object):
for r_id in resource_ids: for r_id in resource_ids:
query.append({"field": "resource_id", "op": "eq", "value": r_id}) query.append({"field": "resource_id", "op": "eq", "value": r_id})
start_timestamp = None
end_timestamp = None
if start_time:
start_timestamp = start_time
if isinstance(start_time, datetime.datetime):
start_timestamp = start_time.isoformat()
if end_time:
end_timestamp = end_time
if isinstance(end_time, datetime.datetime):
end_timestamp = end_time.isoformat()
if (start_timestamp and end_timestamp and
timeutils.parse_isotime(start_timestamp) >
timeutils.parse_isotime(end_timestamp)):
raise exception.Invalid(
_("Invalid query: %(start_time)s > %(end_time)s") % dict(
start_time=start_timestamp, end_time=end_timestamp))
if start_timestamp:
query.append({"field": "timestamp", "op": "ge",
"value": start_timestamp})
if end_timestamp:
query.append({"field": "timestamp", "op": "le",
"value": end_timestamp})
return query return query
def query_retry(self, f, *args, **kargs): def query_retry(self, f, *args, **kargs):
@@ -112,7 +144,10 @@ class CeilometerHelper(object):
:return: :return:
""" """
query = self.build_query(resource_id=resource_id) start_time = (datetime.datetime.utcnow() -
datetime.timedelta(seconds=int(period)))
query = self.build_query(
resource_id=resource_id, start_time=start_time)
statistic = self.query_retry(f=self.ceilometer.statistics.list, statistic = self.query_retry(f=self.ceilometer.statistics.list,
meter_name=meter_name, meter_name=meter_name,
q=query, q=query,

View File

@@ -105,12 +105,12 @@ class WatcherException(Exception):
def __str__(self): def __str__(self):
"""Encode to utf-8 then wsme api can consume it as well""" """Encode to utf-8 then wsme api can consume it as well"""
if not six.PY3: if not six.PY3:
return unicode(self.args[0]).encode('utf-8') return six.text_type(self.args[0]).encode('utf-8')
else: else:
return self.args[0] return self.args[0]
def __unicode__(self): def __unicode__(self):
return unicode(self.args[0]) return six.text_type(self.args[0])
def format_message(self): def format_message(self):
if self.__class__.__name__.endswith('_Remote'): if self.__class__.__name__.endswith('_Remote'):