Add description option to a rating metric definition
There is the need to add human-readable description to the metric definition. This can then be used to create custom reports in the `summary` GET API. The value has to be stored in the backend as we do with the alt_name and unit of the metric as well. Depends-On: https://review.opendev.org/c/openstack/cloudkitty/+/861786 Change-Id: Icea8d00eaf3343e59f0f7b2234754f6abcb23258
This commit is contained in:
parent
8eb8c4931a
commit
3aa31f8719
@ -70,6 +70,8 @@ def MetricDict(value):
|
||||
CONF_BASE_SCHEMA = {Required('metrics'): MetricDict}
|
||||
|
||||
METRIC_BASE_SCHEMA = {
|
||||
# Human-readable description for the CloudKitty rating type
|
||||
Optional('description'): All(str, Length(min=1)),
|
||||
# Display unit
|
||||
Required('unit'): All(str, Length(min=1)),
|
||||
# Factor for unit converion
|
||||
@ -249,7 +251,8 @@ class BaseCollector(object, metaclass=abc.ABCMeta):
|
||||
|
||||
return name, data
|
||||
|
||||
def _create_data_point(self, unit, qty, price, groupby, metadata, start):
|
||||
def _create_data_point(self, metric, qty, price, groupby, metadata, start):
|
||||
unit = metric['unit']
|
||||
if not start:
|
||||
start = datetime.datetime.now()
|
||||
LOG.debug("Collector [%s]. No start datetime defined for "
|
||||
@ -271,7 +274,8 @@ class BaseCollector(object, metaclass=abc.ABCMeta):
|
||||
groupby['month'] = month_of_the_year
|
||||
groupby['year'] = year
|
||||
|
||||
return DataPoint(unit, qty, price, groupby, metadata)
|
||||
return DataPoint(unit, qty, price, groupby, metadata,
|
||||
metric.get('description'))
|
||||
|
||||
|
||||
class InvalidConfiguration(Exception):
|
||||
|
@ -517,9 +517,10 @@ class GnocchiCollector(collector.BaseCollector):
|
||||
project_id, start, end, e),
|
||||
)
|
||||
continue
|
||||
point = self._create_data_point(
|
||||
met['unit'], qty, 0, groupby, metadata, start)
|
||||
point = self._create_data_point(met, qty, 0, groupby,
|
||||
metadata, start)
|
||||
formated_resources.append(point)
|
||||
|
||||
return formated_resources
|
||||
|
||||
@staticmethod
|
||||
|
@ -231,7 +231,7 @@ class MonascaCollector(collector.BaseCollector):
|
||||
metadata, groupby, qty = self._format_data(
|
||||
met, d, resources_info)
|
||||
|
||||
point = self._create_data_point(
|
||||
met['unit'], qty, 0, groupby, metadata, start)
|
||||
point = self._create_data_point(met, qty, 0, groupby,
|
||||
metadata, start)
|
||||
formated_resources.append(point)
|
||||
return formated_resources
|
||||
|
@ -241,9 +241,8 @@ class PrometheusCollector(collector.BaseCollector):
|
||||
end,
|
||||
item,
|
||||
)
|
||||
|
||||
point = self._create_data_point(self.conf[metric_name]['unit'],
|
||||
qty, 0, groupby, metadata, start)
|
||||
point = self._create_data_point(self.conf[metric_name], qty,
|
||||
0, groupby, metadata, start)
|
||||
formatted_resources.append(point)
|
||||
|
||||
return formatted_resources
|
||||
|
@ -44,12 +44,12 @@ DATAPOINT_SCHEMA = voluptuous.Schema({
|
||||
|
||||
_DataPointBase = collections.namedtuple(
|
||||
"DataPoint",
|
||||
field_names=("unit", "qty", "price", "groupby", "metadata"))
|
||||
field_names=("unit", "qty", "price", "groupby", "metadata", "description"))
|
||||
|
||||
|
||||
class DataPoint(_DataPointBase):
|
||||
|
||||
def __new__(cls, unit, qty, price, groupby, metadata):
|
||||
def __new__(cls, unit, qty, price, groupby, metadata, description=None):
|
||||
return _DataPointBase.__new__(
|
||||
cls,
|
||||
unit or "undefined",
|
||||
@ -58,6 +58,7 @@ class DataPoint(_DataPointBase):
|
||||
decimal.Decimal(str(price) if isinstance(price, float) else price),
|
||||
datastructures.ImmutableDict(groupby),
|
||||
datastructures.ImmutableDict(metadata),
|
||||
description
|
||||
)
|
||||
|
||||
def set_price(self, price):
|
||||
|
@ -280,6 +280,7 @@ class ElasticsearchClient(object):
|
||||
'end': end,
|
||||
'type': type_,
|
||||
'unit': point.unit,
|
||||
'description': point.description,
|
||||
'qty': point.qty,
|
||||
'price': point.price,
|
||||
'groupby': point.groupby,
|
||||
|
@ -138,6 +138,7 @@ class InfluxClient(object):
|
||||
measurement_fields['qty'] = float(point.qty)
|
||||
measurement_fields['price'] = float(point.price)
|
||||
measurement_fields['unit'] = point.unit
|
||||
measurement_fields['description'] = point.description
|
||||
# Unfortunately, this seems to be the fastest way: Having several
|
||||
# measurements would imply a high client-side workload, and this allows
|
||||
# us to filter out unrequired keys
|
||||
|
@ -159,6 +159,8 @@ tests:
|
||||
url: /v2/scope
|
||||
method: PUT
|
||||
status: 400
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
|
||||
- name: Reset state with no results for parameters
|
||||
url: /v2/scope
|
||||
|
@ -300,6 +300,7 @@ class TestElasticsearchClient(unittest.TestCase):
|
||||
'end': end,
|
||||
'type': 'awesome_type',
|
||||
'unit': point.unit,
|
||||
'description': point.description,
|
||||
'qty': point.qty,
|
||||
'price': point.price,
|
||||
'groupby': point.groupby,
|
||||
@ -335,6 +336,7 @@ class TestElasticsearchClient(unittest.TestCase):
|
||||
'end': end,
|
||||
'type': 'awesome_type',
|
||||
'unit': point.unit,
|
||||
'description': point.description,
|
||||
'qty': point.qty,
|
||||
'price': point.price,
|
||||
'groupby': point.groupby,
|
||||
|
@ -278,6 +278,40 @@ option does:
|
||||
metadata:
|
||||
- flavor_id
|
||||
|
||||
Metric description
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sometimes, you will want to use a more descriptive attribute to show more
|
||||
details about the configured rating type. For instance, to provide more
|
||||
details about the rating of operating system licenses or other software
|
||||
licenses configured in the cloud. For that, we have the option called
|
||||
``description``, which is a String like field (up to 64 kB) that can be
|
||||
used to provide more information for a rating of a metric. When configured,
|
||||
this option is persisted as rating metadata and it is available through the
|
||||
summary GET API.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
metrics:
|
||||
instance-status:
|
||||
unit: license-hours
|
||||
alt_name: license-hours
|
||||
description: |
|
||||
Operating system licenses are charged as follows: (i)
|
||||
Linux distro will not be charged; (ii) All Windows up to
|
||||
version 8 are charged .01 every hour, and other versions
|
||||
.5; (iii) Any other operating systems will be charged .02
|
||||
groupby:
|
||||
- id
|
||||
- operating_system_name
|
||||
- operating_system_distro
|
||||
- operating_system_version
|
||||
- flavor_id
|
||||
- flavor_name
|
||||
- cores
|
||||
- ram
|
||||
metadata: []
|
||||
|
||||
Collector-specific configuration
|
||||
--------------------------------
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add description option to a rating metric definition, which
|
||||
can be used to create custom reports in the ``summary`` GET API.
|
Loading…
Reference in New Issue
Block a user