Merge "gnocchi: move to jsonpath_rw_ext"

This commit is contained in:
Jenkins 2015-08-26 17:13:52 +00:00 committed by Gerrit Code Review
commit c18d69a800
2 changed files with 51 additions and 46 deletions

View File

@ -16,12 +16,13 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import fnmatch import fnmatch
import functools
import itertools import itertools
import operator import operator
import os import os
import threading import threading
import jsonpath_rw from jsonpath_rw_ext import parser
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log from oslo_log import log
import six import six
@ -102,12 +103,44 @@ class ResourcesDefinition(object):
MANDATORY_FIELDS = {'resource_type': six.string_types, MANDATORY_FIELDS = {'resource_type': six.string_types,
'metrics': list} 'metrics': list}
JSONPATH_RW_PARSER = parser.ExtentedJsonPathParser()
def __init__(self, definition_cfg, default_archive_policy, def __init__(self, definition_cfg, default_archive_policy,
legacy_archive_policy_defintion): legacy_archive_policy_defintion):
self._default_archive_policy = default_archive_policy self._default_archive_policy = default_archive_policy
self._legacy_archive_policy_defintion = legacy_archive_policy_defintion self._legacy_archive_policy_defintion = legacy_archive_policy_defintion
self.cfg = definition_cfg self.cfg = definition_cfg
self._validate()
for field, field_type in self.MANDATORY_FIELDS.items():
if field not in self.cfg:
raise ResourcesDefinitionException(
_LE("Required field %s not specified") % field, self.cfg)
if not isinstance(self.cfg[field], field_type):
raise ResourcesDefinitionException(
_LE("Required field %(field)s should be a %(type)s") %
{'field': field, 'type': field_type}, self.cfg)
self._field_getter = {}
for name, fval in self.cfg.get('attributes', {}).items():
if isinstance(fval, six.integer_types):
self._field_getter[name] = fval
else:
try:
parts = self.JSONPATH_RW_PARSER.parse(fval)
except Exception as e:
raise ResourcesDefinitionException(
_LE("Parse error in JSONPath specification "
"'%(jsonpath)s': %(err)s")
% dict(jsonpath=fval, err=e), self.cfg)
self._field_getter[name] = functools.partial(
self._parse_jsonpath_field, parts)
@staticmethod
def _parse_jsonpath_field(parts, sample):
values = [match.value for match in parts.find(sample)
if match.value is not None]
if values:
return values[0]
def match(self, metric_name): def match(self, metric_name):
for t in self.cfg['metrics']: for t in self.cfg['metrics']:
@ -117,11 +150,13 @@ class ResourcesDefinition(object):
def attributes(self, sample): def attributes(self, sample):
attrs = {} attrs = {}
for attribute_info in self.cfg.get('attributes', []): for attr, getter in self._field_getter.items():
for attr, field in attribute_info.items(): if callable(getter):
value = self._parse_field(field, sample) value = getter(sample)
if value is not None: else:
attrs[attr] = value value = getter
if value is not None:
attrs[attr] = value
return attrs return attrs
def metrics(self): def metrics(self):
@ -134,35 +169,6 @@ class ResourcesDefinition(object):
self._default_archive_policy) self._default_archive_policy)
return metrics return metrics
def _parse_field(self, field, sample):
# TODO(sileht): share this with
# https://review.openstack.org/#/c/197633/
if not field:
return
if isinstance(field, six.integer_types):
return field
try:
parts = jsonpath_rw.parse(field)
except Exception as e:
raise ResourcesDefinitionException(
_LE("Parse error in JSONPath specification "
"'%(jsonpath)s': %(err)s")
% dict(jsonpath=field, err=e), self.cfg)
values = [match.value for match in parts.find(sample)
if match.value is not None]
if values:
return values[0]
def _validate(self):
for field, field_type in self.MANDATORY_FIELDS.items():
if field not in self.cfg:
raise ResourcesDefinitionException(
_LE("Required field %s not specified") % field, self.cfg)
if not isinstance(self.cfg[field], field_type):
raise ResourcesDefinitionException(
_LE("Required field %(field)s should be a %(type)s") %
{'field': field, 'type': field_type}, self.cfg)
class GnocchiDispatcher(dispatcher.Base): class GnocchiDispatcher(dispatcher.Base):
def __init__(self, conf): def __init__(self, conf):

View File

@ -80,12 +80,11 @@ resources:
- 'network.outgoing.bytes' - 'network.outgoing.bytes'
- 'network.incoming.bytes' - 'network.incoming.bytes'
attributes: attributes:
- host: resource_metadata.host host: resource_metadata.host
- image_ref: resource_metadata.image_ref_url image_ref: resource_metadata.image_ref_url
- display_name: resource_metadata.display_name display_name: resource_metadata.display_name
- flavor_id: resource_metadata.instance_flavor_id flavor_id: resource_metadata.(instance_flavor_id|(flavor.id))
- flavor_id: resource_metadata.flavor.id server_group: resource_metadata.user_metadata.server_group
- server_group: resource_metadata.user_metadata.server_group
- resource_type: image - resource_type: image
metrics: metrics:
@ -94,9 +93,9 @@ resources:
- 'image.download' - 'image.download'
- 'image.serve' - 'image.serve'
attributes: attributes:
- name: resource_metadata.name name: resource_metadata.name
- container_format: resource_metadata.container_format container_format: resource_metadata.container_format
- disk_format: resource_metadata.disk_format disk_format: resource_metadata.disk_format
- resource_type: ipmi - resource_type: ipmi
metrics: metrics:
@ -162,4 +161,4 @@ resources:
- 'volume.attach' - 'volume.attach'
- 'volume.detach' - 'volume.detach'
attributes: attributes:
- display_name: resource_metadata.display_name display_name: resource_metadata.display_name