Adds memory stats meter to libvirt inspector
Uses libvirt 'virDomainMemoryStats' to retrive the memory that is used by domain, implements 'inspect_memory_usage' function in libvirt inspector. Change-Id: I5bf17d51d82d10d2f31b9c81583f53b81c1c5268 Implements: blueprint libvirt-memory-utilization-inspector
This commit is contained in:
parent
f3994f0a8b
commit
135961088d
@ -18,8 +18,10 @@
|
|||||||
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
|
from oslo.utils import units
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
from ceilometer.compute.pollsters import util
|
||||||
from ceilometer.compute.virt import inspector as virt_inspector
|
from ceilometer.compute.virt import inspector as virt_inspector
|
||||||
from ceilometer.openstack.common.gettextutils import _
|
from ceilometer.openstack.common.gettextutils import _
|
||||||
from ceilometer.openstack.common import log as logging
|
from ceilometer.openstack.common import log as logging
|
||||||
@ -178,3 +180,35 @@ class LibvirtInspector(virt_inspector.Inspector):
|
|||||||
write_bytes=block_stats[3],
|
write_bytes=block_stats[3],
|
||||||
errors=block_stats[4])
|
errors=block_stats[4])
|
||||||
yield (disk, stats)
|
yield (disk, stats)
|
||||||
|
|
||||||
|
def inspect_memory_usage(self, instance, duration=None):
|
||||||
|
instance_name = util.instance_name(instance)
|
||||||
|
domain = self._lookup_by_name(instance_name)
|
||||||
|
state = domain.info()[0]
|
||||||
|
if state == libvirt.VIR_DOMAIN_SHUTOFF:
|
||||||
|
LOG.warn(_('Failed to inspect memory usage of %(instance_name)s, '
|
||||||
|
'domain is in state of SHUTOFF'),
|
||||||
|
{'instance_name': instance_name})
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
memory_stats = domain.memoryStats()
|
||||||
|
if (memory_stats and
|
||||||
|
memory_stats.get('available') and
|
||||||
|
memory_stats.get('unused')):
|
||||||
|
memory_used = (memory_stats.get('available') -
|
||||||
|
memory_stats.get('unused'))
|
||||||
|
# Stat provided from libvirt is in KB, converting it to MB.
|
||||||
|
memory_used = memory_used / units.Ki
|
||||||
|
return virt_inspector.MemoryUsageStats(usage=memory_used)
|
||||||
|
else:
|
||||||
|
LOG.warn(_('Failed to inspect memory usage of '
|
||||||
|
'%(instance_name)s, can not get info from libvirt'),
|
||||||
|
{'instance_name': instance_name})
|
||||||
|
# memoryStats might launch an exception if the method
|
||||||
|
# is not supported by the underlying hypervisor being
|
||||||
|
# used by libvirt
|
||||||
|
except libvirt.libvirtError as e:
|
||||||
|
LOG.warn(_('Failed to inspect memory usage of %(instance_name)s, '
|
||||||
|
'can not get info from libvirt: %(error)s'),
|
||||||
|
{'instance_name': instance_name, 'error': e})
|
||||||
|
@ -22,6 +22,7 @@ import contextlib
|
|||||||
|
|
||||||
import fixtures
|
import fixtures
|
||||||
import mock
|
import mock
|
||||||
|
from oslo.utils import units
|
||||||
from oslotest import base
|
from oslotest import base
|
||||||
|
|
||||||
from ceilometer.compute.virt import inspector as virt_inspector
|
from ceilometer.compute.virt import inspector as virt_inspector
|
||||||
@ -245,6 +246,44 @@ class TestLibvirtInspection(base.BaseTestCase):
|
|||||||
disks = list(self.inspector.inspect_disks(self.instance_name))
|
disks = list(self.inspector.inspect_disks(self.instance_name))
|
||||||
self.assertEqual(disks, [])
|
self.assertEqual(disks, [])
|
||||||
|
|
||||||
|
def test_inspect_memory_usage(self):
|
||||||
|
fake_memory_stats = {'available': 51200L, 'unused': 25600L}
|
||||||
|
connection = self.inspector.connection
|
||||||
|
with mock.patch.object(connection, 'lookupByName',
|
||||||
|
return_value=self.domain):
|
||||||
|
with mock.patch.object(self.domain, 'info',
|
||||||
|
return_value=(0L, 0L, 51200L,
|
||||||
|
2L, 999999L)):
|
||||||
|
with mock.patch.object(self.domain, 'memoryStats',
|
||||||
|
return_value=fake_memory_stats):
|
||||||
|
memory = self.inspector.inspect_memory_usage(
|
||||||
|
self.instance_name)
|
||||||
|
self.assertEqual(25600L / units.Ki, memory.usage)
|
||||||
|
|
||||||
|
def test_inspect_memory_usage_with_domain_shutoff(self):
|
||||||
|
connection = self.inspector.connection
|
||||||
|
with mock.patch.object(connection, 'lookupByName',
|
||||||
|
return_value=self.domain):
|
||||||
|
with mock.patch.object(self.domain, 'info',
|
||||||
|
return_value=(5L, 0L, 0L,
|
||||||
|
2L, 999999L)):
|
||||||
|
memory = self.inspector.inspect_memory_usage(
|
||||||
|
self.instance_name)
|
||||||
|
self.assertIsNone(memory)
|
||||||
|
|
||||||
|
def test_inspect_memory_usage_with_empty_stats(self):
|
||||||
|
connection = self.inspector.connection
|
||||||
|
with mock.patch.object(connection, 'lookupByName',
|
||||||
|
return_value=self.domain):
|
||||||
|
with mock.patch.object(self.domain, 'info',
|
||||||
|
return_value=(0L, 0L, 51200L,
|
||||||
|
2L, 999999L)):
|
||||||
|
with mock.patch.object(self.domain, 'memoryStats',
|
||||||
|
return_value={}):
|
||||||
|
memory = self.inspector.inspect_memory_usage(
|
||||||
|
self.instance_name)
|
||||||
|
self.assertIsNone(memory)
|
||||||
|
|
||||||
|
|
||||||
class TestLibvirtInspectionWithError(base.BaseTestCase):
|
class TestLibvirtInspectionWithError(base.BaseTestCase):
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ Name Type* Unit Resource Origin** Support**
|
|||||||
instance g instance inst ID both 1, 2, 3, 4 Existence of instance
|
instance g instance inst ID both 1, 2, 3, 4 Existence of instance
|
||||||
instance:<type> g instance inst ID both 1, 2, 3, 4 Existence of instance <type> (openstack types)
|
instance:<type> g instance inst ID both 1, 2, 3, 4 Existence of instance <type> (openstack types)
|
||||||
memory g MB inst ID n 1, 2 Volume of RAM allocated in MB
|
memory g MB inst ID n 1, 2 Volume of RAM allocated in MB
|
||||||
memory.usage g MB inst ID p 3, 4 Volume of RAM used in MB
|
memory.usage g MB inst ID p 1, 3, 4 Volume of RAM used in MB
|
||||||
cpu c ns inst ID p 1, 2 CPU time used
|
cpu c ns inst ID p 1, 2 CPU time used
|
||||||
cpu_util g % inst ID p 1, 2, 3, 4 Average CPU utilisation
|
cpu_util g % inst ID p 1, 2, 3, 4 Average CPU utilisation
|
||||||
vcpus g vcpu inst ID n 1, 2 Number of VCPUs
|
vcpus g vcpu inst ID n 1, 2 Number of VCPUs
|
||||||
@ -118,6 +118,12 @@ network.outgoing.packets.rate g packet/s iface ID p 1, 2, 3,
|
|||||||
[3]: Vsphere support
|
[3]: Vsphere support
|
||||||
[4]: XenAPI support
|
[4]: XenAPI support
|
||||||
|
|
||||||
|
.. note:: To enable the libvirt memory.usage supporting, you need libvirt
|
||||||
|
version 1.1.1+, qemu version 1.5+, and you need to prepare suitable balloon
|
||||||
|
driver in the image, particularly for Windows guests, most modern Linuxes
|
||||||
|
have it built in. The memory.usage meters can't be fetched without image
|
||||||
|
balloon driver.
|
||||||
|
|
||||||
Contributors are welcome to extend other virtualization backends' meters
|
Contributors are welcome to extend other virtualization backends' meters
|
||||||
or complete the existing ones.
|
or complete the existing ones.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user