The variable "stats" and the functions "_update_guest_stats",
"_get_disk_io_rate", "_get_percentage_cpu_usage" and
"_get_network_io_rate", declared in src/kimchi/model/vms.py, are related
to a single instance of a VM, so it makes more sense to move them to the
class VMModel.
Move the variable "stats" and the stats-related functions from
global/static to VMModel.
Signed-off-by: Crístian Deives <cristiandeives(a)gmail.com>
---
src/kimchi/model/vms.py | 203 +++++++++++++++++++++++-------------------------
1 file changed, 99 insertions(+), 104 deletions(-)
diff --git a/src/kimchi/model/vms.py b/src/kimchi/model/vms.py
index 9c1f308..154ae3e 100644
--- a/src/kimchi/model/vms.py
+++ b/src/kimchi/model/vms.py
@@ -63,8 +63,6 @@ VM_STATIC_UPDATE_PARAMS = {'name': './name',
'memory': './memory'}
VM_LIVE_UPDATE_PARAMS = {}
-stats = {}
-
XPATH_DOMAIN_DISK =
"/domain/devices/disk[@device='disk']/source/@file"
XPATH_DOMAIN_DISK_BY_FILE =
"./devices/disk[@device='disk']/source[@file='%s']"
XPATH_DOMAIN_NAME = '/domain/name'
@@ -82,105 +80,6 @@ class VMsModel(object):
self.objstore = kargs['objstore']
self.caps = CapabilitiesModel(**kargs)
- @staticmethod
- def _update_guest_stats(name, conn):
- try:
- dom = VMModel.get_vm(name, conn)
-
- vm_uuid = dom.UUIDString()
- info = dom.info()
- state = DOM_STATE_MAP[info[0]]
-
- if state != 'running':
- stats[vm_uuid] = {}
- return
-
- if stats.get(vm_uuid, None) is None:
- stats[vm_uuid] = {}
-
- timestamp = time.time()
- prevStats = stats.get(vm_uuid, {})
- seconds = timestamp - prevStats.get('timestamp', 0)
- stats[vm_uuid].update({'timestamp': timestamp})
-
- VMsModel._get_percentage_cpu_usage(vm_uuid, info, seconds)
- VMsModel._get_network_io_rate(vm_uuid, dom, seconds)
- VMsModel._get_disk_io_rate(vm_uuid, dom, seconds)
- except Exception as e:
- # VM might be deleted just after we get the list.
- # This is OK, just skip.
- kimchi_log.debug('Error processing VM stats: %s', e.message)
-
- @staticmethod
- def _get_percentage_cpu_usage(vm_uuid, info, seconds):
- prevCpuTime = stats[vm_uuid].get('cputime', 0)
-
- cpus = info[3]
- cpuTime = info[4] - prevCpuTime
-
- base = (((cpuTime) * 100.0) / (seconds * 1000.0 * 1000.0 * 1000.0))
- percentage = max(0.0, min(100.0, base / cpus))
-
- stats[vm_uuid].update({'cputime': info[4], 'cpu': percentage})
-
- @staticmethod
- def _get_network_io_rate(vm_uuid, dom, seconds):
- prevNetRxKB = stats[vm_uuid].get('netRxKB', 0)
- prevNetTxKB = stats[vm_uuid].get('netTxKB', 0)
- currentMaxNetRate = stats[vm_uuid].get('max_net_io', 100)
-
- rx_bytes = 0
- tx_bytes = 0
-
- tree = ElementTree.fromstring(dom.XMLDesc(0))
- for target in tree.findall('devices/interface/target'):
- dev = target.get('dev')
- io = dom.interfaceStats(dev)
- rx_bytes += io[0]
- tx_bytes += io[4]
-
- netRxKB = float(rx_bytes) / 1000
- netTxKB = float(tx_bytes) / 1000
-
- rx_stats = (netRxKB - prevNetRxKB) / seconds
- tx_stats = (netTxKB - prevNetTxKB) / seconds
-
- rate = rx_stats + tx_stats
- max_net_io = round(max(currentMaxNetRate, int(rate)), 1)
-
- stats[vm_uuid].update({'net_io': rate, 'max_net_io': max_net_io,
- 'netRxKB': netRxKB, 'netTxKB': netTxKB})
-
- @staticmethod
- def _get_disk_io_rate(vm_uuid, dom, seconds):
- prevDiskRdKB = stats[vm_uuid].get('diskRdKB', 0)
- prevDiskWrKB = stats[vm_uuid].get('diskWrKB', 0)
- currentMaxDiskRate = stats[vm_uuid].get('max_disk_io', 100)
-
- rd_bytes = 0
- wr_bytes = 0
-
- tree = ElementTree.fromstring(dom.XMLDesc(0))
- for target in tree.findall("devices/disk/target"):
- dev = target.get("dev")
- io = dom.blockStats(dev)
- rd_bytes += io[1]
- wr_bytes += io[3]
-
- diskRdKB = float(rd_bytes) / 1024
- diskWrKB = float(wr_bytes) / 1024
-
- rd_stats = (diskRdKB - prevDiskRdKB) / seconds
- wr_stats = (diskWrKB - prevDiskWrKB) / seconds
-
- rate = rd_stats + wr_stats
- max_disk_io = round(max(currentMaxDiskRate, int(rate)), 1)
-
- stats[vm_uuid].update({'disk_io': rate,
- 'max_disk_io': max_disk_io,
- 'diskRdKB': diskRdKB,
- 'diskWrKB': diskWrKB})
-
def create(self, params):
conn = self.conn.get()
t_name = template_name_from_uri(params['template'])
@@ -273,6 +172,7 @@ class VMModel(object):
self.vmsnapshot = cls(**kargs)
cls = import_class('kimchi.model.vmsnapshots.VMSnapshotsModel')
self.vmsnapshots = cls(**kargs)
+ self.stats = {}
def update(self, name, params):
dom = self.get_vm(name, self.conn)
@@ -793,6 +693,101 @@ class VMModel(object):
dom = ElementTree.fromstring(dom.XMLDesc(0))
return dom.find('devices/video') is not None
+ def _update_guest_stats(self, name):
+ try:
+ dom = VMModel.get_vm(name, self.conn)
+
+ vm_uuid = dom.UUIDString()
+ info = dom.info()
+ state = DOM_STATE_MAP[info[0]]
+
+ if state != 'running':
+ self.stats[vm_uuid] = {}
+ return
+
+ if self.stats.get(vm_uuid, None) is None:
+ self.stats[vm_uuid] = {}
+
+ timestamp = time.time()
+ prevStats = self.stats.get(vm_uuid, {})
+ seconds = timestamp - prevStats.get('timestamp', 0)
+ self.stats[vm_uuid].update({'timestamp': timestamp})
+
+ self._get_percentage_cpu_usage(vm_uuid, info, seconds)
+ self._get_network_io_rate(vm_uuid, dom, seconds)
+ self._get_disk_io_rate(vm_uuid, dom, seconds)
+ except Exception as e:
+ # VM might be deleted just after we get the list.
+ # This is OK, just skip.
+ kimchi_log.debug('Error processing VM stats: %s', e.message)
+
+ def _get_percentage_cpu_usage(self, vm_uuid, info, seconds):
+ prevCpuTime = self.stats[vm_uuid].get('cputime', 0)
+
+ cpus = info[3]
+ cpuTime = info[4] - prevCpuTime
+
+ base = (((cpuTime) * 100.0) / (seconds * 1000.0 * 1000.0 * 1000.0))
+ percentage = max(0.0, min(100.0, base / cpus))
+
+ self.stats[vm_uuid].update({'cputime': info[4], 'cpu':
percentage})
+
+ def _get_network_io_rate(self, vm_uuid, dom, seconds):
+ prevNetRxKB = self.stats[vm_uuid].get('netRxKB', 0)
+ prevNetTxKB = self.stats[vm_uuid].get('netTxKB', 0)
+ currentMaxNetRate = self.stats[vm_uuid].get('max_net_io', 100)
+
+ rx_bytes = 0
+ tx_bytes = 0
+
+ tree = ElementTree.fromstring(dom.XMLDesc(0))
+ for target in tree.findall('devices/interface/target'):
+ dev = target.get('dev')
+ io = dom.interfaceStats(dev)
+ rx_bytes += io[0]
+ tx_bytes += io[4]
+
+ netRxKB = float(rx_bytes) / 1000
+ netTxKB = float(tx_bytes) / 1000
+
+ rx_stats = (netRxKB - prevNetRxKB) / seconds
+ tx_stats = (netTxKB - prevNetTxKB) / seconds
+
+ rate = rx_stats + tx_stats
+ max_net_io = round(max(currentMaxNetRate, int(rate)), 1)
+
+ self.stats[vm_uuid].update({'net_io': rate, 'max_net_io':
max_net_io,
+ 'netRxKB': netRxKB, 'netTxKB':
netTxKB})
+
+ def _get_disk_io_rate(self, vm_uuid, dom, seconds):
+ prevDiskRdKB = self.stats[vm_uuid].get('diskRdKB', 0)
+ prevDiskWrKB = self.stats[vm_uuid].get('diskWrKB', 0)
+ currentMaxDiskRate = self.stats[vm_uuid].get('max_disk_io', 100)
+
+ rd_bytes = 0
+ wr_bytes = 0
+
+ tree = ElementTree.fromstring(dom.XMLDesc(0))
+ for target in tree.findall("devices/disk/target"):
+ dev = target.get("dev")
+ io = dom.blockStats(dev)
+ rd_bytes += io[1]
+ wr_bytes += io[3]
+
+ diskRdKB = float(rd_bytes) / 1024
+ diskWrKB = float(wr_bytes) / 1024
+
+ rd_stats = (diskRdKB - prevDiskRdKB) / seconds
+ wr_stats = (diskWrKB - prevDiskWrKB) / seconds
+
+ rate = rd_stats + wr_stats
+ max_disk_io = round(max(currentMaxDiskRate, int(rate)), 1)
+
+ self.stats[vm_uuid].update({'disk_io': rate,
+ 'max_disk_io': max_disk_io,
+ 'diskRdKB': diskRdKB,
+ 'diskWrKB': diskWrKB})
+
def lookup(self, name):
dom = self.get_vm(name, self.conn)
info = dom.info()
@@ -808,7 +803,7 @@ class VMModel(object):
elif state == 'shutoff':
# reset vm stats when it is powered off to avoid sending
# incorrect (old) data
- stats[dom.UUIDString()] = {}
+ self.stats[dom.UUIDString()] = {}
except NotFoundError:
pass
@@ -819,8 +814,8 @@ class VMModel(object):
extra_info = {}
icon = extra_info.get('icon')
- VMsModel._update_guest_stats(name, self.conn.get())
- vm_stats = stats.get(dom.UUIDString(), {})
+ self._update_guest_stats(name)
+ vm_stats = self.stats.get(dom.UUIDString(), {})
res = {}
res['cpu_utilization'] = vm_stats.get('cpu', 0)
res['net_throughput'] = vm_stats.get('net_io', 0)
--
2.1.0