[virt-tools-list] [PATCH 1/2] domain: Prepare domain for new stats API

Simon Kobyda skobyda at redhat.com
Fri Sep 7 11:52:41 UTC 2018


Only thing which was actually changed was adding several if-else
of whetever use stats passed to domain class or use the old method
of gathering stats.
@stats - statistics dictionary (derived from return value of
virConnectGetAllDomainStats). If this dictionary is empty, old
methods for gathering statistics shall be used.

Signed-off-by: Simon Kobyda <skobyda at redhat.com>
---
 virtManager/domain.py | 176 +++++++++++++++++++++++++-----------------
 1 file changed, 106 insertions(+), 70 deletions(-)

diff --git a/virtManager/domain.py b/virtManager/domain.py
index 5039e7c2..4ac19cf8 100644
--- a/virtManager/domain.py
+++ b/virtManager/domain.py
@@ -1539,10 +1539,10 @@ class vmmDomain(vmmLibvirtObject):
     # Stats helpers #
     #################
 
-    def _sample_cpu_stats(self, info, now):
+    def _sample_cpu_stats(self, info, now, stats):
         if not self._enable_cpu_stats:
             return 0, 0, 0, 0
-        if not info:
+        if not info and not stats:
             info = self._backend.info()
 
         prevCpuTime = 0
@@ -1556,11 +1556,21 @@ class vmmDomain(vmmLibvirtObject):
             prevTimestamp = self._stats[0]["timestamp"]
             prevCpuTime = self._stats[0]["cpuTimeAbs"]
 
-        if not (info[0] in [libvirt.VIR_DOMAIN_SHUTOFF,
+        if stats:
+            state = stats["state.state"]
+        else:
+            state = info[0]
+        if not (state in [libvirt.VIR_DOMAIN_SHUTOFF,
                             libvirt.VIR_DOMAIN_CRASHED]):
-            guestcpus = info[3]
-            cpuTime = info[4] - prevCpuTime
-            cpuTimeAbs = info[4]
+            if stats:
+                guestcpus = stats["vcpu.current"]
+                cpuTime = stats["cpu.time"] - prevCpuTime
+                cpuTimeAbs = stats["cpu.time"]
+            else:
+                guestcpus = info[3]
+                cpuTime = info[4] - prevCpuTime
+                cpuTimeAbs = info[4]
+
             hostcpus = self.conn.host_active_processor_count()
 
             pcentbase = (((cpuTime) * 100.0) /
@@ -1781,7 +1791,7 @@ class vmmDomain(vmmLibvirtObject):
     # Polling helpers #
     ###################
 
-    def _sample_network_traffic(self):
+    def _sample_network_traffic(self, stats):
         rx = 0
         tx = 0
         if (not self._stats_net_supported or
@@ -1790,7 +1800,7 @@ class vmmDomain(vmmLibvirtObject):
             self._stats_net_skip = []
             return rx, tx
 
-        for netdev in self.get_interface_devices_norefresh():
+        for i, netdev in enumerate(self.get_interface_devices_norefresh()):
             dev = netdev.target_dev
             if not dev:
                 continue
@@ -1798,28 +1808,32 @@ class vmmDomain(vmmLibvirtObject):
             if dev in self._stats_net_skip:
                 continue
 
-            try:
-                io = self._backend.interfaceStats(dev)
-                if io:
-                    rx += io[0]
-                    tx += io[4]
-            except libvirt.libvirtError as err:
-                if util.is_error_nosupport(err):
-                    logging.debug("Net stats not supported: %s", err)
-                    self._stats_net_supported = False
-                else:
-                    logging.error("Error reading net stats for "
-                                  "'%s' dev '%s': %s",
-                                  self.get_name(), dev, err)
-                    if self.is_active():
-                        logging.debug("Adding %s to skip list", dev)
-                        self._stats_net_skip.append(dev)
+            if stats:
+                rx += stats["net." + str(i) + ".rx.bytes"]
+                tx += stats["net." + str(i) + ".tx.bytes"]
+            else:
+                try:
+                    io = self._backend.interfaceStats(dev)
+                    if io:
+                        rx += io[0]
+                        tx += io[4]
+                except libvirt.libvirtError as err:
+                    if util.is_error_nosupport(err):
+                        logging.debug("Net stats not supported: %s", err)
+                        self._stats_net_supported = False
                     else:
-                        logging.debug("Aren't running, don't add to skiplist")
+                        logging.error("Error reading net stats for "
+                                      "'%s' dev '%s': %s",
+                                      self.get_name(), dev, err)
+                        if self.is_active():
+                            logging.debug("Adding %s to skip list", dev)
+                            self._stats_net_skip.append(dev)
+                        else:
+                            logging.debug("Aren't running, don't add to skiplist")
 
         return rx, tx
 
-    def _sample_disk_io(self):
+    def _sample_disk_io(self, stats):
         rd = 0
         wr = 0
         if (not self._stats_disk_supported or
@@ -1830,17 +1844,22 @@ class vmmDomain(vmmLibvirtObject):
 
         # Some drivers support this method for getting all usage at once
         if not self._summary_disk_stats_skip:
-            try:
-                io = self._backend.blockStats('')
-                if io:
-                    rd = io[1]
-                    wr = io[3]
-                    return rd, wr
-            except libvirt.libvirtError:
-                self._summary_disk_stats_skip = True
+            if stats:
+                rd = stats["block.0.rd.bytes"]
+                wr = stats["block.0.wr.bytes"]
+                return rd, wr
+            else:
+                try:
+                    io = self._backend.blockStats('')
+                    if io:
+                        rd = io[1]
+                        wr = io[3]
+                        return rd, wr
+                except libvirt.libvirtError:
+                    self._summary_disk_stats_skip = True
 
         # did not work, iterate over all disks
-        for disk in self.get_disk_devices_norefresh():
+        for i, disk in enumerate(self.get_disk_devices_norefresh()):
             dev = disk.target
             if not dev:
                 continue
@@ -1848,24 +1867,27 @@ class vmmDomain(vmmLibvirtObject):
             if dev in self._stats_disk_skip:
                 continue
 
-            try:
-                io = self._backend.blockStats(dev)
-                if io:
-                    rd += io[1]
-                    wr += io[3]
-            except libvirt.libvirtError as err:
-                if util.is_error_nosupport(err):
-                    logging.debug("Disk stats not supported: %s", err)
-                    self._stats_disk_supported = False
-                else:
-                    logging.error("Error reading disk stats for "
-                                  "'%s' dev '%s': %s",
-                                  self.get_name(), dev, err)
-                    if self.is_active():
-                        logging.debug("Adding %s to skip list", dev)
-                        self._stats_disk_skip.append(dev)
+            if stats:
+                rd = stats["block." + str(i) + ".rd.bytes"]
+                wr = stats["block." + str(i) + ".wr.bytes"]
+                try:
+                    io = self._backend.blockStats(dev)
+                    if io:
+                        rd += io[1]
+                        wr += io[3]
+                except libvirt.libvirtError as err:
+                    if util.is_error_nosupport(err):
+                        logging.debug("Disk stats not supported: %s", err)
+                        self._stats_disk_supported = False
                     else:
-                        logging.debug("Aren't running, don't add to skiplist")
+                        logging.error("Error reading disk stats for "
+                                      "'%s' dev '%s': %s",
+                                      self.get_name(), dev, err)
+                        if self.is_active():
+                            logging.debug("Adding %s to skip list", dev)
+                            self._stats_disk_skip.append(dev)
+                        else:
+                            logging.debug("Aren't running, don't add to skiplist")
 
         return rd, wr
 
@@ -1888,7 +1910,7 @@ class vmmDomain(vmmLibvirtObject):
         except Exception as e:
             logging.debug("Error setting memstats period: %s", e)
 
-    def _sample_mem_stats(self):
+    def _sample_mem_stats(self, stats):
         if (not self.mem_stats_supported or
             not self._enable_mem_stats or
             not self.is_active()):
@@ -1901,15 +1923,22 @@ class vmmDomain(vmmLibvirtObject):
 
         curmem = 0
         totalmem = 1
-        try:
-            stats = self._backend.memoryStats()
-            totalmem = stats.get("actual", 1)
-            curmem = stats.get("rss", 0)
+        if stats:
+                totalmem = stats.get("balloon.current", 1)
+                curmem = stats.get("balloon.rss", 0)
+
+                if "unused" in stats:
+                    curmem = max(0, totalmem - stats.get("unused", totalmem))
+        else:
+            try:
+                stats = self._backend.memoryStats()
+                totalmem = stats.get("actual", 1)
+                curmem = stats.get("rss", 0)
 
-            if "unused" in stats:
-                curmem = max(0, totalmem - stats.get("unused", totalmem))
-        except libvirt.libvirtError as err:
-            logging.error("Error reading mem stats: %s", err)
+                if "unused" in stats:
+                    curmem = max(0, totalmem - stats.get("unused", totalmem))
+            except libvirt.libvirtError as err:
+                logging.error("Error reading mem stats: %s", err)
 
         pcentCurrMem = (curmem / float(totalmem)) * 100
         pcentCurrMem = max(0.0, min(pcentCurrMem, 100.0))
@@ -1917,10 +1946,12 @@ class vmmDomain(vmmLibvirtObject):
         return pcentCurrMem, curmem
 
 
-    def tick(self, stats_update=True):
+    def tick(self, stats_update=True, stats=None):
         if (not self._using_events() and
             not stats_update):
             return
+        if stats is None:
+            stats = []
 
         info = []
         dosignal = False
@@ -1929,17 +1960,22 @@ class vmmDomain(vmmLibvirtObject):
             # the latest XML, but other objects probably don't want to do
             # this since it could be a performance hit.
             self._invalidate_xml()
-            info = self._backend.info()
-            dosignal = self._refresh_status(newstatus=info[0], cansignal=False)
+            if stats:
+                dosignal = self._refresh_status(stats["state.state"], cansignal=False)
+            else:
+                info = self._backend.info()
+                dosignal = self._refresh_status(newstatus=info[0], cansignal=False)
 
         if stats_update:
-            self._tick_stats(info)
+            self._tick_stats(info, stats)
         if dosignal:
             self.idle_emit("state-changed")
         if stats_update:
             self.idle_emit("resources-sampled")
 
-    def _tick_stats(self, info):
+    def _tick_stats(self, info, stats=None):
+        if stats is None:
+            stats = []
         expected = self.config.get_stats_history_length()
         current = len(self._stats)
         if current > expected:
@@ -1947,10 +1983,10 @@ class vmmDomain(vmmLibvirtObject):
 
         now = time.time()
         (cpuTime, cpuTimeAbs,
-         pcentHostCpu, pcentGuestCpu) = self._sample_cpu_stats(info, now)
-        pcentCurrMem, curmem = self._sample_mem_stats()
-        rdBytes, wrBytes = self._sample_disk_io()
-        rxBytes, txBytes = self._sample_network_traffic()
+         pcentHostCpu, pcentGuestCpu) = self._sample_cpu_stats(info, now, stats)
+        pcentCurrMem, curmem = self._sample_mem_stats(stats)
+        rdBytes, wrBytes = self._sample_disk_io(stats)
+        rxBytes, txBytes = self._sample_network_traffic(stats)
 
         newStats = {
             "timestamp": now,
-- 
2.17.1




More information about the virt-tools-list mailing list