Merge "Add cpu.delay meter"

This commit is contained in:
Zuul authored and Gerrit Code Review committed 2026-09-28 09:09:08 +00:00
commit 5a3f99d05b
9 files changed
+69 -5

No files matched your search

@@ -38,6 +38,17 @@ class CPUPollster(InstanceStatsPollster):
return {'cpu_number': c_data.cpu_number}
class CPUDelayPollster(InstanceStatsPollster):
sample_name = 'cpu.delay'
sample_unit = 'ns'
sample_stats_key = 'cpu_delay'
sample_type = sample.TYPE_CUMULATIVE
@staticmethod
def get_additional_metadata(instance, c_data):
return {'cpu_number': c_data.cpu_number}
class VCPUsPollster(InstanceStatsPollster):
sample_name = 'vcpus'
sample_unit = 'vcpu'
+1
View File
@@ -43,6 +43,7 @@ class InstanceStats:
'power_state', # the power state of the domain
'cpu_number', # number: number of CPUs
'cpu_time', # time: cumulative CPU time
'cpu_delay', # delay: cumulative CPU steal time
'memory_actual', # actual: Amount of allocated memory
'memory_available', # available: Amount of usable memory
'memory_usage', # usage: Amount of memory used
+4 -1
View File
@@ -246,7 +246,7 @@ class LibvirtInspector(virt_inspector.Inspector):
# TODO(sileht): stats also have the disk/vnic info
# we could use that instead of the old method for Queen
stats = self.connection.domainListGetStats([domain], 0)[0][1]
cpu_time = 0
cpu_time = cpu_delay = 0
current_cpus = stats.get('vcpu.current')
# Iterate over the maximum number of CPUs here, and count the
# actual number encountered, since the vcpu.x structure can
@@ -257,6 +257,7 @@ class LibvirtInspector(virt_inspector.Inspector):
try:
cpu_time += (stats.get('vcpu.%s.time' % vcpu) +
stats.get('vcpu.%s.wait' % vcpu))
cpu_delay += stats.get('vcpu.%s.delay' % vcpu)
current_cpus -= 1
except TypeError:
# pass here, if there are too many holes, the cpu count will
@@ -266,11 +267,13 @@ class LibvirtInspector(virt_inspector.Inspector):
if current_cpus:
# There wasn't enough data, so fall back
cpu_time = stats.get('cpu.time')
cpu_delay = 0
return virt_inspector.InstanceStats(
power_state=domain.info()[0],
cpu_number=stats.get('vcpu.current'),
cpu_time=cpu_time,
cpu_delay=cpu_delay,
memory_actual=memory_actual,
memory_available=memory_available,
memory_usage=memory_used,
@@ -86,6 +86,8 @@ resources:
power.state:
cpu:
archive_policy_name: ceilometer-low-rate
cpu.delay:
archive_policy_name: ceilometer-low-rate
disk.root.size:
disk.ephemeral.size:
disk.latency:
@@ -104,6 +104,37 @@ class TestCPUPollster(base.TestPollsterBase):
samples[0].resource_metadata['instance_type'])
class TestCPUDelayPollster(base.TestPollsterBase):
def test_get_samples(self):
self._mock_inspect_instance(
virt_inspector.InstanceStats(
cpu_delay=1 * (10 ** 6), cpu_number=2),
virt_inspector.InstanceStats(
cpu_delay=3 * (10 ** 6), cpu_number=2),
# cpu_delay resets on instance restart
virt_inspector.InstanceStats(
cpu_delay=2 * (10 ** 6), cpu_number=2),
)
mgr = manager.AgentManager(0, self.CONF)
pollster = instance_stats.CPUDelayPollster(self.CONF)
def _verify_cpu_metering(expected_time):
cache = {}
samples = list(pollster.get_samples(mgr, cache, [self.instance]))
self.assertEqual(1, len(samples))
self.assertEqual({'cpu.delay'}, {s.name for s in samples})
self.assertEqual(expected_time, samples[0].volume)
self.assertEqual(2, samples[0].resource_metadata.get('cpu_number'))
# ensure elapsed time between polling cycles is non-zero
time.sleep(0.001)
_verify_cpu_metering(1 * (10 ** 6))
_verify_cpu_metering(3 * (10 ** 6))
_verify_cpu_metering(2 * (10 ** 6))
class TestVCPUsPollster(base.TestPollsterBase):
def test_get_samples(self):
@@ -64,10 +64,12 @@ class TestLibvirtInspection(base.BaseTestCase):
'cpu.time': 999999,
'vcpu.maximum': 4,
'vcpu.current': 2,
'vcpu.0.time': 10000,
'vcpu.0.wait': 10000,
'vcpu.0.time': 20000,
'vcpu.0.wait': 2000,
'vcpu.0.delay': 100,
'vcpu.2.time': 10000,
'vcpu.2.wait': 10000,
'vcpu.2.wait': 1000,
'vcpu.2.delay': 200,
'perf.cpu_cycles': 7259361,
'perf.instructions': 8815623,
'perf.cache_references': 74184,
@@ -78,7 +80,8 @@ class TestLibvirtInspection(base.BaseTestCase):
stats = self.inspector.inspect_instance(self.instance, None)
self.assertEqual(0, stats.power_state)
self.assertEqual(2, stats.cpu_number)
self.assertEqual(40000, stats.cpu_time)
self.assertEqual(33000, stats.cpu_time)
self.assertEqual(300, stats.cpu_delay)
self.assertEqual(54400 / units.Ki, stats.memory_actual)
self.assertEqual(51200 / units.Ki, stats.memory_available)
self.assertEqual(25600 / units.Ki, stats.memory_usage)
@@ -110,6 +113,7 @@ class TestLibvirtInspection(base.BaseTestCase):
stats = self.inspector.inspect_instance(self.instance)
self.assertEqual(2, stats.cpu_number)
self.assertEqual(999999, stats.cpu_time)
self.assertEqual(0, stats.cpu_delay)
def test_inspect_instance_with_domain_shutoff(self):
domain = mock.Mock()
@@ -138,6 +142,7 @@ class TestLibvirtInspection(base.BaseTestCase):
self.assertEqual(2, stats.cpu_number)
self.assertEqual(2097152 / units.Ki, stats.memory_actual)
self.assertIsNone(stats.cpu_time)
self.assertIsNone(stats.cpu_delay)
self.assertIsNone(stats.memory_available)
self.assertIsNone(stats.memory_usage)
self.assertIsNone(stats.memory_resident)
@@ -236,6 +236,11 @@ The following meters are collected for OpenStack Compute.
| | | | | | | from within the |
| | | | | | | instance |
+-----------+-------+------+----------+----------+---------+------------------+
| **Meters added in the Indri release** |
+-----------+-------+------+----------+----------+---------+------------------+
| cpu.delay | Cumu\ | ns | instance | Pollster | Libvirt | CPU steal time |
| | lative| | ID | | | |
+-----------+-------+------+----------+----------+---------+------------------+
.. note::
+1
View File
@@ -103,6 +103,7 @@ local_node = "ceilometer.polling.discovery.localnode:LocalNodeDiscovery"
"disk.device.write.latency" = "ceilometer.compute.pollsters.disk:PerDeviceDiskWriteLatencyPollster"
"power.state" = "ceilometer.compute.pollsters.instance_stats:PowerStatePollster"
"cpu" = "ceilometer.compute.pollsters.instance_stats:CPUPollster"
"cpu.delay" = "ceilometer.compute.pollsters.instance_stats:CPUDelayPollster"
"vcpus" = "ceilometer.compute.pollsters.instance_stats:VCPUsPollster"
"network.incoming.bytes" = "ceilometer.compute.pollsters.net:IncomingBytesPollster"
"network.incoming.packets" = "ceilometer.compute.pollsters.net:IncomingPacketsPollster"
@@ -0,0 +1,5 @@
---
features:
- |
The new ``cpu.delay`` meter has been added. This meter shows total CPU
steal time observed per instance.