Merge "gnocchi: move to jsonpath_rw_ext"
This commit is contained in:
commit
c18d69a800
@ -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):
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user