Pollster for network internal traffic (n1,n2)
Implements bug 1004449 Change-Id: I9ca8a19ec6b5635868cff1628a169faf2ff87331
This commit is contained in:
parent
fdcd37f6a3
commit
113439da10
@ -16,6 +16,8 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import copy
|
||||||
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
from nova import flags
|
from nova import flags
|
||||||
@ -61,6 +63,24 @@ def make_counter_from_instance(instance, name, type, volume):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def make_vnic_counter(instance, name, type, volume, vnic_data):
|
||||||
|
resource_metadata = copy.copy(vnic_data)
|
||||||
|
resource_metadata['instance_id'] = instance.id
|
||||||
|
|
||||||
|
return counter.Counter(
|
||||||
|
source='?',
|
||||||
|
name=name,
|
||||||
|
type=type,
|
||||||
|
volume=volume,
|
||||||
|
user_id=instance.user_id,
|
||||||
|
project_id=instance.project_id,
|
||||||
|
resource_id=vnic_data['fref'],
|
||||||
|
timestamp=timeutils.isotime(),
|
||||||
|
duration=None,
|
||||||
|
resource_metadata=resource_metadata
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DiskIOPollster(plugin.ComputePollster):
|
class DiskIOPollster(plugin.ComputePollster):
|
||||||
|
|
||||||
LOG = log.getLogger(__name__ + '.diskio')
|
LOG = log.getLogger(__name__ + '.diskio')
|
||||||
@ -134,3 +154,54 @@ class CPUPollster(plugin.ComputePollster):
|
|||||||
self.LOG.error('could not get CPU time for %s: %s',
|
self.LOG.error('could not get CPU time for %s: %s',
|
||||||
instance.uuid, err)
|
instance.uuid, err)
|
||||||
self.LOG.exception(err)
|
self.LOG.exception(err)
|
||||||
|
|
||||||
|
|
||||||
|
class NetPollster(plugin.ComputePollster):
|
||||||
|
|
||||||
|
LOG = log.getLogger(__name__ + '.net')
|
||||||
|
|
||||||
|
NET_USAGE_MESSAGE = ' '.join(["NETWORK USAGE:", "%s %s:", "read-bytes=%d",
|
||||||
|
"write-bytes=%d"])
|
||||||
|
|
||||||
|
def _get_vnics(self, conn, instance):
|
||||||
|
"""Get disks of an instance, only used to bypass bug#998089."""
|
||||||
|
domain = conn._conn.lookupByName(instance.name)
|
||||||
|
tree = etree.fromstring(domain.XMLDesc(0))
|
||||||
|
vnics = []
|
||||||
|
for interface in tree.findall('devices/interface'):
|
||||||
|
vnic = {}
|
||||||
|
vnic['name'] = interface.find('target').get('dev')
|
||||||
|
vnic['mac'] = interface.find('mac').get('address')
|
||||||
|
vnic['fref'] = interface.find('filterref').get('filter')
|
||||||
|
for param in interface.findall('filterref/parameter'):
|
||||||
|
vnic[param.get('name').lower()] = param.get('value')
|
||||||
|
vnics.append(vnic)
|
||||||
|
return vnics
|
||||||
|
|
||||||
|
def get_counters(self, manager, instance):
|
||||||
|
conn = get_libvirt_connection()
|
||||||
|
self.LOG.info('checking instance %s', instance.uuid)
|
||||||
|
try:
|
||||||
|
vnics = self._get_vnics(conn, instance)
|
||||||
|
except Exception as err:
|
||||||
|
self.LOG.warning('Ignoring instance %s: %s',
|
||||||
|
instance.name, err)
|
||||||
|
self.LOG.exception(err)
|
||||||
|
else:
|
||||||
|
domain = conn._conn.lookupByName(instance.name)
|
||||||
|
for vnic in vnics:
|
||||||
|
rx, _, _, _, tx, _, _, _ = domain.interfaceStats(vnic['name'])
|
||||||
|
self.LOG.info(self.NET_USAGE_MESSAGE, instance.name,
|
||||||
|
vnic['name'], rx, tx)
|
||||||
|
yield make_vnic_counter(instance,
|
||||||
|
name='net_in_int',
|
||||||
|
type='cumulative',
|
||||||
|
volume=rx,
|
||||||
|
vnic_data=vnic
|
||||||
|
)
|
||||||
|
yield make_vnic_counter(instance,
|
||||||
|
name='net_out_int',
|
||||||
|
type='cumulative',
|
||||||
|
volume=tx,
|
||||||
|
vnic_data=vnic
|
||||||
|
)
|
||||||
|
1
setup.py
1
setup.py
@ -48,6 +48,7 @@ setuptools.setup(
|
|||||||
[ceilometer.poll.compute]
|
[ceilometer.poll.compute]
|
||||||
libvirt_diskio = ceilometer.compute.libvirt:DiskIOPollster
|
libvirt_diskio = ceilometer.compute.libvirt:DiskIOPollster
|
||||||
libvirt_cpu = ceilometer.compute.libvirt:CPUPollster
|
libvirt_cpu = ceilometer.compute.libvirt:CPUPollster
|
||||||
|
libvirt_net = ceilometer.compute.libvirt:NetPollster
|
||||||
|
|
||||||
[ceilometer.poll.central]
|
[ceilometer.poll.central]
|
||||||
network_floatingip = ceilometer.network.floatingip:FloatingIPPollster
|
network_floatingip = ceilometer.network.floatingip:FloatingIPPollster
|
||||||
|
@ -34,8 +34,12 @@ from nova import flags
|
|||||||
|
|
||||||
from ceilometer.compute import libvirt
|
from ceilometer.compute import libvirt
|
||||||
from ceilometer.compute import manager
|
from ceilometer.compute import manager
|
||||||
|
from ceilometer.tests import base as test_base
|
||||||
from ceilometer.tests import skip
|
from ceilometer.tests import skip
|
||||||
|
|
||||||
|
import mox
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
class TestDiskIOPollster(unittest.TestCase):
|
class TestDiskIOPollster(unittest.TestCase):
|
||||||
|
|
||||||
@ -72,3 +76,106 @@ class TestDiskIOPollster(unittest.TestCase):
|
|||||||
instance.id = 999
|
instance.id = 999
|
||||||
counters = list(self.pollster.get_counters(self.manager, instance))
|
counters = list(self.pollster.get_counters(self.manager, instance))
|
||||||
assert not counters
|
assert not counters
|
||||||
|
|
||||||
|
|
||||||
|
class TestNetPollster(test_base.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.manager = manager.AgentManager()
|
||||||
|
self.pollster = libvirt.NetPollster()
|
||||||
|
super(TestNetPollster, self).setUp()
|
||||||
|
self.instance = mock.MagicMock()
|
||||||
|
self.instance.name = 'instance-00000001'
|
||||||
|
self.instance.id = 1
|
||||||
|
|
||||||
|
def test_get_vnics(self):
|
||||||
|
dom_xml = """
|
||||||
|
<domain type='kvm'>
|
||||||
|
<devices>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<mac address='fa:16:3e:71:ec:6d'/>
|
||||||
|
<source bridge='br100'/>
|
||||||
|
<target dev='vnet0'/>
|
||||||
|
<filterref filter=
|
||||||
|
'nova-instance-instance-00000001-fa163e71ec6d'>
|
||||||
|
<parameter name='DHCPSERVER' value='10.0.0.1'/>
|
||||||
|
<parameter name='IP' value='10.0.0.2'/>
|
||||||
|
<parameter name='PROJMASK' value='255.255.255.0'/>
|
||||||
|
<parameter name='PROJNET' value='10.0.0.0'/>
|
||||||
|
</filterref>
|
||||||
|
<alias name='net0'/>
|
||||||
|
</interface>
|
||||||
|
<interface type='bridge'>
|
||||||
|
<mac address='fa:16:3e:71:ec:6e'/>
|
||||||
|
<source bridge='br100'/>
|
||||||
|
<target dev='vnet1'/>
|
||||||
|
<filterref filter=
|
||||||
|
'nova-instance-instance-00000001-fa163e71ec6e'>
|
||||||
|
<parameter name='DHCPSERVER' value='192.168.0.1'/>
|
||||||
|
<parameter name='IP' value='192.168.0.2'/>
|
||||||
|
<parameter name='PROJMASK' value='255.255.255.0'/>
|
||||||
|
<parameter name='PROJNET' value='192.168.0.0'/>
|
||||||
|
</filterref>
|
||||||
|
<alias name='net1'/>
|
||||||
|
</interface>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
||||||
|
"""
|
||||||
|
|
||||||
|
ignore = mox.IgnoreArg()
|
||||||
|
conn = self.mox.CreateMockAnything()
|
||||||
|
domain = self.mox.CreateMockAnything()
|
||||||
|
conn._conn = self.mox.CreateMockAnything()
|
||||||
|
self.mox.StubOutWithMock(conn._conn, 'lookupByName')
|
||||||
|
conn._conn.lookupByName(self.instance.name).AndReturn(domain)
|
||||||
|
self.mox.StubOutWithMock(domain, 'XMLDesc')
|
||||||
|
domain.XMLDesc(0).AndReturn(dom_xml)
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
interfaces = self.pollster._get_vnics(conn, self.instance)
|
||||||
|
self.assertTrue('vnet1' in [x['name'] for x in interfaces])
|
||||||
|
self.assertTrue('fa:16:3e:71:ec:6d', [x['mac'] for x in interfaces])
|
||||||
|
self.assertTrue([x['dhcpserver'] for x in interfaces])
|
||||||
|
|
||||||
|
def test_get_counters(self):
|
||||||
|
interface_stats1 = (3876L, 15L, 0L, 0L, 15830L, 0L, 0L, 0L)
|
||||||
|
interface_stats2 = (9999L, 99L, 0L, 0L, 88888L, 0L, 0L, 0L)
|
||||||
|
vnics = [
|
||||||
|
{'name': 'vnet0',
|
||||||
|
'ip': '10.0.0.2',
|
||||||
|
'projmask': '255.255.255.0',
|
||||||
|
'projnet': 'proj1',
|
||||||
|
'fref': 'nova-instance-instance-00000001-fa163e71ec6e',
|
||||||
|
'bridge': 'br100',
|
||||||
|
'dhcp_server': '10.0.0.1',
|
||||||
|
'alias': 'net0',
|
||||||
|
'mac': 'fa:16:3e:71:ec:6d'},
|
||||||
|
{'name': 'vnet1',
|
||||||
|
'ip': '192.168.0.3',
|
||||||
|
'projmask': '255.255.255.0',
|
||||||
|
'projnet': 'proj2',
|
||||||
|
'fref': 'nova-instance-instance-00000001-fa163e71ec6f',
|
||||||
|
'bridge': 'br100',
|
||||||
|
'dhcp_server': '192.168.0.1',
|
||||||
|
'fref': '00:00:00:01:1e',
|
||||||
|
'alias': 'net1',
|
||||||
|
'mac': 'fa:16:3e:71:ec:6e'}
|
||||||
|
]
|
||||||
|
|
||||||
|
ignore = mox.IgnoreArg()
|
||||||
|
conn = self.mox.CreateMockAnything()
|
||||||
|
conn._conn = self.mox.CreateMockAnything()
|
||||||
|
domain = self.mox.CreateMockAnything()
|
||||||
|
self.mox.StubOutWithMock(libvirt, 'get_libvirt_connection')
|
||||||
|
libvirt.get_libvirt_connection().AndReturn(conn)
|
||||||
|
self.mox.StubOutWithMock(self.pollster, '_get_vnics')
|
||||||
|
self.pollster._get_vnics(ignore, ignore).AndReturn(vnics)
|
||||||
|
self.mox.StubOutWithMock(conn._conn, 'lookupByName')
|
||||||
|
conn._conn.lookupByName(self.instance.name).AndReturn(domain)
|
||||||
|
self.mox.StubOutWithMock(domain, 'interfaceStats')
|
||||||
|
domain.interfaceStats('vnet0').AndReturn(interface_stats1)
|
||||||
|
domain.interfaceStats('vnet1').AndReturn(interface_stats2)
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
results = list(self.pollster.get_counters(self.manager, self.instance))
|
||||||
|
self.assertTrue([countr.resource_metadata['ip'] for countr in results])
|
||||||
|
self.assertTrue([countr.resource_id for countr in results])
|
||||||
|
Loading…
Reference in New Issue
Block a user