Refactor out Ceilometer V2 API related code
As of Queens the Ceilometer V2 API has been removed. Storage driver related code in monasca-ceilometer can thus be removed. Backport some refactoring that came up in creating https://review.openstack.org/#/c/562400/ Realized some class names could be clearer and fit better with Ceilometer. Update test-requirements.txt with Rocky release of python-monascaclient. Also include more license info. Specify py35 instead of py34 in tox.ini (gates already using py35). Include updates to devstack configuration to keep up with master ceilometer. These include adding values for the [monasca] section in ceilometer.conf and refreshing setup.cfg as well as updating how the connection url to Monasca API is configured. Also include some testing notes in devstack/README.md Change-Id: I9291dfc06d67f18109a0ff66184bd418c6361977
This commit is contained in:
parent
6ebd2dc1c2
commit
8b0fb6d048
|
@ -14,7 +14,4 @@
|
|||
|
||||
|
||||
class NotImplementedError(NotImplementedError):
|
||||
# FIXME(jd) This is used by WSME to return a correct HTTP code. We should
|
||||
# not expose it here but wrap our methods in the API to convert it to a
|
||||
# proper HTTP error.
|
||||
code = 501
|
||||
pass
|
||||
|
|
|
@ -1,178 +0,0 @@
|
|||
#
|
||||
# Copyright 2016 Hewlett Packard
|
||||
# (c) Copyright 2018 SUSE LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Static mapping for Ceilometer static info like unit and type information
|
||||
"""
|
||||
|
||||
import os
|
||||
import pkg_resources
|
||||
import yaml
|
||||
|
||||
from oslo_log import log
|
||||
|
||||
from ceilometer import sample
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class CeilometerStaticMappingDefinitionException(Exception):
|
||||
def __init__(self, message, definition_cfg):
|
||||
super(CeilometerStaticMappingDefinitionException,
|
||||
self).__init__(message)
|
||||
self.message = message
|
||||
self.definition_cfg = definition_cfg
|
||||
|
||||
def __str__(self):
|
||||
return '%s %s: %s' % (self.__class__.__name__,
|
||||
self.definition_cfg, self.message)
|
||||
|
||||
|
||||
class CeilometerStaticMappingDefinition(object):
|
||||
REQUIRED_FIELDS = ['name', 'type', 'unit']
|
||||
|
||||
def __init__(self, definition_cfg):
|
||||
self.cfg = definition_cfg
|
||||
missing = [field for field in self.REQUIRED_FIELDS
|
||||
if not self.cfg.get(field)]
|
||||
if missing:
|
||||
raise CeilometerStaticMappingDefinitionException(
|
||||
"Required fields %s not specified" % missing, self.cfg)
|
||||
|
||||
if ('type' not in self.cfg.get('lookup', []) and
|
||||
self.cfg['type'] not in sample.TYPES):
|
||||
raise CeilometerStaticMappingDefinitionException(
|
||||
"Invalid type %s specified" % self.cfg['type'], self.cfg)
|
||||
|
||||
|
||||
def get_config_file(conf):
|
||||
config_file = conf.monasca.ceilometer_static_info_mapping
|
||||
if not os.path.exists(config_file):
|
||||
config_file = conf.find_file(config_file)
|
||||
if not config_file:
|
||||
config_file = pkg_resources.resource_filename(
|
||||
__name__, "data/ceilometer_static_info_mapping.yaml")
|
||||
return config_file
|
||||
|
||||
|
||||
def setup_ceilometer_static_mapping_config(conf):
|
||||
"""Setup the meters definitions from yaml config file."""
|
||||
config_file = get_config_file(conf)
|
||||
if config_file is not None:
|
||||
LOG.debug("Static Ceilometer mapping file to map static info: %s",
|
||||
config_file)
|
||||
|
||||
with open(config_file) as cf:
|
||||
config = cf.read()
|
||||
|
||||
try:
|
||||
ceilometer_static_mapping_config = yaml.safe_load(config)
|
||||
except yaml.YAMLError as err:
|
||||
if hasattr(err, 'problem_mark'):
|
||||
mark = err.problem_mark
|
||||
errmsg = ("Invalid YAML syntax in static Ceilometer "
|
||||
"Mapping Definitions file %(file)s at line: "
|
||||
"%(line)s, column: %(column)s."
|
||||
% dict(file=config_file,
|
||||
line=mark.line + 1,
|
||||
column=mark.column + 1))
|
||||
else:
|
||||
errmsg = ("YAML error reading static Ceilometer Mapping "
|
||||
"Definitions file %(file)s" %
|
||||
dict(file=config_file))
|
||||
|
||||
LOG.error(errmsg)
|
||||
raise
|
||||
|
||||
else:
|
||||
LOG.debug("No static Ceilometer Definitions configuration file "
|
||||
"found! using default config.")
|
||||
ceilometer_static_mapping_config = {}
|
||||
|
||||
LOG.debug("Ceilometer Monasca Definitions: %s",
|
||||
ceilometer_static_mapping_config)
|
||||
|
||||
return ceilometer_static_mapping_config
|
||||
|
||||
|
||||
def load_definitions(config_def):
|
||||
if not config_def:
|
||||
return []
|
||||
ceilometer_static_mapping_defs = {}
|
||||
for meter_info_static_map in reversed(config_def['meter_info_static_map']):
|
||||
if meter_info_static_map.get('name') in ceilometer_static_mapping_defs:
|
||||
# skip duplicate meters
|
||||
LOG.warning("Skipping duplicate Ceilometer Monasca Mapping"
|
||||
" Definition %s" % meter_info_static_map)
|
||||
continue
|
||||
|
||||
try:
|
||||
md = CeilometerStaticMappingDefinition(meter_info_static_map)
|
||||
ceilometer_static_mapping_defs[meter_info_static_map['name']] = md
|
||||
except CeilometerStaticMappingDefinitionException as me:
|
||||
errmsg = ("Error loading Ceilometer Static Mapping "
|
||||
"Definition : %(err)s" % dict(err=me.message))
|
||||
LOG.error(errmsg)
|
||||
return ceilometer_static_mapping_defs.values()
|
||||
|
||||
|
||||
class ProcessMappedCeilometerStaticInfo(object):
|
||||
"""Implentation for class to provide static info for ceilometer meters
|
||||
|
||||
The class will be responsible for providing the static information of
|
||||
ceilometer meters enabled using pipeline.yaml configuration.
|
||||
get_list_supported_meters: is a get function which can be used to get
|
||||
list of pipeline meters.
|
||||
get_ceilometer_meter_static_definition: returns entire definition for
|
||||
provided meter name
|
||||
get_meter_static_info_key_val: returns specific value for provided meter
|
||||
name and a particular key from definition
|
||||
"""
|
||||
_inited = False
|
||||
_instance = None
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
"""Singleton to avoid duplicated initialization."""
|
||||
if not cls._instance:
|
||||
cls._instance = super(ProcessMappedCeilometerStaticInfo, cls).\
|
||||
__new__(cls, *args, **kwargs)
|
||||
return cls._instance
|
||||
|
||||
def __init__(self, conf):
|
||||
if not (self._instance and self._inited):
|
||||
self.conf = conf
|
||||
self._inited = True
|
||||
self.__definitions = load_definitions(
|
||||
setup_ceilometer_static_mapping_config(self.conf))
|
||||
self.__mapped_meter_info_map = dict()
|
||||
for d in self.__definitions:
|
||||
self.__mapped_meter_info_map[d.cfg['name']] = d
|
||||
|
||||
def get_list_supported_meters(self):
|
||||
return self.__mapped_meter_info_map
|
||||
|
||||
def get_ceilometer_meter_static_definition(self, meter_name):
|
||||
return self.__mapped_meter_info_map.get(meter_name)
|
||||
|
||||
def get_meter_static_info_key_val(self, meter_name, key):
|
||||
return self.__mapped_meter_info_map.get(meter_name).cfg[key]
|
||||
|
||||
def reinitialize(self, conf):
|
||||
self.conf = conf
|
||||
self.__definitions = load_definitions(
|
||||
setup_ceilometer_static_mapping_config(self.conf))
|
||||
self.__mapped_meter_info_map = dict()
|
||||
for d in self.__definitions:
|
||||
self.__mapped_meter_info_map[d.cfg['name']] = d
|
|
@ -1,298 +0,0 @@
|
|||
#
|
||||
# Copyright 2016 Hewlett Packard
|
||||
# (c) Copyright 2018 SUSE LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Monasca metric to Ceilometer Meter Mapper
|
||||
"""
|
||||
|
||||
import functools
|
||||
import os
|
||||
import pkg_resources
|
||||
import six
|
||||
import yaml
|
||||
|
||||
from jsonpath_rw_ext import parser
|
||||
from oslo_log import log
|
||||
|
||||
from ceilometer import pipeline
|
||||
from ceilometer import sample
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class CeiloscaMappingDefinitionException(Exception):
|
||||
def __init__(self, message, definition_cfg):
|
||||
super(CeiloscaMappingDefinitionException, self).__init__(message)
|
||||
self.message = message
|
||||
self.definition_cfg = definition_cfg
|
||||
|
||||
def __str__(self):
|
||||
return '%s %s: %s' % (self.__class__.__name__,
|
||||
self.definition_cfg, self.message)
|
||||
|
||||
|
||||
class CeiloscaMappingDefinition(object):
|
||||
JSONPATH_RW_PARSER = parser.ExtentedJsonPathParser()
|
||||
|
||||
REQUIRED_FIELDS = ['name', 'monasca_metric_name', 'type', 'unit', 'source',
|
||||
'resource_metadata', 'resource_id', 'project_id',
|
||||
'user_id', 'region']
|
||||
|
||||
def __init__(self, definition_cfg):
|
||||
self.cfg = definition_cfg
|
||||
missing = [field for field in self.REQUIRED_FIELDS
|
||||
if not self.cfg.get(field)]
|
||||
if missing:
|
||||
raise CeiloscaMappingDefinitionException(
|
||||
"Required fields %s not specified" % missing, self.cfg)
|
||||
|
||||
self._monasca_metric_name = self.cfg.get('monasca_metric_name')
|
||||
if isinstance(self._monasca_metric_name, six.string_types):
|
||||
self._monasca_metric_name = [self._monasca_metric_name]
|
||||
|
||||
if ('type' not in self.cfg.get('lookup', []) and
|
||||
self.cfg['type'] not in sample.TYPES):
|
||||
raise CeiloscaMappingDefinitionException(
|
||||
"Invalid type %s specified" % self.cfg['type'], self.cfg)
|
||||
|
||||
self._field_getter = {}
|
||||
for name, field in self.cfg.items():
|
||||
if name in ["monasca_metric_name", "lookup"] or not field:
|
||||
continue
|
||||
elif isinstance(field, six.integer_types):
|
||||
self._field_getter[name] = field
|
||||
elif isinstance(field, six.string_types) and not \
|
||||
field.startswith('$'):
|
||||
self._field_getter[name] = field
|
||||
elif isinstance(field, dict) and name == 'resource_metadata':
|
||||
meta = {}
|
||||
for key, val in field.items():
|
||||
parts = self.parse_jsonpath(val)
|
||||
meta[key] = functools.partial(self._parse_jsonpath_field,
|
||||
parts)
|
||||
self._field_getter['resource_metadata'] = meta
|
||||
else:
|
||||
parts = self.parse_jsonpath(field)
|
||||
self._field_getter[name] = functools.partial(
|
||||
self._parse_jsonpath_field, parts)
|
||||
|
||||
def parse_jsonpath(self, field):
|
||||
try:
|
||||
parts = self.JSONPATH_RW_PARSER.parse(field)
|
||||
except Exception as e:
|
||||
raise CeiloscaMappingDefinitionException(
|
||||
"Parse error in JSONPath specification "
|
||||
"'%(jsonpath)s': %(err)s"
|
||||
% dict(jsonpath=field, err=e), self.cfg)
|
||||
return parts
|
||||
|
||||
def parse_fields(self, field, message, all_values=False):
|
||||
getter = self._field_getter.get(field)
|
||||
if not getter:
|
||||
return
|
||||
elif isinstance(getter, dict):
|
||||
dict_val = {}
|
||||
for key, val in getter.items():
|
||||
dict_val[key] = val(message, all_values)
|
||||
return dict_val
|
||||
elif callable(getter):
|
||||
return getter(message, all_values)
|
||||
else:
|
||||
return getter
|
||||
|
||||
@staticmethod
|
||||
def _parse_jsonpath_field(parts, message, all_values):
|
||||
values = [match.value for match in parts.find(message)
|
||||
if match.value is not None]
|
||||
if values:
|
||||
if not all_values:
|
||||
return values[0]
|
||||
return values
|
||||
|
||||
|
||||
def get_config_file(conf):
|
||||
config_file = conf.monasca.ceilometer_monasca_metrics_mapping
|
||||
if not os.path.exists(config_file):
|
||||
config_file = conf.find_file(config_file)
|
||||
if not config_file:
|
||||
config_file = pkg_resources.resource_filename(
|
||||
__name__, "data/ceilosca_mapping.yaml")
|
||||
return config_file
|
||||
|
||||
|
||||
def setup_ceilosca_mapping_config(conf):
|
||||
"""Setup the meters definitions from yaml config file."""
|
||||
config_file = get_config_file(conf)
|
||||
if config_file is not None:
|
||||
LOG.debug("Ceilometer Monasca Mapping Definitions file: %s",
|
||||
config_file)
|
||||
|
||||
with open(config_file) as cf:
|
||||
config = cf.read()
|
||||
|
||||
try:
|
||||
ceilosca_mapping_config = yaml.safe_load(config)
|
||||
except yaml.YAMLError as err:
|
||||
if hasattr(err, 'problem_mark'):
|
||||
mark = err.problem_mark
|
||||
errmsg = ("Invalid YAML syntax in Ceilometer Monasca "
|
||||
"Mapping Definitions file %(file)s at line: "
|
||||
"%(line)s, column: %(column)s."
|
||||
% dict(file=config_file,
|
||||
line=mark.line + 1,
|
||||
column=mark.column + 1))
|
||||
else:
|
||||
errmsg = ("YAML error reading Ceilometer Monasca Mapping "
|
||||
"Definitions file %(file)s" %
|
||||
dict(file=config_file))
|
||||
|
||||
LOG.error(errmsg)
|
||||
raise
|
||||
|
||||
else:
|
||||
LOG.debug("No Ceilometer Monasca Definitions configuration file "
|
||||
"found! using default config.")
|
||||
ceilosca_mapping_config = {}
|
||||
|
||||
LOG.debug("Ceilometer Monasca Definitions: %s",
|
||||
ceilosca_mapping_config)
|
||||
|
||||
return ceilosca_mapping_config
|
||||
|
||||
|
||||
def load_definitions(config_def):
|
||||
if not config_def:
|
||||
return []
|
||||
ceilosca_mapping_defs = {}
|
||||
for meter_metric_map in reversed(config_def['meter_metric_map']):
|
||||
if meter_metric_map.get('name') in ceilosca_mapping_defs:
|
||||
# skip duplicate meters
|
||||
LOG.warning("Skipping duplicate Ceilometer Monasca Mapping"
|
||||
" Definition %s" % meter_metric_map)
|
||||
continue
|
||||
|
||||
try:
|
||||
md = CeiloscaMappingDefinition(meter_metric_map)
|
||||
ceilosca_mapping_defs[meter_metric_map['name']] = md
|
||||
except CeiloscaMappingDefinitionException as me:
|
||||
errmsg = ("Error loading Ceilometer Monasca Mapping "
|
||||
"Definition : %(err)s" % dict(err=me.message))
|
||||
LOG.error(errmsg)
|
||||
return ceilosca_mapping_defs.values()
|
||||
|
||||
|
||||
class ProcessMappedCeiloscaMetric(object):
|
||||
"""Implentation for managing monasca mapped metrics to ceilometer meters
|
||||
|
||||
The class will be responsible for managing mapped meters and their
|
||||
definition. You can use get functions for
|
||||
get_monasca_metric_name: get mapped monasca metric name for ceilometer
|
||||
meter name
|
||||
get_list_monasca_metrics: get list of mapped metrics with their respective
|
||||
definitions
|
||||
get_ceilosca_mapped_metric_definition: get definition of a provided monasca
|
||||
metric name
|
||||
get_ceilosca_mapped_definition_key_val: get respective value of a provided
|
||||
key from mapping definitions
|
||||
The class would be a singleton class
|
||||
"""
|
||||
_inited = False
|
||||
_instance = None
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
"""Singleton to avoid duplicated initialization."""
|
||||
if not cls._instance:
|
||||
cls._instance = super(ProcessMappedCeiloscaMetric, cls).__new__(
|
||||
cls, *args, **kwargs)
|
||||
return cls._instance
|
||||
|
||||
def __init__(self, conf):
|
||||
if not (self._instance and self._inited):
|
||||
self.conf = conf
|
||||
self._inited = True
|
||||
self.__definitions = load_definitions(
|
||||
setup_ceilosca_mapping_config(self.conf))
|
||||
self.__mapped_metric_map = dict()
|
||||
self.__mon_metric_to_cm_meter_map = dict()
|
||||
for d in self.__definitions:
|
||||
self.__mapped_metric_map[d.cfg['monasca_metric_name']] = d
|
||||
self.__mon_metric_to_cm_meter_map[d.cfg['name']] = (
|
||||
d.cfg['monasca_metric_name'])
|
||||
|
||||
def get_monasca_metric_name(self, ceilometer_meter_name):
|
||||
return self.__mon_metric_to_cm_meter_map.get(ceilometer_meter_name)
|
||||
|
||||
def get_list_monasca_metrics(self):
|
||||
return self.__mapped_metric_map
|
||||
|
||||
def get_ceilosca_mapped_metric_definition(self, monasca_metric_name):
|
||||
return self.__mapped_metric_map.get(monasca_metric_name)
|
||||
|
||||
def get_ceilosca_mapped_definition_key_val(self, monasca_metric_name, key):
|
||||
return self.__mapped_metric_map.get(monasca_metric_name).cfg[key]
|
||||
|
||||
def reinitialize(self, conf):
|
||||
self.conf = conf
|
||||
self.__definitions = load_definitions(
|
||||
setup_ceilosca_mapping_config(self.conf))
|
||||
self.__mapped_metric_map = dict()
|
||||
self.__mon_metric_to_cm_meter_map = dict()
|
||||
for d in self.__definitions:
|
||||
self.__mapped_metric_map[d.cfg['monasca_metric_name']] = d
|
||||
self.__mon_metric_to_cm_meter_map[d.cfg['name']] = (
|
||||
d.cfg['monasca_metric_name'])
|
||||
|
||||
|
||||
class PipelineReader(object):
|
||||
"""Implentation for class to provide ceilometer meters enabled by pipeline
|
||||
|
||||
The class will be responsible for providing the list of ceilometer meters
|
||||
enabled using pipeline.yaml configuration.
|
||||
get_pipeline_meters: is a get function which can be used to get list of
|
||||
pipeline meters.
|
||||
"""
|
||||
_inited = False
|
||||
_instance = None
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
"""Singleton to avoid duplicated initialization."""
|
||||
if not cls._instance:
|
||||
cls._instance = super(PipelineReader, cls).__new__(
|
||||
cls, *args, **kwargs)
|
||||
return cls._instance
|
||||
|
||||
def __init__(self, conf):
|
||||
if not (self._instance and self._inited):
|
||||
self._inited = True
|
||||
self.conf = conf
|
||||
self.__pipeline_manager = pipeline.setup_pipeline(self.conf)
|
||||
self.__meters_from_pipeline = set()
|
||||
for pipe in self.__pipeline_manager.pipelines:
|
||||
if not isinstance(pipe, pipeline.EventPipeline):
|
||||
for meter in pipe.source.meters:
|
||||
if meter not in self.__meters_from_pipeline:
|
||||
self.__meters_from_pipeline.add(meter)
|
||||
|
||||
def get_pipeline_meters(self):
|
||||
return self.__meters_from_pipeline
|
||||
|
||||
def reinitialize(self):
|
||||
self.__pipeline_manager = pipeline.setup_pipeline(self.conf)
|
||||
self.__meters_from_pipeline = set()
|
||||
for pipe in self.__pipeline_manager.pipelines:
|
||||
if not isinstance(pipe, pipeline.EventPipeline):
|
||||
for meter in pipe.source.meters:
|
||||
if meter not in self.__meters_from_pipeline:
|
||||
self.__meters_from_pipeline.add(meter)
|
|
@ -1,147 +0,0 @@
|
|||
#reference: https://docs.openstack.org/ceilometer/latest/admin/telemetry-measurements.html
|
||||
---
|
||||
|
||||
meter_info_static_map:
|
||||
- name: "disk.ephemeral.size"
|
||||
type: "gauge"
|
||||
unit: "GB"
|
||||
|
||||
- name: "disk.root.size"
|
||||
type: "gauge"
|
||||
unit: "GB"
|
||||
|
||||
- name: "image"
|
||||
type: "gauge"
|
||||
unit: "image"
|
||||
|
||||
- name: "image.delete"
|
||||
type: "delta"
|
||||
unit: "image"
|
||||
|
||||
- name: "image.size"
|
||||
type: "gauge"
|
||||
unit: "B"
|
||||
|
||||
- name: "image.update"
|
||||
type: "gauge"
|
||||
unit: "image"
|
||||
|
||||
- name: "image.upload"
|
||||
type: "delta"
|
||||
unit: "image"
|
||||
|
||||
- name: "instance"
|
||||
type: "gauge"
|
||||
unit: "instance"
|
||||
|
||||
- name: "ip.floating"
|
||||
type: "gauge"
|
||||
unit: "ip"
|
||||
|
||||
- name: "ip.floating.create"
|
||||
type: "delta"
|
||||
unit: "ip"
|
||||
|
||||
- name: "ip.floating.update"
|
||||
type: "delta"
|
||||
unit: "ip"
|
||||
|
||||
- name: "memory"
|
||||
type: "gauge"
|
||||
unit: "MB"
|
||||
|
||||
- name: "network"
|
||||
type: "gauge"
|
||||
unit: "network"
|
||||
|
||||
- name: "network.create"
|
||||
type: "delta"
|
||||
unit: "network"
|
||||
|
||||
- name: "network.delete"
|
||||
type: "delta"
|
||||
unit: "network"
|
||||
|
||||
- name: "network.update"
|
||||
type: "delta"
|
||||
unit: "network"
|
||||
|
||||
- name: "port"
|
||||
type: "gauge"
|
||||
unit: "port"
|
||||
|
||||
- name: "port.create"
|
||||
type: "delta"
|
||||
unit: "port"
|
||||
|
||||
- name: "port.delete"
|
||||
type: "delta"
|
||||
unit: "port"
|
||||
|
||||
- name: "port.update"
|
||||
type: "delta"
|
||||
unit: "port"
|
||||
|
||||
- name: "router"
|
||||
type: "gauge"
|
||||
unit: "router"
|
||||
|
||||
- name: "router.create"
|
||||
type: "delta"
|
||||
unit: "router"
|
||||
|
||||
- name: "router.delete"
|
||||
type: "delta"
|
||||
unit: "router"
|
||||
|
||||
- name: "router.update"
|
||||
type: "delta"
|
||||
unit: "router"
|
||||
|
||||
- name: "storage.objects"
|
||||
type: "gauge"
|
||||
unit: "object"
|
||||
|
||||
- name: "storage.objects.containers"
|
||||
type: "gauge"
|
||||
unit: "container"
|
||||
|
||||
- name: "storage.objects.size"
|
||||
type: "gauge"
|
||||
unit: "B"
|
||||
|
||||
- name: "subnet"
|
||||
type: "gauge"
|
||||
unit: "subnet"
|
||||
|
||||
- name: "subnet.create"
|
||||
type: "delta"
|
||||
unit: "subnet"
|
||||
|
||||
- name: "subnet.delete"
|
||||
type: "delta"
|
||||
unit: "subnet"
|
||||
|
||||
- name: "subnet.update"
|
||||
type: "delta"
|
||||
unit: "subnet"
|
||||
|
||||
- name: "vcpus"
|
||||
type: "gauge"
|
||||
unit: "vcpu"
|
||||
|
||||
- name: "volume"
|
||||
type: "gauge"
|
||||
unit: "volume"
|
||||
|
||||
- name: "volume.delete.end"
|
||||
type: "delta"
|
||||
unit: "volume"
|
||||
|
||||
- name: "volume.size"
|
||||
type: "gauge"
|
||||
unit: "GB"
|
||||
|
||||
- name: "volume.update.end"
|
||||
type: "delta"
|
||||
unit: "volume"
|
|
@ -1,24 +0,0 @@
|
|||
---
|
||||
|
||||
meter_metric_map:
|
||||
- name: "network.outgoing.rate"
|
||||
monasca_metric_name: "vm.net.out_rate"
|
||||
resource_id: $.dimensions.resource_id
|
||||
project_id: $.dimensions.project_id
|
||||
user_id: $.dimensions.user_id
|
||||
region: "NA"
|
||||
type: "gauge"
|
||||
unit: "b/s"
|
||||
source: "NA"
|
||||
resource_metadata: $.measurement[0][2]
|
||||
|
||||
- name: "network.incoming.rate"
|
||||
monasca_metric_name: "vm.net.in_rate"
|
||||
resource_id: $.dimensions.resource_id
|
||||
project_id: $.dimensions.project_id
|
||||
user_id: $.dimensions.user_id
|
||||
region: "NA"
|
||||
type: "gauge"
|
||||
unit: "b/s"
|
||||
source: "NA"
|
||||
resource_metadata: $.measurement[0][2]
|
|
@ -13,8 +13,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
|
||||
from monascaclient import client
|
||||
from monascaclient import exc
|
||||
from oslo_log import log
|
||||
|
@ -121,6 +119,7 @@ class Client(object):
|
|||
self._endpoint, **self._kwargs)
|
||||
|
||||
def call_func(self, func, **kwargs):
|
||||
"""General method for calling any Monasca API function."""
|
||||
@tenacity.retry(
|
||||
wait=tenacity.wait_fixed(self._retry_interval),
|
||||
stop=tenacity.stop_after_attempt(self._max_retries),
|
||||
|
@ -156,101 +155,3 @@ class Client(object):
|
|||
def metrics_create(self, **kwargs):
|
||||
return self.call_func(self._mon_client.metrics.create,
|
||||
**kwargs)
|
||||
|
||||
def metrics_list(self, **kwargs):
|
||||
"""Using monasca pagination to get all metrics.
|
||||
|
||||
We yield endless metrics till caller doesn't want more or
|
||||
no more is left.
|
||||
"""
|
||||
search_args = copy.deepcopy(kwargs)
|
||||
metrics = self.call_func(self._mon_client.metrics.list, **search_args)
|
||||
# check if api pagination is enabled
|
||||
if self._enable_api_pagination:
|
||||
# page through monasca results
|
||||
while metrics:
|
||||
for metric in metrics:
|
||||
yield metric
|
||||
# offset for metrics is the last metric's id
|
||||
search_args['offset'] = metric['id']
|
||||
metrics = self.call_func(self._mon_client.metrics.list,
|
||||
**search_args)
|
||||
else:
|
||||
for metric in metrics:
|
||||
yield metric
|
||||
|
||||
def metric_names_list(self, **kwargs):
|
||||
return self.call_func(self._mon_client.metrics.list_names,
|
||||
**kwargs)
|
||||
|
||||
def measurements_list(self, **kwargs):
|
||||
"""Using monasca pagination to get all measurements.
|
||||
|
||||
We yield endless measurements till caller doesn't want more or
|
||||
no more is left.
|
||||
"""
|
||||
search_args = copy.deepcopy(kwargs)
|
||||
measurements = self.call_func(
|
||||
self._mon_client.metrics.list_measurements,
|
||||
**search_args)
|
||||
# check if api pagination is enabled
|
||||
if self._enable_api_pagination:
|
||||
while measurements and len(measurements[0]["measurements"]) > 0:
|
||||
for measurement in measurements:
|
||||
if measurement["measurements"] is not None and \
|
||||
len(measurement["measurements"]) > 0:
|
||||
# offset for measurements is measurement id composited
|
||||
# with the last measurement's timestamp
|
||||
last_good_offset = '%s_%s' % (
|
||||
measurement['id'],
|
||||
measurement['measurements'][-1][0])
|
||||
yield measurement
|
||||
search_args['offset'] = last_good_offset
|
||||
measurements = self.call_func(
|
||||
self._mon_client.metrics.list_measurements,
|
||||
**search_args)
|
||||
else:
|
||||
for measurement in measurements:
|
||||
yield measurement
|
||||
|
||||
def statistics_list(self, **kwargs):
|
||||
"""Using monasca pagination to get all statistics.
|
||||
|
||||
We yield endless statistics till caller doesn't want more or
|
||||
no more is left.
|
||||
"""
|
||||
search_args = copy.deepcopy(kwargs)
|
||||
statistics = self.call_func(self._mon_client.metrics.list_statistics,
|
||||
**search_args)
|
||||
# check if api pagination is enabled
|
||||
if self._enable_api_pagination:
|
||||
while statistics and len(statistics[0]["statistics"]) > 0:
|
||||
for statistic in statistics:
|
||||
if statistic["statistics"] is not None and \
|
||||
len(statistic["statistics"]) > 0:
|
||||
# offset for statistics is statistic id composited with
|
||||
# the last statistic's timestamp
|
||||
last_good_offset = '%s_%s' % (
|
||||
statistic['id'], statistic['statistics'][-1][0])
|
||||
yield statistic
|
||||
|
||||
# with groupby, the offset is unpredictable to me, we don't
|
||||
# support pagination for it now.
|
||||
if kwargs.get('group_by'):
|
||||
break
|
||||
search_args['offset'] = last_good_offset
|
||||
statistics = self.call_func(
|
||||
self._mon_client.metrics.list_statistics,
|
||||
**search_args)
|
||||
# unlike metrics.list and metrics.list_measurements
|
||||
# return whole new data, metrics.list_statistics
|
||||
# next page will use last page's final statistic
|
||||
# data as the first one, so we need to pop it here.
|
||||
# I think Monasca should treat this as a bug and fix it.
|
||||
if statistics:
|
||||
statistics[0]['statistics'].pop(0)
|
||||
if len(statistics[0]['statistics']) == 0:
|
||||
statistics.pop(0)
|
||||
else:
|
||||
for statistic in statistics:
|
||||
yield statistic
|
||||
|
|
|
@ -19,18 +19,6 @@ from oslo_config import cfg
|
|||
|
||||
OPTS = [
|
||||
|
||||
# from ceilometer_static_info_mapping
|
||||
cfg.StrOpt('ceilometer_static_info_mapping',
|
||||
default='ceilometer_static_info_mapping.yaml',
|
||||
help='Configuration mapping file to map ceilometer meters to '
|
||||
'their units an type information'),
|
||||
|
||||
# from ceilosca_mapping
|
||||
cfg.StrOpt('ceilometer_monasca_metrics_mapping',
|
||||
default='ceilosca_mapping.yaml',
|
||||
help='Configuration mapping file to map monasca metrics to '
|
||||
'ceilometer meters'),
|
||||
|
||||
# from monasca_client
|
||||
cfg.StrOpt('clientapi_version',
|
||||
default='2_0',
|
|
@ -1,5 +1,4 @@
|
|||
# Copyright 2014 eNovance
|
||||
# (c) Copyright 2018 SUSE LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
|
@ -32,7 +31,7 @@ import ceilometer.ipmi.pollsters
|
|||
import ceilometer.keystone_client
|
||||
import ceilometer.meter.notifications
|
||||
import ceilometer.middleware
|
||||
import ceilometer.monasca_ceilometer_opts
|
||||
import ceilometer.monasca_opts
|
||||
import ceilometer.neutron_client
|
||||
import ceilometer.notification
|
||||
import ceilometer.nova_client
|
||||
|
@ -95,28 +94,6 @@ def list_opts():
|
|||
help='Number of seconds between checks to see if group '
|
||||
'membership has changed'),
|
||||
]),
|
||||
('dispatcher_gnocchi', (
|
||||
cfg.StrOpt(
|
||||
'filter_project',
|
||||
deprecated_for_removal=True,
|
||||
default='gnocchi',
|
||||
help='Gnocchi project used to filter out samples '
|
||||
'generated by Gnocchi service activity'),
|
||||
cfg.StrOpt(
|
||||
'archive_policy',
|
||||
deprecated_for_removal=True,
|
||||
help='The archive policy to use when the dispatcher '
|
||||
'create a new metric.'),
|
||||
cfg.StrOpt(
|
||||
'resources_definition_file',
|
||||
deprecated_for_removal=True,
|
||||
default='gnocchi_resources.yaml',
|
||||
help=('The Yaml file that defines mapping between samples '
|
||||
'and gnocchi resources/metrics')),
|
||||
cfg.FloatOpt(
|
||||
'request_timeout', default=6.05, min=0.0,
|
||||
deprecated_for_removal=True,
|
||||
help='Number of seconds before request to gnocchi times out'))),
|
||||
('event', ceilometer.event.converter.OPTS),
|
||||
('hardware', itertools.chain(
|
||||
ceilometer.hardware.discovery.OPTS,
|
||||
|
@ -125,7 +102,7 @@ def list_opts():
|
|||
itertools.chain(ceilometer.ipmi.platform.intel_node_manager.OPTS,
|
||||
ceilometer.ipmi.pollsters.OPTS)),
|
||||
('meter', ceilometer.meter.notifications.OPTS),
|
||||
('monasca', ceilometer.monasca_ceilometer_opts.OPTS),
|
||||
('monasca', ceilometer.monasca_opts.OPTS),
|
||||
('notification',
|
||||
itertools.chain(ceilometer.notification.OPTS,
|
||||
ceilometer.notification.EXCHANGES_OPTS)),
|
||||
|
@ -133,6 +110,7 @@ def list_opts():
|
|||
('publisher', ceilometer.publisher.utils.OPTS),
|
||||
('publisher_notifier', ceilometer.publisher.messaging.NOTIFIER_OPTS),
|
||||
('rgw_admin_credentials', ceilometer.objectstore.rgw.CREDENTIAL_OPTS),
|
||||
('rgw_client', ceilometer.objectstore.rgw.CLIENT_OPTS),
|
||||
('service_types',
|
||||
itertools.chain(ceilometer.image.discovery.SERVICE_OPTS,
|
||||
ceilometer.neutron_client.SERVICE_OPTS,
|
||||
|
|
|
@ -21,6 +21,7 @@ import threading
|
|||
import time
|
||||
|
||||
from oslo_log import log
|
||||
from six import moves
|
||||
|
||||
import ceilometer
|
||||
from ceilometer import monasca_client as mon_client
|
||||
|
@ -199,7 +200,7 @@ class MonascaPublisher(publisher.ConfigPublisherBase):
|
|||
|
||||
# Iterate over the retry_queue to eliminate
|
||||
# metrics that have maxed out their retry attempts
|
||||
for ctr in xrange(retry_count):
|
||||
for ctr in moves.xrange(retry_count):
|
||||
if self.retry_counter[ctr] > self.conf.monasca.max_retries:
|
||||
if hasattr(self, 'archive_handler'):
|
||||
self.archive_handler.publish_samples(
|
|
@ -22,8 +22,6 @@ from oslo_utils import timeutils
|
|||
import six
|
||||
import yaml
|
||||
|
||||
from ceilometer.ceilosca_mapping.ceilosca_mapping import (
|
||||
CeiloscaMappingDefinitionException)
|
||||
from ceilometer import sample as sample_util
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
@ -37,6 +35,17 @@ class NoMappingsFound(Exception):
|
|||
pass
|
||||
|
||||
|
||||
class CeiloscaMappingDefinitionException(Exception):
|
||||
def __init__(self, message, definition_cfg):
|
||||
super(CeiloscaMappingDefinitionException, self).__init__(message)
|
||||
self.message = message
|
||||
self.definition_cfg = definition_cfg
|
||||
|
||||
def __str__(self):
|
||||
return '%s %s: %s' % (self.__class__.__name__,
|
||||
self.definition_cfg, self.message)
|
||||
|
||||
|
||||
class MonascaDataFilter(object):
|
||||
JSONPATH_RW_PARSER = parser.ExtentedJsonPathParser()
|
||||
|
||||
|
@ -113,7 +122,7 @@ class MonascaDataFilter(object):
|
|||
# If following convention, dict will have one and only one
|
||||
# element of the form <monasca key>: <json path>
|
||||
if len(meta_key.keys()) == 1:
|
||||
mon_key = meta_key.keys()[0]
|
||||
mon_key = list(meta_key.keys())[0]
|
||||
else:
|
||||
# If no keys or more keys than one
|
||||
raise CeiloscaMappingDefinitionException(
|
||||
|
|
|
@ -19,9 +19,7 @@ import mock
|
|||
from oslo_utils import timeutils
|
||||
from oslotest import base
|
||||
|
||||
from ceilometer.ceilosca_mapping.ceilosca_mapping import (
|
||||
CeiloscaMappingDefinitionException)
|
||||
from ceilometer import monasca_ceilometer_opts
|
||||
from ceilometer import monasca_opts
|
||||
from ceilometer.publisher import monasca_data_filter as mdf
|
||||
from ceilometer import sample
|
||||
from ceilometer import service
|
||||
|
@ -31,7 +29,7 @@ class TestMonUtils(base.BaseTestCase):
|
|||
def setUp(self):
|
||||
super(TestMonUtils, self).setUp()
|
||||
self.CONF = service.prepare_service([], [])
|
||||
self.CONF.register_opts(list(monasca_ceilometer_opts.OPTS),
|
||||
self.CONF.register_opts(list(monasca_opts.OPTS),
|
||||
'monasca')
|
||||
self._field_mappings = {
|
||||
'dimensions': ['resource_id',
|
||||
|
@ -418,7 +416,7 @@ class TestMonUtils(base.BaseTestCase):
|
|||
try:
|
||||
# Don't assign to a variable, this should raise
|
||||
data_filter.process_sample_for_monasca(s)
|
||||
except CeiloscaMappingDefinitionException as e:
|
||||
except mdf.CeiloscaMappingDefinitionException as e:
|
||||
self.assertEqual(
|
||||
'Metadata format mismatch, value should be '
|
||||
'a simple string. [\'aaa0001\', \'bbbb002\']',
|
||||
|
@ -503,7 +501,7 @@ class TestMonUtils(base.BaseTestCase):
|
|||
try:
|
||||
# Don't assign to a variable as this should raise
|
||||
data_filter.process_sample_for_monasca(s)
|
||||
except CeiloscaMappingDefinitionException as e:
|
||||
except mdf.CeiloscaMappingDefinitionException as e:
|
||||
# Make sure we got the right kind of error
|
||||
# Cannot check the whole message text, as python
|
||||
# may reorder a dict when producing a string version
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Tests for ceilometer/publisher/monclient.py
|
||||
"""Tests for ceilometer/publisher/monasca.py
|
||||
"""
|
||||
|
||||
import datetime
|
||||
|
@ -23,9 +23,9 @@ import time
|
|||
import mock
|
||||
from oslotest import base
|
||||
|
||||
from ceilometer import monasca_ceilometer_opts
|
||||
from ceilometer import monasca_client as mon_client
|
||||
from ceilometer.publisher import monclient
|
||||
from ceilometer import monasca_opts
|
||||
from ceilometer.publisher import monasca as mon_publisher
|
||||
from ceilometer import sample
|
||||
from ceilometer import service
|
||||
|
||||
|
@ -111,7 +111,7 @@ class TestMonascaPublisher(base.BaseTestCase):
|
|||
super(TestMonascaPublisher, self).setUp()
|
||||
|
||||
self.CONF = service.prepare_service([], [])
|
||||
self.CONF.register_opts(list(monasca_ceilometer_opts.OPTS),
|
||||
self.CONF.register_opts(list(monasca_opts.OPTS),
|
||||
'monasca')
|
||||
self.CONF.set_override('service_username', 'ceilometer', 'monasca')
|
||||
self.CONF.set_override('service_password', 'admin', 'monasca')
|
||||
|
@ -136,7 +136,7 @@ class TestMonascaPublisher(base.BaseTestCase):
|
|||
side_effect=[field_mappings])
|
||||
def test_publisher_publish(self, mapping_patch):
|
||||
self.CONF.set_override('batch_mode', False, group='monasca')
|
||||
publisher = monclient.MonascaPublisher(self.CONF, self.parsed_url)
|
||||
publisher = mon_publisher.MonascaPublisher(self.CONF, self.parsed_url)
|
||||
publisher.mon_client = mock.MagicMock()
|
||||
|
||||
with mock.patch.object(publisher.mon_client,
|
||||
|
@ -154,7 +154,7 @@ class TestMonascaPublisher(base.BaseTestCase):
|
|||
self.CONF.set_override('batch_count', 3, group='monasca')
|
||||
self.CONF.set_override('batch_polling_interval', 1, group='monasca')
|
||||
|
||||
publisher = monclient.MonascaPublisher(self.CONF, self.parsed_url)
|
||||
publisher = mon_publisher.MonascaPublisher(self.CONF, self.parsed_url)
|
||||
publisher.mon_client = mock.MagicMock()
|
||||
with mock.patch.object(publisher.mon_client,
|
||||
'metrics_create') as mock_create:
|
||||
|
@ -175,7 +175,7 @@ class TestMonascaPublisher(base.BaseTestCase):
|
|||
self.CONF.set_override('retry_interval', 2, group='monasca')
|
||||
self.CONF.set_override('max_retries', 1, group='monasca')
|
||||
|
||||
publisher = monclient.MonascaPublisher(self.CONF, self.parsed_url)
|
||||
publisher = mon_publisher.MonascaPublisher(self.CONF, self.parsed_url)
|
||||
publisher.mon_client = mock.MagicMock()
|
||||
with mock.patch.object(publisher.mon_client,
|
||||
'metrics_create') as mock_create:
|
||||
|
@ -200,8 +200,8 @@ class TestMonascaPublisher(base.BaseTestCase):
|
|||
'ceilometer.publisher.file.FilePublisher',
|
||||
return_value=self.fake_publisher))
|
||||
|
||||
publisher = monclient.MonascaPublisher(self.CONF,
|
||||
self.parsed_url)
|
||||
publisher = mon_publisher.MonascaPublisher(self.CONF,
|
||||
self.parsed_url)
|
||||
publisher.mon_client = mock.MagicMock()
|
||||
|
||||
with mock.patch.object(publisher.mon_client,
|
||||
|
|
|
@ -17,8 +17,8 @@ import mock
|
|||
from oslo_utils import netutils
|
||||
from oslotest import base
|
||||
|
||||
from ceilometer import monasca_ceilometer_opts
|
||||
from ceilometer import monasca_client
|
||||
from ceilometer import monasca_opts
|
||||
from ceilometer import service
|
||||
|
||||
from monascaclient import exc
|
||||
|
@ -30,7 +30,7 @@ class TestMonascaClient(base.BaseTestCase):
|
|||
super(TestMonascaClient, self).setUp()
|
||||
|
||||
self.CONF = service.prepare_service([], [])
|
||||
self.CONF.register_opts(list(monasca_ceilometer_opts.OPTS),
|
||||
self.CONF.register_opts(list(monasca_opts.OPTS),
|
||||
'monasca')
|
||||
self.CONF.set_override('service_username', 'ceilometer', 'monasca')
|
||||
self.CONF.set_override('service_password', 'admin', 'monasca')
|
||||
|
@ -78,7 +78,7 @@ class TestMonascaClient(base.BaseTestCase):
|
|||
as create_patch:
|
||||
e = self.assertRaises(tenacity.RetryError,
|
||||
self.mc.metrics_create)
|
||||
(original_ex, traceobj) = e.last_attempt.exception_info()
|
||||
original_ex = e.last_attempt.exception()
|
||||
self.assertIsInstance(original_ex,
|
||||
monasca_client.MonascaServiceException)
|
||||
self.assertEqual(1, create_patch.call_count)
|
||||
|
@ -110,16 +110,6 @@ class TestMonascaClient(base.BaseTestCase):
|
|||
|
||||
self.assertIsNotNone(True, conf.service_username)
|
||||
|
||||
def test_retry_on_key_error(self):
|
||||
self.CONF.set_override('database_max_retries', 2, 'monasca')
|
||||
self.CONF.set_override('database_retry_interval', 1, 'monasca')
|
||||
self.mc = self._get_client()
|
||||
with mock.patch.object(
|
||||
self.mc._mon_client.metrics, 'list',
|
||||
side_effect=[KeyError, []]) as mocked_metrics_list:
|
||||
list(self.mc.metrics_list())
|
||||
self.assertEqual(2, mocked_metrics_list.call_count)
|
||||
|
||||
def test_no_retry_on_invalid_parameter(self):
|
||||
self.CONF.set_override('database_max_retries', 2, 'monasca')
|
||||
self.CONF.set_override('database_retry_interval', 1, 'monasca')
|
||||
|
@ -128,16 +118,16 @@ class TestMonascaClient(base.BaseTestCase):
|
|||
def _check(exception):
|
||||
expected_exc = monasca_client.MonascaInvalidParametersException
|
||||
with mock.patch.object(
|
||||
self.mc._mon_client.metrics, 'list',
|
||||
side_effect=[exception, []]
|
||||
self.mc._mon_client.metrics, 'create',
|
||||
side_effect=[exception, True]
|
||||
) as mocked_metrics_list:
|
||||
self.assertRaises(expected_exc, list, self.mc.metrics_list())
|
||||
self.assertRaises(expected_exc, self.mc.metrics_create)
|
||||
self.assertEqual(1, mocked_metrics_list.call_count)
|
||||
|
||||
_check(exc.http.UnprocessableEntity)
|
||||
_check(exc.http.BadRequest)
|
||||
|
||||
def test_max_retris_not_too_much(self):
|
||||
def test_max_retries_not_too_much(self):
|
||||
def _check(configured, expected):
|
||||
self.CONF.set_override('database_max_retries', configured,
|
||||
'monasca')
|
||||
|
@ -151,25 +141,27 @@ class TestMonascaClient(base.BaseTestCase):
|
|||
|
||||
def test_meaningful_exception_message(self):
|
||||
with mock.patch.object(
|
||||
self.mc._mon_client.metrics, 'list',
|
||||
self.mc._mon_client.metrics, 'create',
|
||||
side_effect=[exc.http.InternalServerError,
|
||||
exc.http.UnprocessableEntity,
|
||||
KeyError]):
|
||||
e = self.assertRaises(
|
||||
tenacity.RetryError,
|
||||
list, self.mc.metrics_list())
|
||||
(original_ex, traceobj) = e.last_attempt.exception_info()
|
||||
self.mc.metrics_create)
|
||||
original_ex = e.last_attempt.exception()
|
||||
self.assertIn('Monasca service is unavailable',
|
||||
str(original_ex))
|
||||
|
||||
e = self.assertRaises(
|
||||
monasca_client.MonascaInvalidParametersException,
|
||||
list, self.mc.metrics_list())
|
||||
self.mc.metrics_create)
|
||||
self.assertIn('Request cannot be handled by Monasca',
|
||||
str(e))
|
||||
|
||||
e = self.assertRaises(
|
||||
tenacity.RetryError,
|
||||
list, self.mc.metrics_list())
|
||||
(original_ex, traceobj) = e.last_attempt.exception_info()
|
||||
self.mc.metrics_create)
|
||||
original_ex = e.last_attempt.exception()
|
||||
self.assertIn('An exception is raised from Monasca',
|
||||
str(original_ex))
|
||||
|
||||
|
@ -181,238 +173,3 @@ class TestMonascaClient(base.BaseTestCase):
|
|||
self.assertRaises(
|
||||
monasca_client.MonascaInvalidParametersException,
|
||||
self.mc.metrics_create)
|
||||
|
||||
def test_metrics_list_with_pagination(self):
|
||||
|
||||
metric_list_pages = [[{u'dimensions': {},
|
||||
u'measurements': [
|
||||
[u'2015-04-14T17:52:31Z',
|
||||
1.0, {}]],
|
||||
u'id': u'2015-04-14T18:42:31Z',
|
||||
u'columns': [u'timestamp', u'value',
|
||||
u'value_meta'],
|
||||
u'name': u'test1'}],
|
||||
[{u'dimensions': {},
|
||||
u'measurements': [
|
||||
[u'2015-04-15T17:52:31Z',
|
||||
2.0, {}]],
|
||||
u'id': u'2015-04-15T18:42:31Z',
|
||||
u'columns': [u'timestamp', u'value',
|
||||
u'value_meta'],
|
||||
u'name': u'test2'}], None]
|
||||
|
||||
expected_page_count = len(metric_list_pages)
|
||||
expected_metric_names = ["test1", "test2"]
|
||||
|
||||
self.CONF.set_override('enable_api_pagination',
|
||||
True, group='monasca')
|
||||
# get a new ceilosca mc
|
||||
mc = self._get_client()
|
||||
with mock.patch.object(
|
||||
mc._mon_client.metrics, 'list',
|
||||
side_effect=metric_list_pages) as mocked_metrics_list:
|
||||
returned_metrics = mc.metrics_list()
|
||||
returned_metric_names_list = [metric["name"]
|
||||
for metric in returned_metrics]
|
||||
self.assertListEqual(expected_metric_names,
|
||||
returned_metric_names_list)
|
||||
self.assertEqual(expected_page_count,
|
||||
mocked_metrics_list.call_count)
|
||||
self.assertEqual(True, mocked_metrics_list.called)
|
||||
|
||||
def test_metrics_list_without_pagination(self):
|
||||
|
||||
metric_list_pages = [[{u'dimensions': {},
|
||||
u'measurements': [
|
||||
[u'2015-04-14T17:52:31Z',
|
||||
1.0, {}]],
|
||||
u'id': u'2015-04-14T18:42:31Z',
|
||||
u'columns': [u'timestamp', u'value',
|
||||
u'value_meta'],
|
||||
u'name': u'test1'}],
|
||||
[{u'dimensions': {},
|
||||
u'measurements': [
|
||||
[u'2015-04-15T17:52:31Z',
|
||||
2.0, {}]],
|
||||
u'id': u'2015-04-15T18:42:31Z',
|
||||
u'columns': [u'timestamp', u'value',
|
||||
u'value_meta'],
|
||||
u'name': u'test2'}], None]
|
||||
|
||||
# first page only
|
||||
expected_page_count = 1
|
||||
expected_metric_names = ["test1"]
|
||||
|
||||
self.CONF.set_override('enable_api_pagination',
|
||||
False, group='monasca')
|
||||
# get a new ceilosca mc
|
||||
mc = self._get_client()
|
||||
with mock.patch.object(
|
||||
mc._mon_client.metrics, 'list',
|
||||
side_effect=metric_list_pages) as mocked_metrics_list:
|
||||
returned_metrics = mc.metrics_list()
|
||||
returned_metric_names_list = [metric["name"]
|
||||
for metric in returned_metrics]
|
||||
self.assertListEqual(expected_metric_names,
|
||||
returned_metric_names_list)
|
||||
self.assertEqual(expected_page_count,
|
||||
mocked_metrics_list.call_count)
|
||||
self.assertEqual(True, mocked_metrics_list.called)
|
||||
|
||||
def test_measurement_list_with_pagination(self):
|
||||
|
||||
measurement_list_pages = [[{u'dimensions': {},
|
||||
u'measurements': [
|
||||
[u'2015-04-14T17:52:31Z',
|
||||
1.0, {}]],
|
||||
u'id': u'2015-04-14T18:42:31Z',
|
||||
u'columns': [u'timestamp', u'value',
|
||||
u'value_meta'],
|
||||
u'name': u'test1'}],
|
||||
[{u'dimensions': {},
|
||||
u'measurements': [
|
||||
[u'2015-04-15T17:52:31Z',
|
||||
2.0, {}]],
|
||||
u'id': u'2015-04-15T18:42:31Z',
|
||||
u'columns': [u'timestamp', u'value',
|
||||
u'value_meta'],
|
||||
u'name': u'test2'}], None]
|
||||
|
||||
expected_page_count = len(measurement_list_pages)
|
||||
expected_metric_names = ["test1", "test2"]
|
||||
|
||||
self.CONF.set_override('enable_api_pagination',
|
||||
True, group='monasca')
|
||||
# get a new ceilosca mc
|
||||
mc = self._get_client()
|
||||
with mock.patch.object(
|
||||
mc._mon_client.metrics, 'list_measurements',
|
||||
side_effect=measurement_list_pages) as mocked_metrics_list:
|
||||
returned_metrics = mc.measurements_list()
|
||||
returned_metric_names_list = [metric["name"]
|
||||
for metric in returned_metrics]
|
||||
self.assertListEqual(expected_metric_names,
|
||||
returned_metric_names_list)
|
||||
self.assertEqual(expected_page_count,
|
||||
mocked_metrics_list.call_count)
|
||||
self.assertEqual(True, mocked_metrics_list.called)
|
||||
|
||||
def test_measurement_list_without_pagination(self):
|
||||
|
||||
measurement_list_pages = [[{u'dimensions': {},
|
||||
u'measurements': [
|
||||
[u'2015-04-14T17:52:31Z',
|
||||
1.0, {}]],
|
||||
u'id': u'2015-04-14T18:42:31Z',
|
||||
u'columns': [u'timestamp', u'value',
|
||||
u'value_meta'],
|
||||
u'name': u'test1'}],
|
||||
[{u'dimensions': {},
|
||||
u'measurements': [
|
||||
[u'2015-04-15T17:52:31Z',
|
||||
2.0, {}]],
|
||||
u'id': u'2015-04-15T18:42:31Z',
|
||||
u'columns': [u'timestamp', u'value',
|
||||
u'value_meta'],
|
||||
u'name': u'test2'}], None]
|
||||
|
||||
# first page only
|
||||
expected_page_count = 1
|
||||
expected_metric_names = ["test1"]
|
||||
|
||||
self.CONF.set_override('enable_api_pagination',
|
||||
False, group='monasca')
|
||||
# get a new ceilosca mc
|
||||
mc = self._get_client()
|
||||
with mock.patch.object(
|
||||
mc._mon_client.metrics, 'list_measurements',
|
||||
side_effect=measurement_list_pages) as mocked_metrics_list:
|
||||
returned_metrics = mc.measurements_list()
|
||||
returned_metric_names_list = [metric["name"]
|
||||
for metric in returned_metrics]
|
||||
self.assertListEqual(expected_metric_names,
|
||||
returned_metric_names_list)
|
||||
self.assertEqual(expected_page_count,
|
||||
mocked_metrics_list.call_count)
|
||||
self.assertEqual(True, mocked_metrics_list.called)
|
||||
|
||||
def test_statistics_list_with_pagination(self):
|
||||
|
||||
statistics_list_pages = [[{u'dimensions': {},
|
||||
u'statistics': [
|
||||
[u'2015-04-14T17:52:31Z',
|
||||
1.0, 10.0],
|
||||
[u'2015-04-15T17:52:31Z',
|
||||
1.0, 10.0]],
|
||||
u'id': u'2015-04-14T18:42:31Z',
|
||||
u'columns': [u'timestamp', u'avg',
|
||||
u'max'],
|
||||
u'name': u'test1'}],
|
||||
[{u'dimensions': {},
|
||||
u'statistics': [
|
||||
[u'2015-04-16T17:52:31Z',
|
||||
2.0, 20.0],
|
||||
[u'2015-04-17T17:52:31Z',
|
||||
2.0, 20.0]],
|
||||
u'id': u'2015-04-15T18:42:31Z',
|
||||
u'columns': [u'timestamp', u'avg',
|
||||
u'max'],
|
||||
u'name': u'test2'}], None]
|
||||
|
||||
expected_page_count = len(statistics_list_pages)
|
||||
expected_metric_names = ["test1", "test2"]
|
||||
|
||||
self.CONF.set_override('enable_api_pagination',
|
||||
True, group='monasca')
|
||||
# get a new ceilosca mc
|
||||
mc = self._get_client()
|
||||
with mock.patch.object(
|
||||
mc._mon_client.metrics, 'list_statistics',
|
||||
side_effect=statistics_list_pages) as mocked_metrics_list:
|
||||
|
||||
returned_metrics = mc.statistics_list()
|
||||
returned_metric_names_list = [metric["name"]
|
||||
for metric in returned_metrics]
|
||||
self.assertListEqual(expected_metric_names,
|
||||
returned_metric_names_list)
|
||||
self.assertEqual(expected_page_count,
|
||||
mocked_metrics_list.call_count)
|
||||
self.assertEqual(True, mocked_metrics_list.called)
|
||||
|
||||
def test_statistics_list_without_pagination(self):
|
||||
|
||||
statistics_list_pages = [[{u'dimensions': {},
|
||||
u'statistics': [
|
||||
[u'2015-04-14T17:52:31Z',
|
||||
1.0, 10.0]],
|
||||
u'id': u'2015-04-14T18:42:31Z',
|
||||
u'columns': [u'timestamp', u'avg',
|
||||
u'max'],
|
||||
u'name': u'test1'}],
|
||||
[{u'dimensions': {},
|
||||
u'statistics': [
|
||||
[u'2015-04-15T17:52:31Z',
|
||||
2.0, 20.0]],
|
||||
u'id': u'2015-04-15T18:42:31Z',
|
||||
u'columns': [u'timestamp', u'avg',
|
||||
u'max'],
|
||||
u'name': u'test2'}], None]
|
||||
# first page only
|
||||
expected_page_count = 1
|
||||
expected_metric_names = ["test1"]
|
||||
|
||||
self.CONF.set_override('enable_api_pagination',
|
||||
False, group='monasca')
|
||||
# get a new ceilosca mc
|
||||
mc = self._get_client()
|
||||
with mock.patch.object(
|
||||
mc._mon_client.metrics, 'list_statistics',
|
||||
side_effect=statistics_list_pages) as mocked_metrics_list:
|
||||
returned_metrics = mc.statistics_list()
|
||||
returned_metric_names_list = [metric["name"]
|
||||
for metric in returned_metrics]
|
||||
self.assertListEqual(expected_metric_names,
|
||||
returned_metric_names_list)
|
||||
self.assertEqual(expected_page_count,
|
||||
mocked_metrics_list.call_count)
|
||||
self.assertEqual(True, mocked_metrics_list.called)
|
||||
|
|
|
@ -3,11 +3,14 @@
|
|||
There are a few options for configuring Ceilosca on top of a Ceilometer and Monasca deployment.
|
||||
|
||||
Choose one:
|
||||
- DevStack can be instructed through the local.conf to "enable ceilosca". Reference the included devstack/sample-local.conf for one configuration.
|
||||
- DevStack can be instructed through the local.conf to "enable ceilosca". Reference the included
|
||||
devstack/sample-local.conf for one example configuration.
|
||||
|
||||
- Use the included Vagrantfile to create and provision a VM. This will provision a new Ubuntu 16.04 VM and run the ceilosca.sh.
|
||||
- Use the included Vagrantfile to create and provision a VM. This will provision a new Ubuntu 16.04 VM and run the
|
||||
ceilosca.sh.
|
||||
|
||||
- Under certain conditions the monasca_test_setup.py may be used to set up Ceilosca for testing. This .py may also be useful reference if you choose to write your own integration scripts.
|
||||
- Under certain conditions the monasca_test_setup.py may be used to set up Ceilosca for testing. This .py may also be
|
||||
useful reference if you choose to write your own integration scripts.
|
||||
|
||||
- The devstack/ceilosca.sh script will copy Ceilosca components on top of Ceilometer.
|
||||
- ceilosca.sh has been updated to the Newton release.
|
||||
|
@ -15,5 +18,40 @@ Choose one:
|
|||
- The script should be tweaked before execution, particularly the lines.
|
||||
- export SERVICE_HOST=192.168.10.6
|
||||
- export HOST_IP_IFACE=eth0
|
||||
- The script should be run by a sudoers user with no password required. Such as is described in https://docs.openstack.org/devstack/latest/
|
||||
- And did not configure Horizon
|
||||
- The script should be run by a sudoers user with no password required. Such as is described in
|
||||
https://docs.openstack.org/devstack/latest/
|
||||
- And note ceilosca.sh does not configure Horizon
|
||||
|
||||
# Testing notes
|
||||
|
||||
Once Ceilosca is installed the gathered metrics will appear in Monasca. The `monasca` cli can be used to verify
|
||||
functionality.
|
||||
|
||||
- Source a valid rc file to set the OS_ environment variables needed for the cli. For example:
|
||||
```
|
||||
export OS_PROJECT_NAME=mini-mon
|
||||
export OS_IDENTITY_API_VERSION=3
|
||||
export OS_PASSWORD=<the password>
|
||||
export OS_AUTH_URL=http://<Your Keystone IP>/identity/v3/
|
||||
export OS_USERNAME=mini-mon
|
||||
```
|
||||
- Run `monasca metric-list`
|
||||
- Devstack includes a cirros 3.5 image by default. This will be represented in an `image.size` metric in monasca
|
||||
with a datasource of `ceilometer`.
|
||||
- Cause further metrics to be created by doing more OpenStack operations.
|
||||
- Create another image
|
||||
- wget -c http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img -o cirros-0.4.0-x86_64-disk.img
|
||||
- openstack image create --disk-format qcow2 --container-format bare cirros-0.4.0 < cirros-0.4.0-x86_64-disk.img
|
||||
- Create a simple vm
|
||||
- openstack image list
|
||||
- Choose one of the images listed, note its id
|
||||
- openstack flavor list
|
||||
- Choose one of the flavors, note its id
|
||||
- openstack project list
|
||||
- openstack security group list
|
||||
- Pick the group that matches the `admin` project, note its id
|
||||
- openstack security group rule create --proto tcp --dst-port 22 <security group id>
|
||||
- openstack server create --flavor <flavor id> --image <image id> --security-group <security group id> mytest
|
||||
- Check the progress with `openstack server list`
|
||||
- Look for additional metrics with `datasource: ceilometer` in `monasca metric-list`
|
||||
- Explore the samples (aka. measurements) in `monasca measurement-list image.size -120` and similar commands.
|
||||
|
|
|
@ -13,6 +13,15 @@ function configure_ceilosca {
|
|||
echo "In configure_ceilosca"
|
||||
sudo mkdir -p /etc/ceilometer
|
||||
sudo chown $CEILOSCA_USER /etc/ceilometer
|
||||
# back up Ceilometer's ceilometer.conf for reference
|
||||
if [[ -e /etc/ceilometer/ceilometer.conf ]]; then
|
||||
cp /etc/ceilometer/ceilometer.conf /etc/ceilometer/ceilometer.conf.preceilosca
|
||||
fi
|
||||
# back up existing pipeline.yaml
|
||||
if [[ -e /etc/ceilometer/pipeline.yaml ]]; then
|
||||
cp /etc/ceilometer/pipeline.yaml /etc/ceilometer/pipeline.yaml.preceilosca
|
||||
fi
|
||||
|
||||
for ceilosca_conf_file in $CEILOSCA_CONF_FILES
|
||||
do
|
||||
# source file and dest file names are separated with :
|
||||
|
@ -24,24 +33,48 @@ function configure_ceilosca {
|
|||
cp $CEILOSCA_DIR/etc/ceilometer/$source_file /etc/ceilometer/$dest_file
|
||||
done
|
||||
|
||||
iniset $CEILOMETER_CONF database metering_connection monasca://$MONASCA_API_URL
|
||||
# For reference, these ceilometer.conf options should be checked against
|
||||
# the current version and any updates made with each release.
|
||||
# https://docs.openstack.org/ceilometer/latest/configuration/
|
||||
|
||||
# [database] removed after Pike
|
||||
# iniset $CEILOMETER_CONF database metering_connection monasca://$MONASCA_API_URL
|
||||
iniset $CEILOMETER_CONF notification workers $API_WORKERS
|
||||
# TODO: workload_partitioning deprecated in Rocky
|
||||
iniset $CEILOMETER_CONF notification workload_partitioning False
|
||||
# Disable, otherwise Ceilosca won't process and store event data
|
||||
iniset $CEILOMETER_CONF notification disable_non_metric_meters False
|
||||
# iniset $CEILOMETER_CONF notification disable_non_metric_meters False
|
||||
|
||||
# Workaround: Client has a problem with the /identity auth url only in service_credentials
|
||||
auth_url=$(iniget $CEILOMETER_CONF service_credentials auth_url)
|
||||
if [[ -n "$auth_url" ]]; then
|
||||
# Go direct to the port
|
||||
auth_url=${auth_url/%\/identity/:35357\/v3}
|
||||
iniset $CEILOMETER_CONF service_credentials auth_url ${auth_url}
|
||||
fi
|
||||
#if [[ -n "$auth_url" ]]; then
|
||||
# # Go direct to the port
|
||||
# auth_url=${auth_url/%\/identity/:35357\/v3}
|
||||
# iniset $CEILOMETER_CONF service_credentials auth_url ${auth_url}
|
||||
#fi
|
||||
|
||||
# Add the [monasca] section and connection values
|
||||
iniset $CEILOMETER_CONF monasca service_auth_url ${auth_url}
|
||||
iniset $CEILOMETER_CONF monasca service_interface internalURL
|
||||
iniset $CEILOMETER_CONF monasca service_auth_type password
|
||||
|
||||
# default monasca user for devstack (check monasca-api/devstack/plugin.sh)
|
||||
iniset $CEILOMETER_CONF monasca service_username mini-mon
|
||||
iniset $CEILOMETER_CONF monasca service_password password
|
||||
iniset $CEILOMETER_CONF monasca service_project_name mini-mon
|
||||
iniset $CEILOMETER_CONF monasca service_domain_name Default
|
||||
iniset $CEILOMETER_CONF monasca service_region_name RegionOne
|
||||
|
||||
# leave the defaults for retry_on_failure, retry_interval,
|
||||
# enable_api_pagination, database_retry_interval, database_max_retries
|
||||
|
||||
# Fill in Monasca URL in pipeline.yaml
|
||||
sed -i "s,monasca://INSERT-URL-HERE,monasca://${MONASCA_API_URL},g" /etc/ceilometer/pipeline.yaml
|
||||
}
|
||||
|
||||
function preinstall_ceilosca {
|
||||
# create new directory
|
||||
cp -r $CEILOSCA_DIR/ceilosca/ceilometer/ceilosca_mapping $CEILOMETER_DIR/ceilometer/
|
||||
# create new directory --- removed in Rocky
|
||||
# cp -r $CEILOSCA_DIR/ceilosca/ceilometer/ceilosca_mapping $CEILOMETER_DIR/ceilometer/
|
||||
|
||||
# overlay files into existing dirs
|
||||
for ceilosca_file in $CEILOSCA_FILES
|
||||
|
@ -59,7 +92,6 @@ function preinstall_ceilosca {
|
|||
if ! grep -q "python-monascaclient" $CEILOMETER_DIR/requirements.txt; then
|
||||
sudo bash -c "echo python-monascaclient >> $CEILOMETER_DIR/requirements.txt"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
# check for service enabled
|
||||
|
|
|
@ -24,6 +24,7 @@ MONASCA_PERSISTER_IMPLEMENTATION_LANG=${MONASCA_PERSISTER_IMPLEMENTATION_LANG:-p
|
|||
|
||||
# Uncomment one of the following two lines to choose either InfluxDB or Vertica.
|
||||
MONASCA_METRICS_DB=${MONASCA_METRICS_DB:-influxdb}
|
||||
# MONASCA_METRICS_DB=${MONASCA_METRICS_DB:-cassandra}
|
||||
# MONASCA_METRICS_DB=${MONASCA_METRICS_DB:-vertica}
|
||||
|
||||
# Monasca services to enable
|
||||
|
@ -38,7 +39,7 @@ enable_service monasca-agent
|
|||
enable_service monasca-cli
|
||||
|
||||
# This line will enable all of Monasca.
|
||||
enable_plugin monasca-api git://git.openstack.org/openstack/monasca-api stable/newton
|
||||
enable_plugin monasca-api git://git.openstack.org/openstack/monasca-api stable/rocky
|
||||
|
||||
# the following may be disabled to leave monasca transform still functional
|
||||
#disable_service monasca-persister
|
||||
|
@ -49,13 +50,12 @@ disable_service horizon
|
|||
#disable_service cinder
|
||||
disable_service monasca-smoke-test
|
||||
|
||||
# NO stable/newton branch for monasca-transform
|
||||
enable_plugin monasca-transform https://git.openstack.org/openstack/monasca-transform master
|
||||
|
||||
# USING UPSTREAM master ceilosca but newton everything else
|
||||
enable_plugin ceilometer https://git.openstack.org/openstack/ceilometer stable/newton
|
||||
enable_plugin ceilosca https://git.openstack.org/openstack/monasca-ceilometer master
|
||||
# Another good Monasca service that isn't installed by monasca-api automatically
|
||||
enable_plugin monasca-transform https://git.openstack.org/openstack/monasca-transform stable/rocky
|
||||
|
||||
# Be sure that Ceilometer is installed before Ceilosca (monasca-ceilometer repo is not stand-alone installable)
|
||||
enable_plugin ceilometer https://git.openstack.org/openstack/ceilometer stable/rocky
|
||||
enable_plugin ceilosca https://git.openstack.org/openstack/monasca-ceilometer stable/rocky
|
||||
|
||||
enable_service ceilosca
|
||||
|
||||
|
|
|
@ -4,8 +4,11 @@ source $DEST/ceilometer/devstack/settings
|
|||
|
||||
enable_service ceilosca
|
||||
|
||||
MONASCA_API_URL=http://$SERVICE_HOST:8070/v2.0
|
||||
# Should be getting the same value as in the Keystone endpoint list!
|
||||
# Note: to clarify, Monasca is at /metrics/v2.0, Gnocchi is at /metric (no s)
|
||||
MONASCA_API_URL=http://$SERVICE_HOST/metrics/v2.0
|
||||
|
||||
CEILOSCA_DIR=$DEST/ceilosca
|
||||
CEILOSCA_FILES='ceilometer/monasca_client.py ceilometer/publisher/monasca_data_filter.py ceilometer/publisher/monclient.py ceilometer/storage/impl_monasca.py ../devstack/setup.cfg:.'
|
||||
CEILOSCA_FILES='ceilometer/monasca_client.py ceilometer/publisher/monasca_data_filter.py ceilometer/publisher/monasca.py ceilometer/opts.py ceilometer/monasca_opts.py ../devstack/setup.cfg:.'
|
||||
CEILOSCA_CONF_FILES='ceilosca_pipeline.yaml:pipeline.yaml monasca_field_definitions.yaml'
|
||||
CEILOSCA_USER=$USER
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
[metadata]
|
||||
name = ceilometer
|
||||
url = http://launchpad.net/ceilometer
|
||||
summary = OpenStack Telemetry
|
||||
description-file =
|
||||
README.rst
|
||||
|
@ -15,6 +16,8 @@ classifier =
|
|||
Programming Language :: Python
|
||||
Programming Language :: Python :: 2
|
||||
Programming Language :: Python :: 2.7
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3.5
|
||||
Topic :: System :: Monitoring
|
||||
|
||||
[global]
|
||||
|
@ -24,41 +27,39 @@ setup-hooks =
|
|||
[files]
|
||||
packages =
|
||||
ceilometer
|
||||
data_files =
|
||||
etc/ceilometer = etc/ceilometer/*
|
||||
|
||||
[extras]
|
||||
gnocchi =
|
||||
oslo.cache>=1.5.0 # Apache-2.0
|
||||
gnocchiclient>=7.0.0 # Apache-2.0
|
||||
zaqar =
|
||||
python-zaqarclient>=1.0.0 # Apache-2.0
|
||||
monasca =
|
||||
python-monascaclient>=1.7.0 # Apache-2.0
|
||||
|
||||
[entry_points]
|
||||
ceilometer.notification =
|
||||
instance = ceilometer.compute.notifications.instance:Instance
|
||||
instance_scheduled = ceilometer.compute.notifications.instance:InstanceScheduled
|
||||
network = ceilometer.network.notifications:Network
|
||||
subnet = ceilometer.network.notifications:Subnet
|
||||
port = ceilometer.network.notifications:Port
|
||||
router = ceilometer.network.notifications:Router
|
||||
floatingip = ceilometer.network.notifications:FloatingIP
|
||||
ceilometer.notification.pipeline =
|
||||
meter = ceilometer.pipeline.sample:SamplePipelineManager
|
||||
event = ceilometer.pipeline.event:EventPipelineManager
|
||||
|
||||
ceilometer.sample.endpoint =
|
||||
http.request = ceilometer.middleware:HTTPRequest
|
||||
http.response = ceilometer.middleware:HTTPResponse
|
||||
hardware.ipmi.temperature = ceilometer.ipmi.notifications.ironic:TemperatureSensorNotification
|
||||
hardware.ipmi.voltage = ceilometer.ipmi.notifications.ironic:VoltageSensorNotification
|
||||
hardware.ipmi.current = ceilometer.ipmi.notifications.ironic:CurrentSensorNotification
|
||||
hardware.ipmi.fan = ceilometer.ipmi.notifications.ironic:FanSensorNotification
|
||||
network.services.lb.pool = ceilometer.network.notifications:Pool
|
||||
network.services.lb.vip = ceilometer.network.notifications:Vip
|
||||
network.services.lb.member = ceilometer.network.notifications:Member
|
||||
network.services.lb.health_monitor = ceilometer.network.notifications:HealthMonitor
|
||||
network.services.firewall = ceilometer.network.notifications:Firewall
|
||||
network.services.firewall.policy = ceilometer.network.notifications:FirewallPolicy
|
||||
network.services.firewall.rule = ceilometer.network.notifications:FirewallRule
|
||||
network.services.vpn = ceilometer.network.notifications:VPNService
|
||||
network.services.vpn.ipsecpolicy = ceilometer.network.notifications:IPSecPolicy
|
||||
network.services.vpn.ikepolicy = ceilometer.network.notifications:IKEPolicy
|
||||
network.services.vpn.connections = ceilometer.network.notifications:IPSecSiteConnection
|
||||
_sample = ceilometer.telemetry.notifications:TelemetryIpc
|
||||
meter = ceilometer.meter.notifications:ProcessMeterNotifications
|
||||
|
||||
ceilometer.discover =
|
||||
ceilometer.discover.compute =
|
||||
local_instances = ceilometer.compute.discovery:InstanceDiscovery
|
||||
endpoint = ceilometer.agent.discovery.endpoint:EndpointDiscovery
|
||||
tenant = ceilometer.agent.discovery.tenant:TenantDiscovery
|
||||
local_node = ceilometer.agent.discovery.localnode:LocalNodeDiscovery
|
||||
|
||||
ceilometer.discover.central =
|
||||
endpoint = ceilometer.polling.discovery.endpoint:EndpointDiscovery
|
||||
tenant = ceilometer.polling.discovery.tenant:TenantDiscovery
|
||||
lb_pools = ceilometer.network.services.discovery:LBPoolsDiscovery
|
||||
lb_vips = ceilometer.network.services.discovery:LBVipsDiscovery
|
||||
lb_members = ceilometer.network.services.discovery:LBMembersDiscovery
|
||||
|
@ -70,6 +71,14 @@ ceilometer.discover =
|
|||
fw_services = ceilometer.network.services.discovery:FirewallDiscovery
|
||||
fw_policy = ceilometer.network.services.discovery:FirewallPolicyDiscovery
|
||||
tripleo_overcloud_nodes = ceilometer.hardware.discovery:NodesDiscoveryTripleO
|
||||
fip_services = ceilometer.network.services.discovery:FloatingIPDiscovery
|
||||
images = ceilometer.image.discovery:ImagesDiscovery
|
||||
volumes = ceilometer.volume.discovery:VolumeDiscovery
|
||||
volume_snapshots = ceilometer.volume.discovery:VolumeSnapshotsDiscovery
|
||||
volume_backups = ceilometer.volume.discovery:VolumeBackupsDiscovery
|
||||
|
||||
ceilometer.discover.ipmi =
|
||||
local_node = ceilometer.polling.discovery.localnode:LocalNodeDiscovery
|
||||
|
||||
ceilometer.poll.compute =
|
||||
disk.read.requests = ceilometer.compute.pollsters.disk:ReadRequestsPollster
|
||||
|
@ -88,27 +97,41 @@ ceilometer.poll.compute =
|
|||
disk.device.write.requests.rate = ceilometer.compute.pollsters.disk:PerDeviceWriteRequestsRatePollster
|
||||
disk.device.read.bytes.rate = ceilometer.compute.pollsters.disk:PerDeviceReadBytesRatePollster
|
||||
disk.device.write.bytes.rate = ceilometer.compute.pollsters.disk:PerDeviceWriteBytesRatePollster
|
||||
disk.device.read.latency = ceilometer.compute.pollsters.disk:PerDeviceDiskReadLatencyPollster
|
||||
disk.device.write.latency = ceilometer.compute.pollsters.disk:PerDeviceDiskWriteLatencyPollster
|
||||
disk.latency = ceilometer.compute.pollsters.disk:DiskLatencyPollster
|
||||
disk.device.latency = ceilometer.compute.pollsters.disk:PerDeviceDiskLatencyPollster
|
||||
disk.iops = ceilometer.compute.pollsters.disk:DiskIOPSPollster
|
||||
disk.device.iops = ceilometer.compute.pollsters.disk:PerDeviceDiskIOPSPollster
|
||||
cpu = ceilometer.compute.pollsters.cpu:CPUPollster
|
||||
cpu_util = ceilometer.compute.pollsters.cpu:CPUUtilPollster
|
||||
cpu = ceilometer.compute.pollsters.instance_stats:CPUPollster
|
||||
cpu_util = ceilometer.compute.pollsters.instance_stats:CPUUtilPollster
|
||||
cpu_l3_cache = ceilometer.compute.pollsters.instance_stats:CPUL3CachePollster
|
||||
network.incoming.bytes = ceilometer.compute.pollsters.net:IncomingBytesPollster
|
||||
network.incoming.packets = ceilometer.compute.pollsters.net:IncomingPacketsPollster
|
||||
network.outgoing.bytes = ceilometer.compute.pollsters.net:OutgoingBytesPollster
|
||||
network.outgoing.packets = ceilometer.compute.pollsters.net:OutgoingPacketsPollster
|
||||
network.incoming.bytes.rate = ceilometer.compute.pollsters.net:IncomingBytesRatePollster
|
||||
network.outgoing.bytes.rate = ceilometer.compute.pollsters.net:OutgoingBytesRatePollster
|
||||
instance = ceilometer.compute.pollsters.instance:InstancePollster
|
||||
memory.usage = ceilometer.compute.pollsters.memory:MemoryUsagePollster
|
||||
memory.resident = ceilometer.compute.pollsters.memory:MemoryResidentPollster
|
||||
network.incoming.packets.drop = ceilometer.compute.pollsters.net:IncomingDropPollster
|
||||
network.outgoing.packets.drop = ceilometer.compute.pollsters.net:OutgoingDropPollster
|
||||
network.incoming.packets.error = ceilometer.compute.pollsters.net:IncomingErrorsPollster
|
||||
network.outgoing.packets.error = ceilometer.compute.pollsters.net:OutgoingErrorsPollster
|
||||
memory.usage = ceilometer.compute.pollsters.instance_stats:MemoryUsagePollster
|
||||
memory.resident = ceilometer.compute.pollsters.instance_stats:MemoryResidentPollster
|
||||
memory.swap.in = ceilometer.compute.pollsters.instance_stats:MemorySwapInPollster
|
||||
memory.swap.out = ceilometer.compute.pollsters.instance_stats:MemorySwapOutPollster
|
||||
memory.bandwidth.total = ceilometer.compute.pollsters.instance_stats:MemoryBandwidthTotalPollster
|
||||
memory.bandwidth.local = ceilometer.compute.pollsters.instance_stats:MemoryBandwidthLocalPollster
|
||||
disk.capacity = ceilometer.compute.pollsters.disk:CapacityPollster
|
||||
disk.allocation = ceilometer.compute.pollsters.disk:AllocationPollster
|
||||
disk.usage = ceilometer.compute.pollsters.disk:PhysicalPollster
|
||||
disk.device.capacity = ceilometer.compute.pollsters.disk:PerDeviceCapacityPollster
|
||||
disk.device.allocation = ceilometer.compute.pollsters.disk:PerDeviceAllocationPollster
|
||||
disk.device.usage = ceilometer.compute.pollsters.disk:PerDevicePhysicalPollster
|
||||
perf.cpu.cycles = ceilometer.compute.pollsters.instance_stats:PerfCPUCyclesPollster
|
||||
perf.instructions = ceilometer.compute.pollsters.instance_stats:PerfInstructionsPollster
|
||||
perf.cache.references = ceilometer.compute.pollsters.instance_stats:PerfCacheReferencesPollster
|
||||
perf.cache.misses = ceilometer.compute.pollsters.instance_stats:PerfCacheMissesPollster
|
||||
|
||||
ceilometer.poll.ipmi =
|
||||
hardware.ipmi.node.power = ceilometer.ipmi.pollsters.node:PowerPollster
|
||||
|
@ -126,22 +149,28 @@ ceilometer.poll.ipmi =
|
|||
|
||||
ceilometer.poll.central =
|
||||
ip.floating = ceilometer.network.floatingip:FloatingIPPollster
|
||||
image = ceilometer.image.glance:ImagePollster
|
||||
image.size = ceilometer.image.glance:ImageSizePollster
|
||||
rgw.containers.objects = ceilometer.objectstore.rgw:ContainersObjectsPollster
|
||||
rgw.containers.objects.size = ceilometer.objectstore.rgw:ContainersSizePollster
|
||||
rgw.objects = ceilometer.objectstore.rgw:ObjectsPollster
|
||||
rgw.objects.size = ceilometer.objectstore.rgw:ObjectsSizePollster
|
||||
rgw.objects.containers = ceilometer.objectstore.rgw:ObjectsContainersPollster
|
||||
rgw.usage = ceilometer.objectstore.rgw:UsagePollster
|
||||
port = ceilometer.network.statistics.port_v2:PortPollster
|
||||
port.uptime = ceilometer.network.statistics.port_v2:PortPollsterUptime
|
||||
port.receive.packets = ceilometer.network.statistics.port_v2:PortPollsterReceivePackets
|
||||
port.transmit.packets = ceilometer.network.statistics.port_v2:PortPollsterTransmitPackets
|
||||
port.receive.bytes = ceilometer.network.statistics.port_v2:PortPollsterReceiveBytes
|
||||
port.transmit.bytes = ceilometer.network.statistics.port_v2:PortPollsterTransmitBytes
|
||||
port.receive.drops = ceilometer.network.statistics.port_v2:PortPollsterReceiveDrops
|
||||
port.receive.errors = ceilometer.network.statistics.port_v2:PortPollsterReceiveErrors
|
||||
radosgw.containers.objects = ceilometer.objectstore.rgw:ContainersObjectsPollster
|
||||
radosgw.containers.objects.size = ceilometer.objectstore.rgw:ContainersSizePollster
|
||||
radosgw.objects = ceilometer.objectstore.rgw:ObjectsPollster
|
||||
radosgw.objects.size = ceilometer.objectstore.rgw:ObjectsSizePollster
|
||||
radosgw.objects.containers = ceilometer.objectstore.rgw:ObjectsContainersPollster
|
||||
radosgw.usage = ceilometer.objectstore.rgw:UsagePollster
|
||||
storage.containers.objects = ceilometer.objectstore.swift:ContainersObjectsPollster
|
||||
storage.containers.objects.size = ceilometer.objectstore.swift:ContainersSizePollster
|
||||
storage.objects = ceilometer.objectstore.swift:ObjectsPollster
|
||||
storage.objects.size = ceilometer.objectstore.swift:ObjectsSizePollster
|
||||
storage.objects.containers = ceilometer.objectstore.swift:ObjectsContainersPollster
|
||||
energy = ceilometer.energy.kwapi:EnergyPollster
|
||||
power = ceilometer.energy.kwapi:PowerPollster
|
||||
switch.port = ceilometer.network.statistics.port:PortPollster
|
||||
switch.port.uptime = ceilometer.network.statistics.port:PortPollsterUptime
|
||||
switch.port.receive.packets = ceilometer.network.statistics.port:PortPollsterReceivePackets
|
||||
switch.port.transmit.packets = ceilometer.network.statistics.port:PortPollsterTransmitPackets
|
||||
switch.port.receive.bytes = ceilometer.network.statistics.port:PortPollsterReceiveBytes
|
||||
|
@ -159,6 +188,7 @@ ceilometer.poll.central =
|
|||
switch.table.lookup.packets = ceilometer.network.statistics.table:TablePollsterLookupPackets
|
||||
switch.table.matched.packets = ceilometer.network.statistics.table:TablePollsterMatchedPackets
|
||||
switch = ceilometer.network.statistics.switch:SWPollster
|
||||
switch.ports = ceilometer.network.statistics.switch:SwitchPollsterPorts
|
||||
switch.flow = ceilometer.network.statistics.flow:FlowPollster
|
||||
switch.flow.bytes = ceilometer.network.statistics.flow:FlowPollsterBytes
|
||||
switch.flow.duration.nanoseconds = ceilometer.network.statistics.flow:FlowPollsterDurationNanoseconds
|
||||
|
@ -178,30 +208,13 @@ ceilometer.poll.central =
|
|||
network.services.vpn.connections = ceilometer.network.services.vpnaas:IPSecConnectionsPollster
|
||||
network.services.firewall = ceilometer.network.services.fwaas:FirewallPollster
|
||||
network.services.firewall.policy = ceilometer.network.services.fwaas:FirewallPolicyPollster
|
||||
volume.size = ceilometer.volume.cinder:VolumeSizePollster
|
||||
volume.snapshot.size = ceilometer.volume.cinder:VolumeSnapshotSize
|
||||
volume.backup.size = ceilometer.volume.cinder:VolumeBackupSize
|
||||
|
||||
ceilometer.builder.poll.central =
|
||||
hardware.snmp = ceilometer.hardware.pollsters.generic:GenericHardwareDeclarativePollster
|
||||
|
||||
ceilometer.event.storage =
|
||||
es = ceilometer.event.storage.impl_elasticsearch:Connection
|
||||
log = ceilometer.event.storage.impl_log:Connection
|
||||
mongodb = ceilometer.event.storage.impl_mongodb:Connection
|
||||
mysql = ceilometer.event.storage.impl_sqlalchemy:Connection
|
||||
postgresql = ceilometer.event.storage.impl_sqlalchemy:Connection
|
||||
sqlite = ceilometer.event.storage.impl_sqlalchemy:Connection
|
||||
hbase = ceilometer.event.storage.impl_hbase:Connection
|
||||
db2 = ceilometer.event.storage.impl_db2:Connection
|
||||
|
||||
ceilometer.metering.storage =
|
||||
log = ceilometer.storage.impl_log:Connection
|
||||
mongodb = ceilometer.storage.impl_mongodb:Connection
|
||||
mysql = ceilometer.storage.impl_sqlalchemy:Connection
|
||||
postgresql = ceilometer.storage.impl_sqlalchemy:Connection
|
||||
sqlite = ceilometer.storage.impl_sqlalchemy:Connection
|
||||
hbase = ceilometer.storage.impl_hbase:Connection
|
||||
db2 = ceilometer.storage.impl_db2:Connection
|
||||
monasca = ceilometer.storage.impl_monasca:Connection
|
||||
|
||||
ceilometer.compute.virt =
|
||||
libvirt = ceilometer.compute.virt.libvirt.inspector:LibvirtInspector
|
||||
hyperv = ceilometer.compute.virt.hyperv.inspector:HyperVInspector
|
||||
|
@ -219,47 +232,37 @@ ceilometer.transformer =
|
|||
aggregator = ceilometer.transformer.conversions:AggregatorTransformer
|
||||
arithmetic = ceilometer.transformer.arithmetic:ArithmeticTransformer
|
||||
|
||||
ceilometer.publisher =
|
||||
ceilometer.sample.publisher =
|
||||
test = ceilometer.publisher.test:TestPublisher
|
||||
notifier = ceilometer.publisher.messaging:SampleNotifierPublisher
|
||||
udp = ceilometer.publisher.udp:UDPPublisher
|
||||
file = ceilometer.publisher.file:FilePublisher
|
||||
direct = ceilometer.publisher.direct:DirectPublisher
|
||||
kafka = ceilometer.publisher.kafka_broker:KafkaBrokerPublisher
|
||||
monasca = ceilometer.publisher.monclient:MonascaPublisher
|
||||
http = ceilometer.publisher.http:HttpPublisher
|
||||
prometheus = ceilometer.publisher.prometheus:PrometheusPublisher
|
||||
https = ceilometer.publisher.http:HttpPublisher
|
||||
monasca = ceilometer.publisher.monasca:MonascaPublisher
|
||||
gnocchi = ceilometer.publisher.gnocchi:GnocchiPublisher
|
||||
zaqar = ceilometer.publisher.zaqar:ZaqarPublisher
|
||||
|
||||
ceilometer.event.publisher =
|
||||
test = ceilometer.publisher.test:TestPublisher
|
||||
direct = ceilometer.publisher.direct:DirectPublisher
|
||||
notifier = ceilometer.publisher.messaging:EventNotifierPublisher
|
||||
kafka = ceilometer.publisher.kafka_broker:KafkaBrokerPublisher
|
||||
http = ceilometer.publisher.http:HttpPublisher
|
||||
https = ceilometer.publisher.http:HttpPublisher
|
||||
gnocchi = ceilometer.publisher.gnocchi:GnocchiPublisher
|
||||
zaqar = ceilometer.publisher.zaqar:ZaqarPublisher
|
||||
|
||||
ceilometer.event.trait_plugin =
|
||||
split = ceilometer.event.trait_plugins:SplitterTraitPlugin
|
||||
bitfield = ceilometer.event.trait_plugins:BitfieldTraitPlugin
|
||||
timedelta = ceilometer.event.trait_plugins:TimedeltaPlugin
|
||||
|
||||
|
||||
console_scripts =
|
||||
ceilometer-api = ceilometer.cmd.api:main
|
||||
ceilometer-polling = ceilometer.cmd.polling:main
|
||||
ceilometer-agent-notification = ceilometer.cmd.agent_notification:main
|
||||
ceilometer-send-sample = ceilometer.cmd.sample:send_sample
|
||||
ceilometer-dbsync = ceilometer.cmd.storage:dbsync
|
||||
ceilometer-expirer = ceilometer.cmd.storage:expirer
|
||||
ceilometer-upgrade = ceilometer.cmd.storage:upgrade
|
||||
ceilometer-rootwrap = oslo_rootwrap.cmd:main
|
||||
ceilometer-collector = ceilometer.cmd.collector:main
|
||||
|
||||
ceilometer.dispatcher.meter =
|
||||
database = ceilometer.dispatcher.database:DatabaseDispatcher
|
||||
file = ceilometer.dispatcher.file:FileDispatcher
|
||||
http = ceilometer.dispatcher.http:HttpDispatcher
|
||||
gnocchi = ceilometer.dispatcher.gnocchi:GnocchiDispatcher
|
||||
|
||||
ceilometer.dispatcher.event =
|
||||
database = ceilometer.dispatcher.database:DatabaseDispatcher
|
||||
file = ceilometer.dispatcher.file:FileDispatcher
|
||||
http = ceilometer.dispatcher.http:HttpDispatcher
|
||||
|
||||
network.statistics.drivers =
|
||||
opendaylight = ceilometer.network.statistics.opendaylight.driver:OpenDayLightDriver
|
||||
|
@ -267,15 +270,7 @@ network.statistics.drivers =
|
|||
|
||||
oslo.config.opts =
|
||||
ceilometer = ceilometer.opts:list_opts
|
||||
|
||||
oslo.config.opts.defaults =
|
||||
ceilometer = ceilometer.conf.defaults:set_cors_middleware_defaults
|
||||
|
||||
keystoneauth1.plugin =
|
||||
password-ceilometer-legacy = ceilometer.keystone_client:LegacyCeilometerKeystoneLoader
|
||||
|
||||
tempest.test_plugins =
|
||||
ceilometer_tests = ceilometer.tests.tempest.plugin:CeilometerTempestPlugin
|
||||
ceilometer-auth = ceilometer.opts:list_keystoneauth_opts
|
||||
|
||||
[build_sphinx]
|
||||
all_files = 1
|
||||
|
|
|
@ -19,4 +19,4 @@ sinks:
|
|||
- name: meter_sink
|
||||
transformers:
|
||||
publishers:
|
||||
- monasca://http://192.168.10.6:8070/v2.0
|
||||
- monasca://INSERT-URL-HERE
|
|
@ -23,9 +23,9 @@ ceilosca_files = {
|
|||
for file in
|
||||
[
|
||||
'monasca_client.py',
|
||||
'monasca_ceilometer_opts.py',
|
||||
'monasca_opts.py',
|
||||
'publisher/monasca_data_filter.py',
|
||||
'publisher/monclient.py'
|
||||
'publisher/monasca.py'
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -34,11 +34,6 @@ ceilosca_files = {
|
|||
for src, dest in ceilosca_files.items():
|
||||
shutil.copyfile(src, dest)
|
||||
|
||||
# Include new module
|
||||
shutil.rmtree(ceilo_dir + "/ceilosca_mapping/", True)
|
||||
shutil.copytree('ceilosca/ceilometer/ceilosca_mapping',
|
||||
ceilo_dir + "/ceilosca_mapping/")
|
||||
|
||||
ceilo_parent_dir = os.path.dirname(os.path.abspath(
|
||||
os.path.dirname(ceilometer.__file__)))
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
git+https://github.com/openstack/ceilometer.git@master#egg=ceilometer
|
||||
mock>=1.2
|
||||
testscenarios>=0.4
|
||||
testtools>=1.4.0
|
||||
mock>=1.2 # BSD
|
||||
testscenarios>=0.4 # Apache-2.0/BSD
|
||||
testtools>=1.4.0 # MIT
|
||||
oslotest>=2.15.0 # Apache-2.0
|
||||
oslo.vmware>=1.16.0,<2.17.0 # Apache-2.0
|
||||
# Use lower versions of config and utils since
|
||||
|
@ -9,6 +9,6 @@ oslo.vmware>=1.16.0,<2.17.0 # Apache-2.0
|
|||
oslo.config>=3.22.0 # Apache-2.0
|
||||
oslo.log>=1.14.0 # Apache-2.0
|
||||
os-testr>=1.0.0 # Apache-2.0
|
||||
python-monascaclient<=1.7.1
|
||||
python-monascaclient<=1.12.0 # Apache-2.0
|
||||
docutils>=0.11 # OSI-Approved Open Source, Public Domain
|
||||
hacking<0.11,>=0.10.0
|
||||
|
|
Loading…
Reference in New Issue