Merge "Declarative meters support"
This commit is contained in:
commit
9a67d602b3
@ -93,8 +93,9 @@ class NotificationBase(PluginBase):
|
||||
super(NotificationBase, self).__init__()
|
||||
# NOTE(gordc): this is filter rule used by oslo.messaging to dispatch
|
||||
# messages to an endpoint.
|
||||
self.filter_rule = oslo_messaging.NotificationFilter(
|
||||
event_type='|'.join(self.event_types))
|
||||
if self.event_types is not None:
|
||||
self.filter_rule = oslo_messaging.NotificationFilter(
|
||||
event_type='|'.join(self.event_types))
|
||||
self.manager = manager
|
||||
|
||||
@abc.abstractproperty
|
||||
|
0
ceilometer/meter/__init__.py
Normal file
0
ceilometer/meter/__init__.py
Normal file
204
ceilometer/meter/notifications.py
Normal file
204
ceilometer/meter/notifications.py
Normal file
@ -0,0 +1,204 @@
|
||||
#
|
||||
# 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.
|
||||
|
||||
import fnmatch
|
||||
import os
|
||||
import six
|
||||
import yaml
|
||||
|
||||
import jsonpath_rw
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
import oslo_messaging
|
||||
|
||||
from ceilometer.agent import plugin_base
|
||||
from ceilometer.i18n import _LE
|
||||
from ceilometer import sample
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt('meter_definitions_cfg_file',
|
||||
default="meters.yaml",
|
||||
help="Configuration file for defining meter notifications."
|
||||
),
|
||||
]
|
||||
|
||||
cfg.CONF.register_opts(OPTS, group='meter')
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class MeterDefinitionException(Exception):
|
||||
def __init__(self, message, definition_cfg):
|
||||
super(MeterDefinitionException, self).__init__(message)
|
||||
self.definition_cfg = definition_cfg
|
||||
|
||||
def __str__(self):
|
||||
return '%s %s: %s' % (self.__class__.__name__,
|
||||
self.definition_cfg, self.message)
|
||||
|
||||
|
||||
class MeterDefinition(object):
|
||||
|
||||
def __init__(self, definition_cfg):
|
||||
self.cfg = definition_cfg
|
||||
self._validate_type()
|
||||
|
||||
def match_type(self, meter_name):
|
||||
try:
|
||||
event_type = self.cfg['event_type']
|
||||
except KeyError as err:
|
||||
raise MeterDefinitionException(
|
||||
_LE("Required field %s not specified") % err.args[0], self.cfg)
|
||||
|
||||
if isinstance(event_type, six.string_types):
|
||||
event_type = [event_type]
|
||||
for t in event_type:
|
||||
if fnmatch.fnmatch(meter_name, t):
|
||||
return True
|
||||
|
||||
def parse_fields(self, field, message):
|
||||
fval = self.cfg.get(field)
|
||||
if not fval:
|
||||
return
|
||||
if isinstance(fval, six.integer_types):
|
||||
return fval
|
||||
try:
|
||||
parts = jsonpath_rw.parse(fval)
|
||||
except Exception as e:
|
||||
raise MeterDefinitionException(
|
||||
_LE("Parse error in JSONPath specification "
|
||||
"'%(jsonpath)s': %(err)s")
|
||||
% dict(jsonpath=parts, err=e), self.cfg)
|
||||
values = [match.value for match in parts.find(message)
|
||||
if match.value is not None]
|
||||
if values:
|
||||
return values[0]
|
||||
|
||||
def _validate_type(self):
|
||||
if self.cfg['type'] not in sample.TYPES:
|
||||
raise MeterDefinitionException(
|
||||
_LE("Invalid type %s specified") % self.cfg['type'], self.cfg)
|
||||
|
||||
|
||||
def get_config_file():
|
||||
config_file = cfg.CONF.meter.meter_definitions_cfg_file
|
||||
if not os.path.exists(config_file):
|
||||
config_file = cfg.CONF.find_file(config_file)
|
||||
return config_file
|
||||
|
||||
|
||||
def setup_meters_config():
|
||||
"""Setup the meters definitions from yaml config file."""
|
||||
config_file = get_config_file()
|
||||
if config_file is not None:
|
||||
LOG.debug(_LE("Meter Definitions configuration file: %s"), config_file)
|
||||
|
||||
with open(config_file) as cf:
|
||||
config = cf.read()
|
||||
|
||||
try:
|
||||
meters_config = yaml.safe_load(config)
|
||||
except yaml.YAMLError as err:
|
||||
if hasattr(err, 'problem_mark'):
|
||||
mark = err.problem_mark
|
||||
errmsg = (_LE("Invalid YAML syntax in Meter 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 = (_LE("YAML error reading Meter Definitions file "
|
||||
"%(file)s")
|
||||
% dict(file=config_file))
|
||||
LOG.error(errmsg)
|
||||
raise
|
||||
|
||||
else:
|
||||
LOG.debug(_LE("No Meter Definitions configuration file found!"
|
||||
" Using default config."))
|
||||
meters_config = []
|
||||
|
||||
LOG.info(_LE("Meter Definitions: %s"), meters_config)
|
||||
|
||||
return meters_config
|
||||
|
||||
|
||||
def load_definitions(config_def):
|
||||
return [MeterDefinition(event_def)
|
||||
for event_def in reversed(config_def['metric'])]
|
||||
|
||||
|
||||
class ProcessMeterNotifications(plugin_base.NotificationBase):
|
||||
|
||||
event_types = None
|
||||
|
||||
def __init__(self, manager):
|
||||
super(ProcessMeterNotifications, self).__init__(manager)
|
||||
self.definitions = load_definitions(setup_meters_config())
|
||||
|
||||
def get_targets(self, conf):
|
||||
"""Return a sequence of oslo_messaging.Target
|
||||
|
||||
It is defining the exchange and topics to be connected for this plugin.
|
||||
:param conf: Configuration.
|
||||
#TODO(prad): This should be defined in the notification agent
|
||||
"""
|
||||
targets = []
|
||||
exchanges = [
|
||||
conf.nova_control_exchange,
|
||||
conf.cinder_control_exchange,
|
||||
conf.glance_control_exchange,
|
||||
conf.neutron_control_exchange,
|
||||
conf.heat_control_exchange,
|
||||
conf.keystone_control_exchange,
|
||||
conf.sahara_control_exchange,
|
||||
conf.trove_control_exchange,
|
||||
conf.zaqar_control_exchange,
|
||||
conf.swift_control_exchange,
|
||||
conf.magnetodb_control_exchange,
|
||||
conf.ceilometer_control_exchange,
|
||||
]
|
||||
|
||||
for exchange in exchanges:
|
||||
targets.extend(oslo_messaging.Target(topic=topic,
|
||||
exchange=exchange)
|
||||
for topic in conf.notification_topics)
|
||||
return targets
|
||||
|
||||
def process_notification(self, notification_body):
|
||||
for d in self.definitions:
|
||||
if d.match_type(notification_body['event_type']):
|
||||
userid = self.get_user_id(d, notification_body)
|
||||
projectid = self.get_project_id(d, notification_body)
|
||||
resourceid = d.parse_fields('resource_id', notification_body)
|
||||
yield sample.Sample.from_notification(
|
||||
name=d.cfg['name'],
|
||||
type=d.cfg['type'],
|
||||
unit=d.cfg['unit'],
|
||||
volume=d.parse_fields('volume', notification_body),
|
||||
resource_id=resourceid,
|
||||
user_id=userid,
|
||||
project_id=projectid,
|
||||
message=notification_body)
|
||||
|
||||
@staticmethod
|
||||
def get_user_id(d, notification_body):
|
||||
return (d.parse_fields('user_id', notification_body) or
|
||||
notification_body.get('_context_user_id') or
|
||||
notification_body.get('_context_user', None))
|
||||
|
||||
@staticmethod
|
||||
def get_project_id(d, notification_body):
|
||||
return (d.parse_fields('project_id', notification_body) or
|
||||
notification_body.get('_context_tenant_id') or
|
||||
notification_body.get('_context_tenant', None))
|
@ -13,10 +13,12 @@
|
||||
import datetime
|
||||
|
||||
import mock
|
||||
from oslotest import base
|
||||
|
||||
from ceilometer.key_value_storage import notifications
|
||||
from oslo_config import fixture as fixture_config
|
||||
|
||||
from ceilometer.meter import notifications
|
||||
from ceilometer import sample
|
||||
from ceilometer.tests import base as test
|
||||
|
||||
|
||||
def fake_uuid(x):
|
||||
@ -70,7 +72,15 @@ NOTIFICATION_TABLE_DELETE = {
|
||||
}
|
||||
|
||||
|
||||
class TestNotification(base.BaseTestCase):
|
||||
class TestNotification(test.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestNotification, self).setUp()
|
||||
self.CONF = self.useFixture(fixture_config.Config()).conf
|
||||
self.CONF.set_override(
|
||||
'meter_definitions_cfg_file',
|
||||
self.path_get('etc/ceilometer/meters.yaml'), group='meter')
|
||||
self.handler = notifications.ProcessMeterNotifications(mock.Mock())
|
||||
|
||||
def _verify_common_counter(self, c, name, volume):
|
||||
self.assertIsNotNone(c)
|
||||
@ -82,19 +92,18 @@ class TestNotification(base.BaseTestCase):
|
||||
self.assertEqual(u'magnetodb.winterfell.com', metadata.get('host'))
|
||||
|
||||
def test_create_table(self):
|
||||
handler = notifications.Table(mock.Mock())
|
||||
counters = list(handler.process_notification(
|
||||
counters = list(self.handler.process_notification(
|
||||
NOTIFICATION_TABLE_CREATE))
|
||||
self.assertEqual(1, len(counters))
|
||||
table = counters[0]
|
||||
self.assertEqual(2, len(counters))
|
||||
table = [item for item in counters
|
||||
if item.name == "magnetodb.table.create"][0]
|
||||
self._verify_common_counter(table, 'magnetodb.table.create', 1)
|
||||
self.assertEqual(fake_uuid('u'), table.user_id)
|
||||
self.assertEqual(fake_uuid('t'), table.project_id)
|
||||
self.assertEqual(sample.TYPE_GAUGE, table.type)
|
||||
|
||||
def test_delete_table(self):
|
||||
handler = notifications.Table(mock.Mock())
|
||||
counters = list(handler.process_notification(
|
||||
counters = list(self.handler.process_notification(
|
||||
NOTIFICATION_TABLE_DELETE))
|
||||
self.assertEqual(1, len(counters))
|
||||
table = counters[0]
|
||||
@ -104,11 +113,11 @@ class TestNotification(base.BaseTestCase):
|
||||
self.assertEqual(sample.TYPE_GAUGE, table.type)
|
||||
|
||||
def test_index_count(self):
|
||||
handler = notifications.Index(mock.Mock())
|
||||
counters = list(handler.process_notification(
|
||||
counters = list(self.handler.process_notification(
|
||||
NOTIFICATION_TABLE_CREATE))
|
||||
self.assertEqual(1, len(counters))
|
||||
table = counters[0]
|
||||
self.assertEqual(2, len(counters))
|
||||
table = [item for item in counters
|
||||
if item.name == "magnetodb.table.index.count"][0]
|
||||
self._verify_common_counter(table, 'magnetodb.table.index.count', 2)
|
||||
self.assertEqual(fake_uuid('u'), table.user_id)
|
||||
self.assertEqual(fake_uuid('t'), table.project_id)
|
||||
|
0
ceilometer/tests/meter/__init__.py
Normal file
0
ceilometer/tests/meter/__init__.py
Normal file
149
ceilometer/tests/meter/test_notifications.py
Normal file
149
ceilometer/tests/meter/test_notifications.py
Normal file
@ -0,0 +1,149 @@
|
||||
#
|
||||
# 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.
|
||||
"""Tests for ceilometer.meter.notifications
|
||||
"""
|
||||
import mock
|
||||
import six
|
||||
import yaml
|
||||
|
||||
from oslo_config import fixture as fixture_config
|
||||
|
||||
from ceilometer.meter import notifications
|
||||
from ceilometer.openstack.common import fileutils
|
||||
from ceilometer.tests import base as test
|
||||
|
||||
NOTIFICATION = {
|
||||
'event_type': u'test.create',
|
||||
'timestamp': u'2015-06-1909: 19: 35.786893',
|
||||
'payload': {u'user_id': u'e1d870e51c7340cb9d555b15cbfcaec2',
|
||||
u'resource_id': u'bea70e51c7340cb9d555b15cbfcaec23',
|
||||
u'timestamp': u'2015-06-19T09: 19: 35.785330',
|
||||
u'message_signature': u'fake_signature1',
|
||||
u'resource_metadata': {u'foo': u'bar'},
|
||||
u'source': u'30be1fc9a03c4e94ab05c403a8a377f2: openstack',
|
||||
u'volume': 1.0,
|
||||
u'project_id': u'30be1fc9a03c4e94ab05c403a8a377f2',
|
||||
},
|
||||
u'_context_tenant': u'30be1fc9a03c4e94ab05c403a8a377f2',
|
||||
u'_context_request_id': u'req-da91b4bf-d2b5-43ae-8b66-c7752e72726d',
|
||||
u'_context_user': u'e1d870e51c7340cb9d555b15cbfcaec2',
|
||||
'message_id': u'939823de-c242-45a2-a399-083f4d6a8c3e',
|
||||
'publisher_id': "foo123"
|
||||
}
|
||||
|
||||
|
||||
class TestMeterDefinition(test.BaseTestCase):
|
||||
|
||||
def test_config_definition(self):
|
||||
cfg = dict(name="test",
|
||||
event_type="test.create",
|
||||
type="delta",
|
||||
unit="B",
|
||||
volume="payload.volume",
|
||||
resource_id="payload.resource_id",
|
||||
project_id="payload.project_id")
|
||||
handler = notifications.MeterDefinition(cfg)
|
||||
self.assertTrue(handler.match_type("test.create"))
|
||||
self.assertEqual(1, handler.parse_fields("volume", NOTIFICATION))
|
||||
self.assertEqual("bea70e51c7340cb9d555b15cbfcaec23",
|
||||
handler.parse_fields("resource_id", NOTIFICATION))
|
||||
self.assertEqual("30be1fc9a03c4e94ab05c403a8a377f2",
|
||||
handler.parse_fields("project_id", NOTIFICATION))
|
||||
|
||||
def test_config_missing_fields(self):
|
||||
cfg = dict(name="test", type="delta")
|
||||
handler = notifications.MeterDefinition(cfg)
|
||||
try:
|
||||
handler.match_type("test.create")
|
||||
except notifications.MeterDefinitionException as e:
|
||||
self.assertEqual("Required field event_type not specified",
|
||||
e.message)
|
||||
|
||||
def test_bad_type_cfg_definition(self):
|
||||
cfg = dict(name="test", type="foo")
|
||||
try:
|
||||
notifications.MeterDefinition(cfg)
|
||||
except notifications.MeterDefinitionException as e:
|
||||
self.assertEqual("Invalid type foo specified", e.message)
|
||||
|
||||
|
||||
class TestMeterProcessing(test.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestMeterProcessing, self).setUp()
|
||||
self.CONF = self.useFixture(fixture_config.Config()).conf
|
||||
self.CONF.set_override(
|
||||
'meter_definitions_cfg_file',
|
||||
self.path_get('etc/ceilometer/meters.yaml'), group='meter')
|
||||
self.handler = notifications.ProcessMeterNotifications(mock.Mock())
|
||||
|
||||
def __setup_meter_def_file(self, cfg):
|
||||
if six.PY3:
|
||||
cfg = cfg.encode('utf-8')
|
||||
meter_cfg_file = fileutils.write_to_tempfile(content=cfg,
|
||||
prefix="meters",
|
||||
suffix="yaml")
|
||||
self.CONF.set_override(
|
||||
'meter_definitions_cfg_file',
|
||||
meter_cfg_file, group='meter')
|
||||
cfg = notifications.setup_meters_config()
|
||||
return cfg
|
||||
|
||||
def test_multiple_meter(self):
|
||||
cfg = yaml.dump(
|
||||
{'metric': [dict(name="test1",
|
||||
event_type="test.create",
|
||||
type="delta",
|
||||
unit="B",
|
||||
volume="payload.volume",
|
||||
resource_id="payload.resource_id",
|
||||
project_id="payload.project_id"),
|
||||
dict(name="test2",
|
||||
event_type="test.create",
|
||||
type="delta",
|
||||
unit="B",
|
||||
volume="payload.volume",
|
||||
resource_id="payload.resource_id",
|
||||
project_id="payload.project_id")]})
|
||||
self.handler.definitions = notifications.load_definitions(
|
||||
self.__setup_meter_def_file(cfg))
|
||||
c = list(self.handler.process_notification(NOTIFICATION))
|
||||
self.assertEqual(2, len(c))
|
||||
|
||||
def test_unmatched_meter(self):
|
||||
cfg = yaml.dump(
|
||||
{'metric': [dict(name="test1",
|
||||
event_type="test.update",
|
||||
type="delta",
|
||||
unit="B",
|
||||
volume="payload.volume",
|
||||
resource_id="payload.resource_id",
|
||||
project_id="payload.project_id")]})
|
||||
self.handler.definitions = notifications.load_definitions(
|
||||
self.__setup_meter_def_file(cfg))
|
||||
c = list(self.handler.process_notification(NOTIFICATION))
|
||||
self.assertEqual(0, len(c))
|
||||
|
||||
def test_regex_match_meter(self):
|
||||
cfg = yaml.dump(
|
||||
{'metric': [dict(name="test1",
|
||||
event_type="test.*",
|
||||
type="delta",
|
||||
unit="B",
|
||||
volume="payload.volume",
|
||||
resource_id="payload.resource_id",
|
||||
project_id="payload.project_id")]})
|
||||
self.handler.definitions = notifications.load_definitions(
|
||||
self.__setup_meter_def_file(cfg))
|
||||
c = list(self.handler.process_notification(NOTIFICATION))
|
||||
self.assertEqual(1, len(c))
|
@ -14,11 +14,12 @@ import datetime
|
||||
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
from oslo_config import fixture as fixture_config
|
||||
from oslo_log import log
|
||||
from oslotest import base
|
||||
|
||||
from ceilometer.orchestration import notifications
|
||||
from ceilometer.meter import notifications
|
||||
from ceilometer import sample
|
||||
from ceilometer.tests import base as test
|
||||
|
||||
NOW = datetime.datetime.isoformat(datetime.datetime.utcnow())
|
||||
|
||||
@ -51,8 +52,7 @@ def stack_notification_for(operation, use_trust=None):
|
||||
trustor_id = None
|
||||
|
||||
return {
|
||||
u'event_type': '%s.stack.%s.end' % (notifications.SERVICE,
|
||||
operation),
|
||||
u'event_type': 'orchestration.stack.%s.end' % operation,
|
||||
u'_context_roles': [
|
||||
u'Member',
|
||||
],
|
||||
@ -87,7 +87,15 @@ def stack_notification_for(operation, use_trust=None):
|
||||
}
|
||||
|
||||
|
||||
class TestNotification(base.BaseTestCase):
|
||||
class TestNotification(test.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestNotification, self).setUp()
|
||||
self.CONF = self.useFixture(fixture_config.Config()).conf
|
||||
self.CONF.set_override(
|
||||
'meter_definitions_cfg_file',
|
||||
self.path_get('etc/ceilometer/meters.yaml'), group='meter')
|
||||
self.handler = notifications.ProcessMeterNotifications(mock.Mock())
|
||||
|
||||
def _verify_common_sample(self, s, name, volume):
|
||||
self.assertIsNotNone(s)
|
||||
@ -102,8 +110,8 @@ class TestNotification(base.BaseTestCase):
|
||||
|
||||
def _test_operation(self, operation, trust=None):
|
||||
notif = stack_notification_for(operation, trust)
|
||||
handler = notifications.StackCRUD(mock.Mock())
|
||||
data = list(handler.process_notification(notif))
|
||||
|
||||
data = list(self.handler.process_notification(notif))
|
||||
self.assertEqual(1, len(data))
|
||||
if trust:
|
||||
self.assertEqual(TRUSTOR_ID, data[0].user_id)
|
||||
|
393
etc/ceilometer/meters.yaml
Normal file
393
etc/ceilometer/meters.yaml
Normal file
@ -0,0 +1,393 @@
|
||||
---
|
||||
|
||||
metric:
|
||||
- name: "image.size"
|
||||
event_type:
|
||||
- "image.upload"
|
||||
- "image.delete"
|
||||
- "image.update"
|
||||
type: "gauge"
|
||||
unit: B
|
||||
volume: payload.size
|
||||
resource_id: payload.id
|
||||
project_id: payload.owner
|
||||
|
||||
- name: "image.download"
|
||||
event_type: "image.send"
|
||||
type: "delta"
|
||||
unit: "B"
|
||||
volume: payload.bytes_sent
|
||||
resource_id: payload.image_id
|
||||
user_id: payload.receiver_user_id
|
||||
project_id: payload.receiver_tenant_id
|
||||
|
||||
- name: "image.serve"
|
||||
event_type: "image.send"
|
||||
type: "delta"
|
||||
unit: "B"
|
||||
volume: payload.bytes_sent
|
||||
resource_id: payload.image_id
|
||||
project_id: payload.owner_id
|
||||
|
||||
- name: 'bandwidth'
|
||||
event_type: 'l3.meter'
|
||||
type: 'delta'
|
||||
unit: 'B'
|
||||
volume: payload.bytes
|
||||
project_id: payload.tenant_id
|
||||
resource_id: payload.label_id
|
||||
|
||||
- name: 'magnetodb.table.index.count'
|
||||
type: 'gauge'
|
||||
unit: 'index'
|
||||
event_type: 'magnetodb.table.create.end'
|
||||
volume: payload.index_count
|
||||
resource_id: payload.table_uuid
|
||||
user_id: _context_user
|
||||
|
||||
- name: 'memory'
|
||||
event_type: 'compute.instance.*'
|
||||
type: 'gauge'
|
||||
unit: 'MB'
|
||||
volume: payload.memory_mb
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
resource_id: payload.instance_id
|
||||
|
||||
- name: 'vcpus'
|
||||
event_type: 'compute.instance.*'
|
||||
type: 'gauge'
|
||||
unit: 'vcpu'
|
||||
volume: payload.vcpus
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
resource_id: payload.instance_id
|
||||
|
||||
- name: 'disk.root.size'
|
||||
event_type: 'compute.instance.*'
|
||||
type: 'gauge'
|
||||
unit: 'GB'
|
||||
volume: payload.root_gb
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
resource_id: payload.instance_id
|
||||
|
||||
- name: 'disk.ephemeral.size'
|
||||
event_type: 'compute.instance.*'
|
||||
type: 'gauge'
|
||||
unit: 'GB'
|
||||
volume: payload.ephemeral_gb
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
resource_id: payload.instance_id
|
||||
|
||||
- name: 'volume.size'
|
||||
event_type:
|
||||
- 'volume.exists'
|
||||
- 'volume.create.*'
|
||||
- 'volume.delete.*'
|
||||
- 'volume.resize.*'
|
||||
- 'volume.attach.*'
|
||||
- 'volume.detach.*'
|
||||
- 'volume.update.*'
|
||||
type: 'gauge'
|
||||
unit: 'GB'
|
||||
volume: payload.size
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
resource_id: payload.volume_id
|
||||
|
||||
- name: 'snapshot.size'
|
||||
event_type:
|
||||
- 'snapshot.exists'
|
||||
- 'snapshot.create.*'
|
||||
- 'snapshot.delete.*'
|
||||
type: 'gauge'
|
||||
unit: 'GB'
|
||||
volume: payload.volume_size
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
resource_id: payload.snapshot_id
|
||||
|
||||
# NOTE: non-metric meters are generally events/existence meters
|
||||
# These are expected to be DEPRECATED in future releases
|
||||
#
|
||||
|
||||
- name: 'stack.create'
|
||||
event_type:
|
||||
- 'orchestration.stack.create.end'
|
||||
type: 'delta'
|
||||
unit: 'stack'
|
||||
volume: 1
|
||||
user_id: _context_trustor_user_id
|
||||
project_id: payload.tenant_id
|
||||
resource_id: payload.stack_identity
|
||||
|
||||
- name: 'stack.update'
|
||||
event_type:
|
||||
- 'orchestration.stack.update.end'
|
||||
type: 'delta'
|
||||
unit: 'stack'
|
||||
volume: 1
|
||||
user_id: _context_trustor_user_id
|
||||
project_id: payload.tenant_id
|
||||
resource_id: payload.stack_identity
|
||||
|
||||
- name: 'stack.delete'
|
||||
event_type:
|
||||
- 'orchestration.stack.delete.end'
|
||||
type: 'delta'
|
||||
unit: 'stack'
|
||||
volume: 1
|
||||
user_id: _context_trustor_user_id
|
||||
project_id: payload.tenant_id
|
||||
resource_id: payload.stack_identity
|
||||
|
||||
- name: 'stack.resume'
|
||||
event_type:
|
||||
- 'orchestration.stack.resume.end'
|
||||
type: 'delta'
|
||||
unit: 'stack'
|
||||
volume: 1
|
||||
user_id: _context_trustor_user_id
|
||||
project_id: payload.tenant_id
|
||||
resource_id: payload.stack_identity
|
||||
|
||||
- name: 'stack.suspend'
|
||||
event_type:
|
||||
- 'orchestration.stack.suspend.end'
|
||||
type: 'delta'
|
||||
unit: 'stack'
|
||||
volume: 1
|
||||
user_id: _context_trustor_user_id
|
||||
project_id: payload.tenant_id
|
||||
resource_id: payload.stack_identity
|
||||
|
||||
- name: 'magnetodb.table.create'
|
||||
type: 'gauge'
|
||||
unit: 'table'
|
||||
volume: 1
|
||||
event_type: 'magnetodb.table.create.end'
|
||||
resource_id: payload.table_uuid
|
||||
user_id: _context_user
|
||||
project_id: _context_tenant
|
||||
|
||||
- name: 'magnetodb.table.delete'
|
||||
type: 'gauge'
|
||||
unit: 'table'
|
||||
volume: 1
|
||||
event_type: 'magnetodb.table.delete.end'
|
||||
resource_id: payload.table_uuid
|
||||
user_id: _context_user
|
||||
project_id: _context_tenant
|
||||
|
||||
- name: 'volume'
|
||||
type: 'gauge'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.exists'
|
||||
- 'volume.create.*'
|
||||
- 'volume.delete.*'
|
||||
- 'volume.resize.*'
|
||||
- 'volume.attach.*'
|
||||
- 'volume.detach.*'
|
||||
- 'volume.update.*'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'volume.exists'
|
||||
type: 'delta'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.exists'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'volume.create.start'
|
||||
type: 'delta'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.create.*'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'volume.create.end'
|
||||
type: 'delta'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.create.*'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'volume.delete.start'
|
||||
type: 'delta'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.delete.*'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'volume.delete.end'
|
||||
type: 'delta'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.delete.*'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'volume.update.end'
|
||||
type: 'delta'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.update.*'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'volume.update.start'
|
||||
type: 'delta'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.update.*'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'volume.resize.end'
|
||||
type: 'delta'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.resize.*'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'volume.resize.start'
|
||||
type: 'delta'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.resize.*'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
|
||||
- name: 'volume.attach.end'
|
||||
type: 'delta'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.attach.*'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'volume.attach.start'
|
||||
type: 'delta'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.attach.*'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'volume.detach.end'
|
||||
type: 'delta'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.detach.*'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'volume.detach.start'
|
||||
type: 'delta'
|
||||
unit: 'volume'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'volume.detach.*'
|
||||
resource_id: payload.volume_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
|
||||
- name: 'snapshot'
|
||||
type: 'gauge'
|
||||
unit: 'snapshot'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'snapshot.exists'
|
||||
- 'snapshot.create.*'
|
||||
- 'snapshot.delete.*'
|
||||
|
||||
resource_id: payload.snapshot_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'snapshot.exists'
|
||||
type: 'delta'
|
||||
unit: 'snapshot'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'snapshot.exists'
|
||||
resource_id: payload.snapshot_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'snapshot.create.start'
|
||||
type: 'delta'
|
||||
unit: 'snapshot'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'snapshot.create.*'
|
||||
resource_id: payload.snapshot_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'snapshot.create.end'
|
||||
type: 'delta'
|
||||
unit: 'snapshot'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'snapshot.create.*'
|
||||
resource_id: payload.snapshot_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'snapshot.delete.start'
|
||||
type: 'delta'
|
||||
unit: 'snapshot'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'snapshot.delete.*'
|
||||
resource_id: payload.snapshot_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
||||
|
||||
- name: 'snapshot.delete.end'
|
||||
type: 'delta'
|
||||
unit: 'snapshot'
|
||||
volume: 1
|
||||
event_type:
|
||||
- 'snapshot.delete.*'
|
||||
resource_id: payload.snapshot_id
|
||||
user_id: payload.user_id
|
||||
project_id: payload.tenant_id
|
Loading…
Reference in New Issue
Block a user