From 7794efcec63f293abc219fa14fb6e86e8893c562 Mon Sep 17 00:00:00 2001 From: Prudhvi Rao Shedimbi Date: Wed, 7 Sep 2016 21:59:06 +0000 Subject: [PATCH] Compute agent can poll tx and rx errors and drops Allows compute agent to poll for tx and rx errors and dropped packets. Closes-Bug: #1587987 Change-Id: I5f1a48b4f1751c64dde2e09005947f7af1efa505 --- ceilometer/compute/pollsters/net.py | 80 +++++++++++++++++++ ceilometer/compute/virt/hyperv/inspector.py | 6 +- ceilometer/compute/virt/inspector.py | 6 +- ceilometer/compute/virt/libvirt/inspector.py | 6 +- .../tests/unit/compute/pollsters/test_net.py | 72 ++++++++++++++++- setup.cfg | 4 + 6 files changed, 166 insertions(+), 8 deletions(-) diff --git a/ceilometer/compute/pollsters/net.py b/ceilometer/compute/pollsters/net.py index a528bb6eb9..f08558ed26 100644 --- a/ceilometer/compute/pollsters/net.py +++ b/ceilometer/compute/pollsters/net.py @@ -149,6 +149,34 @@ class _PacketsBase(_Base): return info.tx_packets +class _DropBase(_Base): + + NET_USAGE_MESSAGE = ' '.join(["NETWORK PACKET DROPS:", "%s %s:", + "rx-drop=%d", "tx-drop=%d"]) + + @staticmethod + def _get_rx_info(info): + return info.rx_drop + + @staticmethod + def _get_tx_info(info): + return info.tx_drop + + +class _ErrorsBase(_Base): + + NET_USAGE_MESSAGE = ' '.join(["NETWORK PACKET ERRORS:", "%s %s:", + "rx-errors=%d", "tx-errors=%d"]) + + @staticmethod + def _get_rx_info(info): + return info.rx_errors + + @staticmethod + def _get_tx_info(info): + return info.tx_errors + + class IncomingBytesPollster(_Base): def _get_sample(self, instance, vnic, info): @@ -225,3 +253,55 @@ class OutgoingBytesRatePollster(_RateBase): volume=info.tx_bytes_rate, vnic_data=vnic, ) + + +class IncomingDropPollster(_DropBase): + + def _get_sample(self, instance, vnic, info): + return self.make_vnic_sample( + instance, + name='network.incoming.packets.drop', + type=sample.TYPE_CUMULATIVE, + unit='packet', + volume=info.rx_drop, + vnic_data=vnic, + ) + + +class OutgoingDropPollster(_DropBase): + + def _get_sample(self, instance, vnic, info): + return self.make_vnic_sample( + instance, + name='network.outgoing.packets.drop', + type=sample.TYPE_CUMULATIVE, + unit='packet', + volume=info.tx_drop, + vnic_data=vnic, + ) + + +class IncomingErrorsPollster(_ErrorsBase): + + def _get_sample(self, instance, vnic, info): + return self.make_vnic_sample( + instance, + name='network.incoming.packets.error', + type=sample.TYPE_CUMULATIVE, + unit='packet', + volume=info.rx_errors, + vnic_data=vnic, + ) + + +class OutgoingErrorsPollster(_ErrorsBase): + + def _get_sample(self, instance, vnic, info): + return self.make_vnic_sample( + instance, + name='network.outgoing.packets.error', + type=sample.TYPE_CUMULATIVE, + unit='packet', + volume=info.tx_errors, + vnic_data=vnic, + ) diff --git a/ceilometer/compute/virt/hyperv/inspector.py b/ceilometer/compute/virt/hyperv/inspector.py index 3840929540..685323c7ac 100644 --- a/ceilometer/compute/virt/hyperv/inspector.py +++ b/ceilometer/compute/virt/hyperv/inspector.py @@ -120,8 +120,12 @@ class HyperVInspector(virt_inspector.Inspector): stats = virt_inspector.InterfaceStats( rx_bytes=vnic_metrics['rx_mb'] * units.Mi, rx_packets=0, + rx_drop=0, + rx_errors=0, tx_bytes=vnic_metrics['tx_mb'] * units.Mi, - tx_packets=0) + tx_packets=0, + tx_drop=0, + tx_errors=0) yield (interface, stats) diff --git a/ceilometer/compute/virt/inspector.py b/ceilometer/compute/virt/inspector.py index 46336e3341..f5637318a3 100644 --- a/ceilometer/compute/virt/inspector.py +++ b/ceilometer/compute/virt/inspector.py @@ -120,8 +120,10 @@ Interface = collections.namedtuple('Interface', ['name', 'mac', # tx_packets: number of transmitted packets # InterfaceStats = collections.namedtuple('InterfaceStats', - ['rx_bytes', 'rx_packets', - 'tx_bytes', 'tx_packets']) + ['rx_bytes', 'tx_bytes', + 'rx_packets', 'tx_packets', + 'rx_drop', 'tx_drop', + 'rx_errors', 'tx_errors']) # Named tuple representing vNIC rate statistics. diff --git a/ceilometer/compute/virt/libvirt/inspector.py b/ceilometer/compute/virt/libvirt/inspector.py index f662da1cfe..edde68a509 100644 --- a/ceilometer/compute/virt/libvirt/inspector.py +++ b/ceilometer/compute/virt/libvirt/inspector.py @@ -179,8 +179,12 @@ class LibvirtInspector(virt_inspector.Inspector): dom_stats = domain.interfaceStats(name) stats = virt_inspector.InterfaceStats(rx_bytes=dom_stats[0], rx_packets=dom_stats[1], + rx_drop=dom_stats[2], + rx_errors=dom_stats[3], tx_bytes=dom_stats[4], - tx_packets=dom_stats[5]) + tx_packets=dom_stats[5], + tx_drop=dom_stats[6], + tx_errors=dom_stats[7]) yield (interface, stats) def inspect_disks(self, instance): diff --git a/ceilometer/tests/unit/compute/pollsters/test_net.py b/ceilometer/tests/unit/compute/pollsters/test_net.py index d78a2ec30f..60c50baffd 100644 --- a/ceilometer/tests/unit/compute/pollsters/test_net.py +++ b/ceilometer/tests/unit/compute/pollsters/test_net.py @@ -49,7 +49,9 @@ class TestNetPollster(base.TestPollsterBase): projnet='proj1', dhcp_server='10.0.0.1')) stats0 = virt_inspector.InterfaceStats(rx_bytes=1, rx_packets=2, - tx_bytes=3, tx_packets=4) + rx_drop=20, rx_errors=21, + tx_bytes=3, tx_packets=4, + tx_drop=22, tx_errors=23) self.vnic1 = virt_inspector.Interface( name='vnet1', fref='fa163e71ec6f', @@ -59,7 +61,9 @@ class TestNetPollster(base.TestPollsterBase): projnet='proj2', dhcp_server='10.0.0.2')) stats1 = virt_inspector.InterfaceStats(rx_bytes=5, rx_packets=6, - tx_bytes=7, tx_packets=8) + rx_drop=24, rx_errors=25, + tx_bytes=7, tx_packets=8, + tx_drop=26, tx_errors=27) self.vnic2 = virt_inspector.Interface( name='vnet2', fref=None, @@ -69,7 +73,9 @@ class TestNetPollster(base.TestPollsterBase): projnet='proj3', dhcp_server='10.0.0.3')) stats2 = virt_inspector.InterfaceStats(rx_bytes=9, rx_packets=10, - tx_bytes=11, tx_packets=12) + rx_drop=28, rx_errors=29, + tx_bytes=11, tx_packets=12, + tx_drop=30, tx_errors=31) vnics = [ (self.vnic0, stats0), @@ -175,6 +181,50 @@ class TestNetPollster(base.TestPollsterBase): ], ) + def test_incoming_drops(self): + instance_name_id = "%s-%s" % (self.instance.name, self.instance.id) + self._check_get_samples( + net.IncomingDropPollster, + [('10.0.0.2', 20, self.vnic0.fref), + ('192.168.0.3', 24, self.vnic1.fref), + ('192.168.0.4', 28, + "%s-%s" % (instance_name_id, self.vnic2.name)), + ], + ) + + def test_outgoing_drops(self): + instance_name_id = "%s-%s" % (self.instance.name, self.instance.id) + self._check_get_samples( + net.OutgoingDropPollster, + [('10.0.0.2', 22, self.vnic0.fref), + ('192.168.0.3', 26, self.vnic1.fref), + ('192.168.0.4', 30, + "%s-%s" % (instance_name_id, self.vnic2.name)), + ], + ) + + def test_incoming_errors(self): + instance_name_id = "%s-%s" % (self.instance.name, self.instance.id) + self._check_get_samples( + net.IncomingErrorsPollster, + [('10.0.0.2', 21, self.vnic0.fref), + ('192.168.0.3', 25, self.vnic1.fref), + ('192.168.0.4', 29, + "%s-%s" % (instance_name_id, self.vnic2.name)), + ], + ) + + def test_outgoing_errors(self): + instance_name_id = "%s-%s" % (self.instance.name, self.instance.id) + self._check_get_samples( + net.OutgoingErrorsPollster, + [('10.0.0.2', 23, self.vnic0.fref), + ('192.168.0.3', 27, self.vnic1.fref), + ('192.168.0.4', 31, + "%s-%s" % (instance_name_id, self.vnic2.name)), + ], + ) + @mock.patch('ceilometer.pipeline.setup_pipeline', mock.MagicMock()) def test_metadata(self): factory = net.OutgoingBytesPollster @@ -206,7 +256,9 @@ class TestNetPollsterCache(base.TestPollsterBase): projnet='proj1', dhcp_server='10.0.0.1')) stats0 = virt_inspector.InterfaceStats(rx_bytes=1, rx_packets=2, - tx_bytes=3, tx_packets=4) + rx_drop=20, rx_errors=21, + tx_bytes=3, tx_packets=4, + tx_drop=22, tx_errors=23) vnics = [(vnic0, stats0)] mgr = manager.AgentManager() @@ -231,6 +283,18 @@ class TestNetPollsterCache(base.TestPollsterBase): def test_outgoing_packets(self): self._check_get_samples_cache(net.OutgoingPacketsPollster) + def test_incoming_drops(self): + self._check_get_samples_cache(net.IncomingDropPollster) + + def test_outgoing_drops(self): + self._check_get_samples_cache(net.OutgoingDropPollster) + + def test_incoming_errors(self): + self._check_get_samples_cache(net.IncomingErrorsPollster) + + def test_outgoing_errors(self): + self._check_get_samples_cache(net.OutgoingErrorsPollster) + class TestNetRatesPollster(base.TestPollsterBase): diff --git a/setup.cfg b/setup.cfg index b3d08ec110..dd963d683a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -123,6 +123,10 @@ ceilometer.poll.compute = network.outgoing.packets = ceilometer.compute.pollsters.net:OutgoingPacketsPollster network.incoming.bytes.rate = ceilometer.compute.pollsters.net:IncomingBytesRatePollster network.outgoing.bytes.rate = ceilometer.compute.pollsters.net:OutgoingBytesRatePollster + network.incoming.packets.drop = ceilometer.compute.pollsters.net:IncomingDropPollster + network.outgoing.packets.drop = ceilometer.compute.pollsters.net:OutgoingDropPollster + network.incoming.packets.error = ceilometer.compute.pollsters.net:IncomingErrorsPollster + network.outgoing.packets.error = ceilometer.compute.pollsters.net:OutgoingErrorsPollster instance = ceilometer.compute.pollsters.instance:InstancePollster memory.usage = ceilometer.compute.pollsters.memory:MemoryUsagePollster memory.resident = ceilometer.compute.pollsters.memory:MemoryResidentPollster