Add a counter for instance scheduling

Blueprint: scheduler-counter

Change-Id: I20abaddf69f4d134e9f65885b5f1b1399c4e9946
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2013-05-07 12:42:05 +02:00
parent fbe2f00418
commit ddc37e6e9a
2 changed files with 125 additions and 24 deletions

View File

@ -1,8 +1,10 @@
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
# #
# Copyright © 2012 New Dream Network, LLC (DreamHost) # Copyright © 2012 New Dream Network, LLC (DreamHost)
# Copyright © 2013 eNovance
# #
# Author: Doug Hellmann <doug.hellmann@dreamhost.com> # Author: Doug Hellmann <doug.hellmann@dreamhost.com>
# Julien Danjou <julien@danjou.info>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
@ -23,6 +25,7 @@ from oslo.config import cfg
from ceilometer.compute import instance from ceilometer.compute import instance
from ceilometer import counter from ceilometer import counter
from ceilometer import plugin from ceilometer import plugin
from ceilometer import utils
OPTS = [ OPTS = [
@ -35,23 +38,7 @@ OPTS = [
cfg.CONF.register_opts(OPTS) cfg.CONF.register_opts(OPTS)
class _Base(plugin.NotificationBase): class ComputeNotificationBase(plugin.NotificationBase):
"""Convert compute.instance.* notifications into Counters
"""
metadata_keys = instance.INSTANCE_PROPERTIES
def notification_to_metadata(self, event):
metadata = super(_Base, self).notification_to_metadata(event)
metadata['instance_type'] = event['payload']['instance_type_id']
return metadata
@staticmethod
def get_event_types():
return ['compute.instance.create.end',
'compute.instance.exists',
'compute.instance.delete.start',
'compute.instance.finish_resize.end',
'compute.instance.resize.revert.end']
@staticmethod @staticmethod
def get_exchange_topics(conf): def get_exchange_topics(conf):
@ -65,7 +52,61 @@ class _Base(plugin.NotificationBase):
] ]
class Instance(_Base): class InstanceScheduled(ComputeNotificationBase):
metadata_keys = ['request_spec']
@staticmethod
def get_event_types():
return ['scheduler.run_instance.scheduled']
def notification_to_metadata(self, event):
metadata = super(InstanceScheduled,
self).notification_to_metadata(event)
metadata['weighted_host'] = event['payload']['weighted_host']['host']
metadata['weight'] = event['payload']['weighted_host']['weight']
return metadata
def process_notification(self, message):
return [
counter.Counter(
name='instance.scheduled',
type=counter.TYPE_DELTA,
volume=1,
unit='instance',
user_id=None,
project_id=
message['payload']['request_spec']
['instance_properties']['project_id'],
resource_id=message['payload']['instance_id'],
timestamp=message['timestamp'],
resource_metadata=dict(
utils.recursive_keypairs(message['payload'])),
)
]
class ComputeInstanceNotificationBase(ComputeNotificationBase):
"""Convert compute.instance.* notifications into Counters
"""
metadata_keys = instance.INSTANCE_PROPERTIES
def notification_to_metadata(self, event):
metadata = super(ComputeInstanceNotificationBase,
self).notification_to_metadata(event)
metadata['instance_type'] = event['payload']['instance_type_id']
return metadata
@staticmethod
def get_event_types():
return ['compute.instance.create.end',
'compute.instance.exists',
'compute.instance.delete.start',
'compute.instance.finish_resize.end',
'compute.instance.resize.revert.end']
class Instance(ComputeInstanceNotificationBase):
def process_notification(self, message): def process_notification(self, message):
return [ return [
@ -83,7 +124,7 @@ class Instance(_Base):
] ]
class Memory(_Base): class Memory(ComputeInstanceNotificationBase):
def process_notification(self, message): def process_notification(self, message):
return [ return [
@ -100,7 +141,7 @@ class Memory(_Base):
] ]
class VCpus(_Base): class VCpus(ComputeInstanceNotificationBase):
def process_notification(self, message): def process_notification(self, message):
return [ return [
@ -117,7 +158,7 @@ class VCpus(_Base):
] ]
class RootDiskSize(_Base): class RootDiskSize(ComputeInstanceNotificationBase):
def process_notification(self, message): def process_notification(self, message):
return [ return [
@ -134,7 +175,7 @@ class RootDiskSize(_Base):
] ]
class EphemeralDiskSize(_Base): class EphemeralDiskSize(ComputeInstanceNotificationBase):
def process_notification(self, message): def process_notification(self, message):
return [ return [
@ -151,7 +192,7 @@ class EphemeralDiskSize(_Base):
] ]
class InstanceFlavor(_Base): class InstanceFlavor(ComputeInstanceNotificationBase):
def process_notification(self, message): def process_notification(self, message):
counters = [] counters = []
@ -174,7 +215,7 @@ class InstanceFlavor(_Base):
return counters return counters
class InstanceDelete(_Base): class InstanceDelete(ComputeInstanceNotificationBase):
"""Handle the messages sent by the nova notifier plugin """Handle the messages sent by the nova notifier plugin
when an instance is being deleted. when an instance is being deleted.
""" """

View File

@ -1,8 +1,10 @@
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
# #
# Copyright © 2012 New Dream Network, LLC (DreamHost) # Copyright © 2012 New Dream Network, LLC (DreamHost)
# Copyright © 2013 eNovance
# #
# Author: Doug Hellmann <doug.hellmann@dreamhost.com> # Author: Doug Hellmann <doug.hellmann@dreamhost.com>
# Julien Danjou <julien@danjou.info>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # 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 # not use this file except in compliance with the License. You may obtain
@ -351,6 +353,51 @@ INSTANCE_DELETE_SAMPLES = {
} }
INSTANCE_SCHEDULED = {
u'_context_roles': [u'admin'],
u'_context_request_id': u'req-9da1d714-dabe-42fd-8baa-583e57cd4f1a',
u'_context_quota_class': None,
u'event_type': u'scheduler.run_instance.scheduled',
u'_context_user_name': u'admin',
u'_context_project_name': u'admin',
u'timestamp': u'2013-01-04 15:20:32.009532',
u'_context_is_admin': True,
u'message_id': u'c48deeba-d0c3-4154-b3db-47480b52267a',
u'_context_auth_token': None,
u'_context_instance_lock_checked': False,
u'_context_project_id': u'cea4b25edb484e5392727181b7721d29',
u'_context_timestamp': u'2013-01-04T15:19:51.018218',
u'_context_read_deleted': u'no',
u'_context_user_id': u'01b83a5e23f24a6fb6cd073c0aee6eed',
u'_context_remote_address': u'10.147.132.184',
u'publisher_id': u'compute.ip-10-147-132-184.ec2.internal',
u'payload': {
'instance_id': 'fake-uuid1-1',
'weighted_host': {
'host': 'host3',
'weight': 3.0,
},
'request_spec': {
'instance_properties': {
'root_gb': 512,
'ephemeral_gb': 0,
'launch_index': 0,
'memory_mb': 512,
'vcpus': 1,
'os_type': 'Linux',
'project_id': 1,
'system_metadata': {'system': 'metadata'}},
'instance_type': {'memory_mb': 512,
'vcpus': 1,
'root_gb': 512,
'ephemeral_gb': 0},
'instance_uuids': ['fake-uuid1-1'],
},
},
u'priority': u'INFO'
}
class TestNotifications(base.TestCase): class TestNotifications(base.TestCase):
def test_process_notification(self): def test_process_notification(self):
@ -507,3 +554,16 @@ class TestNotifications(base.TestCase):
self.assertEqual(len(counters), 2) self.assertEqual(len(counters), 2)
names = [c.name for c in counters] names = [c.name for c in counters]
self.assertEqual(names, ['sample-name1', 'sample-name2']) self.assertEqual(names, ['sample-name1', 'sample-name2'])
def test_instance_scheduled(self):
ic = notifications.InstanceScheduled()
self.assertIn(INSTANCE_SCHEDULED['event_type'],
ic.get_event_types())
counters = ic.process_notification(INSTANCE_SCHEDULED)
self.assertEqual(len(counters), 1)
names = [c.name for c in counters]
self.assertEqual(names, ['instance.scheduled'])
rid = [c.resource_id for c in counters]
self.assertEqual(rid, ['fake-uuid1-1'])