Add pollster data cache
Add a dictionary as a data cache for the pollsters, creating it outside of the loop where they are invoked and passing it to them. Future changesets will include changes to the pollsters to put data in the cache. blueprint one-meter-per-plugin Change-Id: Ie65526dfe65a8880ad8683b62fae62f8e7f9e69b Signed-off-by: Doug Hellmann <doug.hellmann@dreamhost.com>
This commit is contained in:
parent
2f1378ebea
commit
a10773e413
@ -37,11 +37,15 @@ class PollingTask(agent.PollingTask):
|
|||||||
with self.publish_context as publisher:
|
with self.publish_context as publisher:
|
||||||
# TODO(yjiang5) passing counters into get_counters to avoid
|
# TODO(yjiang5) passing counters into get_counters to avoid
|
||||||
# polling all counters one by one
|
# polling all counters one by one
|
||||||
|
cache = {}
|
||||||
for pollster in self.pollsters:
|
for pollster in self.pollsters:
|
||||||
try:
|
try:
|
||||||
LOG.info("Polling pollster %s", pollster.name)
|
LOG.info("Polling pollster %s", pollster.name)
|
||||||
publisher(list(pollster.obj.get_counters(
|
counters = list(pollster.obj.get_counters(
|
||||||
self.manager)))
|
self.manager,
|
||||||
|
cache,
|
||||||
|
))
|
||||||
|
publisher(counters)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
LOG.warning('Continue after error from %s: %s',
|
LOG.warning('Continue after error from %s: %s',
|
||||||
pollster.name, err)
|
pollster.name, err)
|
||||||
|
@ -37,12 +37,15 @@ class PollingTask(agent.PollingTask):
|
|||||||
if getattr(instance, 'OS-EXT-STS:vm_state', None) != 'error':
|
if getattr(instance, 'OS-EXT-STS:vm_state', None) != 'error':
|
||||||
# TODO(yjiang5) passing counters to get_counters to avoid
|
# TODO(yjiang5) passing counters to get_counters to avoid
|
||||||
# polling all counters one by one
|
# polling all counters one by one
|
||||||
|
cache = {}
|
||||||
for pollster in self.pollsters:
|
for pollster in self.pollsters:
|
||||||
try:
|
try:
|
||||||
LOG.info("Polling pollster %s", pollster.name)
|
LOG.info("Polling pollster %s", pollster.name)
|
||||||
publisher(list(pollster.obj.get_counters(
|
publisher(list(pollster.obj.get_counters(
|
||||||
self.manager,
|
self.manager,
|
||||||
instance)))
|
cache,
|
||||||
|
instance,
|
||||||
|
)))
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
LOG.warning('Continue after error from %s: %s',
|
LOG.warning('Continue after error from %s: %s',
|
||||||
pollster.name, err)
|
pollster.name, err)
|
||||||
|
@ -55,12 +55,14 @@ class DeletedInstanceStatsGatherer(object):
|
|||||||
self.mgr = extensions
|
self.mgr = extensions
|
||||||
self.inspector = inspector.get_hypervisor_inspector()
|
self.inspector = inspector.get_hypervisor_inspector()
|
||||||
|
|
||||||
def _get_counters_from_plugin(self, ext, instance, *args, **kwds):
|
def _get_counters_from_plugin(self, ext, cache, instance, *args, **kwds):
|
||||||
"""Used with the extenaion manager map() method."""
|
"""Used with the extenaion manager map() method."""
|
||||||
return ext.obj.get_counters(self, instance)
|
return ext.obj.get_counters(self, cache, instance)
|
||||||
|
|
||||||
def __call__(self, instance):
|
def __call__(self, instance):
|
||||||
|
cache = {}
|
||||||
counters = self.mgr.map(self._get_counters_from_plugin,
|
counters = self.mgr.map(self._get_counters_from_plugin,
|
||||||
|
cache=cache,
|
||||||
instance=instance,
|
instance=instance,
|
||||||
)
|
)
|
||||||
# counters is a list of lists, so flatten it before returning
|
# counters is a list of lists, so flatten it before returning
|
||||||
|
@ -30,6 +30,10 @@ class ComputePollster(plugin.PollsterBase):
|
|||||||
__metaclass__ = abc.ABCMeta
|
__metaclass__ = abc.ABCMeta
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def get_counters(self, manager, context):
|
def get_counters(self, manager, cache, instance):
|
||||||
"""Return a sequence of Counter instances from polling the resources.
|
"""Return a sequence of Counter instances from polling the resources.
|
||||||
|
|
||||||
|
:param manager: The service manager invoking the plugin
|
||||||
|
:param cache: A dictionary for passing data between plugins
|
||||||
|
:param instance: The instance to examine
|
||||||
"""
|
"""
|
||||||
|
@ -57,7 +57,7 @@ class InstancePollster(plugin.ComputePollster):
|
|||||||
# variable. We don't need such format in future
|
# variable. We don't need such format in future
|
||||||
return ['instance', 'instance:*']
|
return ['instance', 'instance:*']
|
||||||
|
|
||||||
def get_counters(self, manager, instance):
|
def get_counters(self, manager, cache, instance):
|
||||||
yield make_counter_from_instance(instance,
|
yield make_counter_from_instance(instance,
|
||||||
name='instance',
|
name='instance',
|
||||||
type=counter.TYPE_GAUGE,
|
type=counter.TYPE_GAUGE,
|
||||||
@ -91,7 +91,7 @@ class DiskIOPollster(plugin.ComputePollster):
|
|||||||
'disk.write.requests',
|
'disk.write.requests',
|
||||||
'disk.write.bytes']
|
'disk.write.bytes']
|
||||||
|
|
||||||
def get_counters(self, manager, instance):
|
def get_counters(self, manager, cache, instance):
|
||||||
instance_name = _instance_name(instance)
|
instance_name = _instance_name(instance)
|
||||||
try:
|
try:
|
||||||
r_bytes = 0
|
r_bytes = 0
|
||||||
@ -164,7 +164,7 @@ class CPUPollster(plugin.ComputePollster):
|
|||||||
def get_counter_names():
|
def get_counter_names():
|
||||||
return ['cpu', 'cpu_util']
|
return ['cpu', 'cpu_util']
|
||||||
|
|
||||||
def get_counters(self, manager, instance):
|
def get_counters(self, manager, cache, instance):
|
||||||
self.LOG.info('checking instance %s', instance.id)
|
self.LOG.info('checking instance %s', instance.id)
|
||||||
instance_name = _instance_name(instance)
|
instance_name = _instance_name(instance)
|
||||||
try:
|
try:
|
||||||
@ -237,7 +237,7 @@ class NetPollster(plugin.ComputePollster):
|
|||||||
'network.outgoing.bytes',
|
'network.outgoing.bytes',
|
||||||
'network.outgoing.packets']
|
'network.outgoing.packets']
|
||||||
|
|
||||||
def get_counters(self, manager, instance):
|
def get_counters(self, manager, cache, instance):
|
||||||
instance_name = _instance_name(instance)
|
instance_name = _instance_name(instance)
|
||||||
self.LOG.info('checking instance %s', instance.id)
|
self.LOG.info('checking instance %s', instance.id)
|
||||||
try:
|
try:
|
||||||
|
@ -77,7 +77,7 @@ class KwapiPollster(_Base):
|
|||||||
def get_counter_names():
|
def get_counter_names():
|
||||||
return ['energy', 'power']
|
return ['energy', 'power']
|
||||||
|
|
||||||
def get_counters(self, manager):
|
def get_counters(self, manager, cache):
|
||||||
"""Returns all counters."""
|
"""Returns all counters."""
|
||||||
for probe in self.iter_probes(manager.keystone):
|
for probe in self.iter_probes(manager.keystone):
|
||||||
yield counter.Counter(
|
yield counter.Counter(
|
||||||
|
@ -99,7 +99,7 @@ class ImagePollster(_Base):
|
|||||||
def get_counter_names():
|
def get_counter_names():
|
||||||
return ['image', 'image.size']
|
return ['image', 'image.size']
|
||||||
|
|
||||||
def get_counters(self, manager):
|
def get_counters(self, manager, cache):
|
||||||
for image in self.iter_images(manager.keystone):
|
for image in self.iter_images(manager.keystone):
|
||||||
yield counter.Counter(
|
yield counter.Counter(
|
||||||
name='image',
|
name='image',
|
||||||
|
@ -35,7 +35,7 @@ class FloatingIPPollster(plugin.CentralPollster):
|
|||||||
def get_counter_names():
|
def get_counter_names():
|
||||||
return ['ip.floating']
|
return ['ip.floating']
|
||||||
|
|
||||||
def get_counters(self, manager):
|
def get_counters(self, manager, cache):
|
||||||
nv = nova_client.Client()
|
nv = nova_client.Client()
|
||||||
for ip in nv.floating_ip_get_all():
|
for ip in nv.floating_ip_get_all():
|
||||||
self.LOG.info("FLOATING IP USAGE: %s" % ip.ip)
|
self.LOG.info("FLOATING IP USAGE: %s" % ip.ip)
|
||||||
|
@ -55,7 +55,7 @@ class _Base(plugin.PollsterBase):
|
|||||||
def iter_accounts(ksclient):
|
def iter_accounts(ksclient):
|
||||||
"""Iterate over all accounts, yielding (tenant_id, stats) tuples."""
|
"""Iterate over all accounts, yielding (tenant_id, stats) tuples."""
|
||||||
|
|
||||||
def get_counters(self, manager):
|
def get_counters(self, manager, cache):
|
||||||
for tenant, account in self.iter_accounts(manager.keystone):
|
for tenant, account in self.iter_accounts(manager.keystone):
|
||||||
yield counter.Counter(
|
yield counter.Counter(
|
||||||
name='storage.objects',
|
name='storage.objects',
|
||||||
|
@ -88,7 +88,13 @@ class PollsterBase(PluginBase):
|
|||||||
"""Return a sequence of Counter names supported by the pollster."""
|
"""Return a sequence of Counter names supported by the pollster."""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def get_counters(self, manager, instance):
|
def get_counters(self, manager, cache):
|
||||||
"""Return a sequence of Counter instances from polling the resources.
|
"""Return a sequence of Counter instances from polling the resources.
|
||||||
|
|
||||||
|
:param manager: The service manager class invoking the plugin.
|
||||||
|
:param cache: A dictionary to allow pollsters to pass data
|
||||||
|
between themselves when recomputing it would be
|
||||||
|
expensive (e.g., asking another service for a
|
||||||
|
list of objects).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -77,7 +77,7 @@ class TestNovaNotifier(base.TestCase):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_counters(self, manager, instance):
|
def get_counters(self, manager, cache, instance):
|
||||||
self.instances.append((manager, instance))
|
self.instances.append((manager, instance))
|
||||||
return [self.test_data]
|
return [self.test_data]
|
||||||
|
|
||||||
|
@ -52,17 +52,17 @@ class TestPollster:
|
|||||||
def get_counter_names(self):
|
def get_counter_names(self):
|
||||||
return [self.test_data.name]
|
return [self.test_data.name]
|
||||||
|
|
||||||
def get_counters(self, manager, instance=None):
|
def get_counters(self, manager, cache, instance=None):
|
||||||
self.counters.append((manager, instance))
|
self.counters.append((manager, instance))
|
||||||
return [self.test_data]
|
return [self.test_data]
|
||||||
|
|
||||||
|
|
||||||
class TestPollsterException(TestPollster):
|
class TestPollsterException(TestPollster):
|
||||||
def get_counters(self, manager, instance=None):
|
def get_counters(self, manager, cache, instance=None):
|
||||||
# Put an instance parameter here so that it can be used
|
# Put an instance parameter here so that it can be used
|
||||||
# by both central manager and compute manager
|
# by both central manager and compute manager
|
||||||
# In future, we possibly don't need such hack if we
|
# In future, we possibly don't need such hack if we
|
||||||
# combin the get_counters() function again
|
# combine the get_counters() function again
|
||||||
self.counters.append((manager, instance))
|
self.counters.append((manager, instance))
|
||||||
raise Exception()
|
raise Exception()
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ class TestInstancePollster(TestPollsterBase):
|
|||||||
|
|
||||||
mgr = manager.AgentManager()
|
mgr = manager.AgentManager()
|
||||||
pollster = pollsters.InstancePollster()
|
pollster = pollsters.InstancePollster()
|
||||||
counters = list(pollster.get_counters(mgr, self.instance))
|
counters = list(pollster.get_counters(mgr, {}, self.instance))
|
||||||
self.assertEquals(len(counters), 2)
|
self.assertEquals(len(counters), 2)
|
||||||
self.assertEqual(counters[0].name, 'instance')
|
self.assertEqual(counters[0].name, 'instance')
|
||||||
self.assertEqual(counters[1].name, 'instance:m1.small')
|
self.assertEqual(counters[1].name, 'instance:m1.small')
|
||||||
@ -80,7 +80,7 @@ class TestDiskIOPollster(TestPollsterBase):
|
|||||||
|
|
||||||
mgr = manager.AgentManager()
|
mgr = manager.AgentManager()
|
||||||
pollster = pollsters.DiskIOPollster()
|
pollster = pollsters.DiskIOPollster()
|
||||||
counters = list(pollster.get_counters(mgr, self.instance))
|
counters = list(pollster.get_counters(mgr, {}, self.instance))
|
||||||
assert counters
|
assert counters
|
||||||
|
|
||||||
self.assertEqual(set([c.name for c in counters]),
|
self.assertEqual(set([c.name for c in counters]),
|
||||||
@ -143,7 +143,7 @@ class TestNetPollster(TestPollsterBase):
|
|||||||
|
|
||||||
mgr = manager.AgentManager()
|
mgr = manager.AgentManager()
|
||||||
pollster = pollsters.NetPollster()
|
pollster = pollsters.NetPollster()
|
||||||
counters = list(pollster.get_counters(mgr, self.instance))
|
counters = list(pollster.get_counters(mgr, {}, self.instance))
|
||||||
assert counters
|
assert counters
|
||||||
self.assertEqual(set([c.name for c in counters]),
|
self.assertEqual(set([c.name for c in counters]),
|
||||||
set(pollster.get_counter_names()))
|
set(pollster.get_counter_names()))
|
||||||
@ -203,7 +203,7 @@ class TestCPUPollster(TestPollsterBase):
|
|||||||
pollster = pollsters.CPUPollster()
|
pollster = pollsters.CPUPollster()
|
||||||
|
|
||||||
def _verify_cpu_metering(zero, expected_time):
|
def _verify_cpu_metering(zero, expected_time):
|
||||||
counters = list(pollster.get_counters(mgr, self.instance))
|
counters = list(pollster.get_counters(mgr, {}, self.instance))
|
||||||
self.assertEquals(len(counters), 2)
|
self.assertEquals(len(counters), 2)
|
||||||
self.assertEqual(set([c.name for c in counters]),
|
self.assertEqual(set([c.name for c in counters]),
|
||||||
set(pollster.get_counter_names()))
|
set(pollster.get_counter_names()))
|
||||||
|
@ -76,13 +76,13 @@ class TestKwapiPollster(base.TestCase):
|
|||||||
self.stubs.Set(kwapi._Base, 'get_kwapi_client',
|
self.stubs.Set(kwapi._Base, 'get_kwapi_client',
|
||||||
self.fake_kwapi_get_kwapi_client)
|
self.fake_kwapi_get_kwapi_client)
|
||||||
|
|
||||||
counters = list(kwapi.KwapiPollster().get_counters(self.manager))
|
counters = list(kwapi.KwapiPollster().get_counters(self.manager, {}))
|
||||||
self.assertEqual(len(counters), 0)
|
self.assertEqual(len(counters), 0)
|
||||||
|
|
||||||
def test_kwapi_counter(self):
|
def test_kwapi_counter(self):
|
||||||
self.stubs.Set(kwapi._Base, 'iter_probes', self.fake_kwapi_iter_probes)
|
self.stubs.Set(kwapi._Base, 'iter_probes', self.fake_kwapi_iter_probes)
|
||||||
|
|
||||||
counters = list(kwapi.KwapiPollster().get_counters(self.manager))
|
counters = list(kwapi.KwapiPollster().get_counters(self.manager, {}))
|
||||||
self.assertEqual(len(counters), 6)
|
self.assertEqual(len(counters), 6)
|
||||||
energy_counters = [counter for counter in counters
|
energy_counters = [counter for counter in counters
|
||||||
if counter.name == "energy"]
|
if counter.name == "energy"]
|
||||||
@ -104,6 +104,6 @@ class TestKwapiPollster(base.TestCase):
|
|||||||
def test_kwapi_counter_list(self):
|
def test_kwapi_counter_list(self):
|
||||||
self.stubs.Set(kwapi._Base, 'iter_probes', self.fake_kwapi_iter_probes)
|
self.stubs.Set(kwapi._Base, 'iter_probes', self.fake_kwapi_iter_probes)
|
||||||
|
|
||||||
counters = list(kwapi.KwapiPollster().get_counters(self.manager))
|
counters = list(kwapi.KwapiPollster().get_counters(self.manager, {}))
|
||||||
self.assertEqual(set([c.name for c in counters]),
|
self.assertEqual(set([c.name for c in counters]),
|
||||||
set(kwapi.KwapiPollster().get_counter_names()))
|
set(kwapi.KwapiPollster().get_counter_names()))
|
||||||
|
@ -140,7 +140,7 @@ class TestImagePollster(base.TestCase):
|
|||||||
self.assertEqual(len(images), len(set(image.id for image in images)))
|
self.assertEqual(len(images), len(set(image.id for image in images)))
|
||||||
|
|
||||||
def test_glance_image_counter(self):
|
def test_glance_image_counter(self):
|
||||||
counters = list(glance.ImagePollster().get_counters(self.manager))
|
counters = list(glance.ImagePollster().get_counters(self.manager, {}))
|
||||||
self.assertEqual(len(counters), 6)
|
self.assertEqual(len(counters), 6)
|
||||||
for counter in [c for c in counters if c.name == 'image']:
|
for counter in [c for c in counters if c.name == 'image']:
|
||||||
self.assertEqual(counter.volume, 1)
|
self.assertEqual(counter.volume, 1)
|
||||||
@ -150,6 +150,6 @@ class TestImagePollster(base.TestCase):
|
|||||||
counters)))
|
counters)))
|
||||||
|
|
||||||
def test_get_counter_names(self):
|
def test_get_counter_names(self):
|
||||||
counters = list(glance.ImagePollster().get_counters(self.manager))
|
counters = list(glance.ImagePollster().get_counters(self.manager, {}))
|
||||||
self.assertEqual(set([c.name for c in counters]),
|
self.assertEqual(set([c.name for c in counters]),
|
||||||
set(glance.ImagePollster().get_counter_names()))
|
set(glance.ImagePollster().get_counter_names()))
|
||||||
|
@ -65,7 +65,7 @@ class TestFloatingIPPollster(base.TestCase):
|
|||||||
# assert False, 'Should have seen an error'
|
# assert False, 'Should have seen an error'
|
||||||
|
|
||||||
def test_get_counters_not_empty(self):
|
def test_get_counters_not_empty(self):
|
||||||
counters = list(self.pollster.get_counters(self.manager))
|
counters = list(self.pollster.get_counters(self.manager, {}))
|
||||||
self.assertEqual(len(counters), 3)
|
self.assertEqual(len(counters), 3)
|
||||||
# It's necessary to verify all the attributes extracted by Nova
|
# It's necessary to verify all the attributes extracted by Nova
|
||||||
# API /os-floating-ips to make sure they're available and correct.
|
# API /os-floating-ips to make sure they're available and correct.
|
||||||
@ -82,6 +82,6 @@ class TestFloatingIPPollster(base.TestCase):
|
|||||||
self.assertEqual(counters[2].resource_metadata["pool"], "public")
|
self.assertEqual(counters[2].resource_metadata["pool"], "public")
|
||||||
|
|
||||||
def test_get_counter_names(self):
|
def test_get_counter_names(self):
|
||||||
counters = list(self.pollster.get_counters(self.manager))
|
counters = list(self.pollster.get_counters(self.manager, {}))
|
||||||
self.assertEqual(set([c.name for c in counters]),
|
self.assertEqual(set([c.name for c in counters]),
|
||||||
set(self.pollster.get_counter_names()))
|
set(self.pollster.get_counter_names()))
|
||||||
|
@ -77,18 +77,18 @@ class TestSwiftPollster(base.TestCase):
|
|||||||
def test_objectstore_metering(self):
|
def test_objectstore_metering(self):
|
||||||
self.stubs.Set(swift.SwiftPollster, 'iter_accounts',
|
self.stubs.Set(swift.SwiftPollster, 'iter_accounts',
|
||||||
self.fake_iter_accounts)
|
self.fake_iter_accounts)
|
||||||
counters = list(self.pollster.get_counters(self.manager))
|
counters = list(self.pollster.get_counters(self.manager, {}))
|
||||||
self.assertEqual(len(counters), 6)
|
self.assertEqual(len(counters), 6)
|
||||||
|
|
||||||
def test_objectstore_get_counter_names(self):
|
def test_objectstore_get_counter_names(self):
|
||||||
self.stubs.Set(swift.SwiftPollster, 'iter_accounts',
|
self.stubs.Set(swift.SwiftPollster, 'iter_accounts',
|
||||||
self.fake_iter_accounts)
|
self.fake_iter_accounts)
|
||||||
counters = list(self.pollster.get_counters(self.manager))
|
counters = list(self.pollster.get_counters(self.manager, {}))
|
||||||
self.assertEqual(set([c.name for c in counters]),
|
self.assertEqual(set([c.name for c in counters]),
|
||||||
set(self.pollster.get_counter_names()))
|
set(self.pollster.get_counter_names()))
|
||||||
|
|
||||||
def test_objectstore_endpoint_notfound(self):
|
def test_objectstore_endpoint_notfound(self):
|
||||||
self.stubs.Set(self.manager.keystone.service_catalog, 'url_for',
|
self.stubs.Set(self.manager.keystone.service_catalog, 'url_for',
|
||||||
self.fake_ks_service_catalog_url_for)
|
self.fake_ks_service_catalog_url_for)
|
||||||
counters = list(self.pollster.get_counters(self.manager))
|
counters = list(self.pollster.get_counters(self.manager, {}))
|
||||||
self.assertEqual(len(counters), 0)
|
self.assertEqual(len(counters), 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user