[Kimchi-devel] [PATCH 2/2] Move stats-related VM functions to VMModel

Crístian Deives cristiandeives at gmail.com
Thu Apr 9 01:37:32 UTC 2015


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 at 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




More information about the Kimchi-devel mailing list