mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-07-07 12:58:58 +03:00
statsmanager: Absorb more domain stats handling
This commit is contained in:
@ -211,14 +211,6 @@ class vmmDomain(vmmLibvirtObject):
|
|||||||
|
|
||||||
self.cloning = False
|
self.cloning = False
|
||||||
|
|
||||||
self.stats = []
|
|
||||||
self._stats_rates = {
|
|
||||||
"diskRdRate": 10.0,
|
|
||||||
"diskWrRate": 10.0,
|
|
||||||
"netTxRate": 10.0,
|
|
||||||
"netRxRate": 10.0,
|
|
||||||
}
|
|
||||||
|
|
||||||
self._install_abort = False
|
self._install_abort = False
|
||||||
self._id = None
|
self._id = None
|
||||||
self._uuid = None
|
self._uuid = None
|
||||||
@ -232,10 +224,6 @@ class vmmDomain(vmmLibvirtObject):
|
|||||||
self.managedsave_supported = False
|
self.managedsave_supported = False
|
||||||
self._domain_state_supported = False
|
self._domain_state_supported = False
|
||||||
|
|
||||||
self.stats_net_skip = []
|
|
||||||
self.stats_disk_skip = []
|
|
||||||
self.summary_disk_stats_skip = False
|
|
||||||
|
|
||||||
self.inspection = vmmInspectionData()
|
self.inspection = vmmInspectionData()
|
||||||
|
|
||||||
def _cleanup(self):
|
def _cleanup(self):
|
||||||
@ -258,7 +246,8 @@ class vmmDomain(vmmLibvirtObject):
|
|||||||
# Prime caches
|
# Prime caches
|
||||||
info = self._backend.info()
|
info = self._backend.info()
|
||||||
self._refresh_status(newstatus=info[0])
|
self._refresh_status(newstatus=info[0])
|
||||||
self._tick_stats()
|
# XXX _tick_stats
|
||||||
|
# self._tick_stats()
|
||||||
self.has_managed_save()
|
self.has_managed_save()
|
||||||
self.snapshots_supported()
|
self.snapshots_supported()
|
||||||
|
|
||||||
@ -1512,95 +1501,52 @@ class vmmDomain(vmmLibvirtObject):
|
|||||||
# Don't schedule any conn update, migrate dialog handles it for us
|
# Don't schedule any conn update, migrate dialog handles it for us
|
||||||
|
|
||||||
|
|
||||||
#################
|
|
||||||
# Stats helpers #
|
|
||||||
#################
|
|
||||||
|
|
||||||
def _get_cur_rate(self, what):
|
|
||||||
if len(self.stats) > 1:
|
|
||||||
ret = (float(self.stats[0][what] -
|
|
||||||
self.stats[1][what]) /
|
|
||||||
float(self.stats[0]["timestamp"] -
|
|
||||||
self.stats[1]["timestamp"]))
|
|
||||||
else:
|
|
||||||
ret = 0.0
|
|
||||||
return max(ret, 0, 0) # avoid negative values at poweroff
|
|
||||||
|
|
||||||
def _set_max_rate(self, record, what):
|
|
||||||
if record[what] > self._stats_rates[what]:
|
|
||||||
self._stats_rates[what] = record[what]
|
|
||||||
def _get_max_rate(self, name1, name2):
|
|
||||||
return float(max(self._stats_rates[name1], self._stats_rates[name2]))
|
|
||||||
|
|
||||||
def _get_record_helper(self, record_name):
|
|
||||||
if len(self.stats) == 0:
|
|
||||||
return 0
|
|
||||||
return self.stats[0][record_name]
|
|
||||||
|
|
||||||
def _vector_helper(self, record_name, limit, ceil=100.0):
|
|
||||||
vector = []
|
|
||||||
statslen = self.config.get_stats_history_length() + 1
|
|
||||||
if limit is not None:
|
|
||||||
statslen = min(statslen, limit)
|
|
||||||
|
|
||||||
for i in range(statslen):
|
|
||||||
if i < len(self.stats):
|
|
||||||
vector.append(self.stats[i][record_name] / ceil)
|
|
||||||
else:
|
|
||||||
vector.append(0)
|
|
||||||
|
|
||||||
return vector
|
|
||||||
|
|
||||||
def _in_out_vector_helper(self, name1, name2, limit, ceil):
|
|
||||||
if ceil is None:
|
|
||||||
ceil = self._get_max_rate(name1, name2)
|
|
||||||
|
|
||||||
return (self._vector_helper(name1, limit, ceil=ceil),
|
|
||||||
self._vector_helper(name2, limit, ceil=ceil))
|
|
||||||
|
|
||||||
|
|
||||||
###################
|
###################
|
||||||
# Stats accessors #
|
# Stats accessors #
|
||||||
###################
|
###################
|
||||||
|
|
||||||
|
def _get_stats(self):
|
||||||
|
return self.conn.statsmanager.get_vm_statslist(self)
|
||||||
def stats_memory(self):
|
def stats_memory(self):
|
||||||
return self._get_record_helper("curmem")
|
return self._get_stats().get_record("curmem")
|
||||||
def cpu_time(self):
|
def cpu_time(self):
|
||||||
return self._get_record_helper("cpuTime")
|
return self._get_stats().get_record("cpuTime")
|
||||||
def host_cpu_time_percentage(self):
|
def host_cpu_time_percentage(self):
|
||||||
return self._get_record_helper("cpuHostPercent")
|
return self._get_stats().get_record("cpuHostPercent")
|
||||||
def guest_cpu_time_percentage(self):
|
def guest_cpu_time_percentage(self):
|
||||||
return self._get_record_helper("cpuGuestPercent")
|
return self._get_stats().get_record("cpuGuestPercent")
|
||||||
def network_rx_rate(self):
|
def network_rx_rate(self):
|
||||||
return self._get_record_helper("netRxRate")
|
return self._get_stats().get_record("netRxRate")
|
||||||
def network_tx_rate(self):
|
def network_tx_rate(self):
|
||||||
return self._get_record_helper("netTxRate")
|
return self._get_stats().get_record("netTxRate")
|
||||||
def disk_read_rate(self):
|
def disk_read_rate(self):
|
||||||
return self._get_record_helper("diskRdRate")
|
return self._get_stats().get_record("diskRdRate")
|
||||||
def disk_write_rate(self):
|
def disk_write_rate(self):
|
||||||
return self._get_record_helper("diskWrRate")
|
return self._get_stats().get_record("diskWrRate")
|
||||||
|
|
||||||
def network_traffic_rate(self):
|
def network_traffic_rate(self):
|
||||||
return self.network_tx_rate() + self.network_rx_rate()
|
return self.network_tx_rate() + self.network_rx_rate()
|
||||||
def network_traffic_max_rate(self):
|
def network_traffic_max_rate(self):
|
||||||
return self._get_max_rate("netRxRate", "netTxRate")
|
stats = self._get_stats()
|
||||||
|
return max(stats.netRxMaxRate, stats.netTxMaxRate)
|
||||||
def disk_io_rate(self):
|
def disk_io_rate(self):
|
||||||
return self.disk_read_rate() + self.disk_write_rate()
|
return self.disk_read_rate() + self.disk_write_rate()
|
||||||
def disk_io_max_rate(self):
|
def disk_io_max_rate(self):
|
||||||
return self._get_max_rate("diskRdRate", "diskWrRate")
|
stats = self._get_stats()
|
||||||
|
return max(stats.diskRdMaxRate, stats.diskWrMaxRate)
|
||||||
|
|
||||||
def host_cpu_time_vector(self, limit=None):
|
def host_cpu_time_vector(self, limit=None):
|
||||||
return self._vector_helper("cpuHostPercent", limit)
|
return self._get_stats().get_vector("cpuHostPercent", limit)
|
||||||
def guest_cpu_time_vector(self, limit=None):
|
def guest_cpu_time_vector(self, limit=None):
|
||||||
return self._vector_helper("cpuGuestPercent", limit)
|
return self._get_stats().get_vector("cpuGuestPercent", limit)
|
||||||
def stats_memory_vector(self, limit=None):
|
def stats_memory_vector(self, limit=None):
|
||||||
return self._vector_helper("currMemPercent", limit)
|
return self._get_stats().get_vector("currMemPercent", limit)
|
||||||
def network_traffic_vectors(self, limit=None, ceil=None):
|
def network_traffic_vectors(self, limit=None, ceil=None):
|
||||||
return self._in_out_vector_helper(
|
return self._get_stats().get_in_out_vector(
|
||||||
"netRxRate", "netTxRate", limit, ceil)
|
"netRxRate", "netTxRate", limit, ceil)
|
||||||
def disk_io_vectors(self, limit=None, ceil=None):
|
def disk_io_vectors(self, limit=None, ceil=None):
|
||||||
return self._in_out_vector_helper(
|
return self._get_stats().get_in_out_vector(
|
||||||
"diskRdRate", "diskWrRate", limit, ceil)
|
"diskRdRate", "diskWrRate", limit, ceil)
|
||||||
|
|
||||||
|
|
||||||
###################
|
###################
|
||||||
@ -1727,26 +1673,12 @@ class vmmDomain(vmmLibvirtObject):
|
|||||||
dosignal = self._refresh_status(newstatus=info[0], cansignal=False)
|
dosignal = self._refresh_status(newstatus=info[0], cansignal=False)
|
||||||
|
|
||||||
if stats_update:
|
if stats_update:
|
||||||
self._tick_stats()
|
self.conn.statsmanager.refresh_vm_stats(self)
|
||||||
if dosignal:
|
if dosignal:
|
||||||
self.idle_emit("state-changed")
|
self.idle_emit("state-changed")
|
||||||
if stats_update:
|
if stats_update:
|
||||||
self.idle_emit("resources-sampled")
|
self.idle_emit("resources-sampled")
|
||||||
|
|
||||||
def _tick_stats(self):
|
|
||||||
expected = self.config.get_stats_history_length()
|
|
||||||
current = len(self.stats)
|
|
||||||
if current > expected:
|
|
||||||
del self.stats[expected:current]
|
|
||||||
|
|
||||||
newStats = self.conn.statsmanager.refresh_vm_stats(self)
|
|
||||||
|
|
||||||
for r in ["diskRd", "diskWr", "netRx", "netTx"]:
|
|
||||||
newStats[r + "Rate"] = self._get_cur_rate(r + "KiB")
|
|
||||||
self._set_max_rate(newStats, r + "Rate")
|
|
||||||
|
|
||||||
self.stats.insert(0, newStats)
|
|
||||||
|
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# Libvirt domain class #
|
# Libvirt domain class #
|
||||||
|
@ -14,12 +14,115 @@ from virtinst import util
|
|||||||
from .baseclass import vmmGObject
|
from .baseclass import vmmGObject
|
||||||
|
|
||||||
|
|
||||||
|
class _VMStatsRecord(object):
|
||||||
|
"""
|
||||||
|
Tracks a set of VM stats for a single timestamp
|
||||||
|
"""
|
||||||
|
def __init__(self, timestamp,
|
||||||
|
cpuTime, cpuTimeAbs,
|
||||||
|
cpuHostPercent, cpuGuestPercent,
|
||||||
|
curmem, currMemPercent,
|
||||||
|
diskRdBytes, diskWrBytes,
|
||||||
|
netRxBytes, netTxBytes):
|
||||||
|
self.timestamp = timestamp
|
||||||
|
self.cpuTime = cpuTime
|
||||||
|
self.cpuTimeAbs = cpuTimeAbs
|
||||||
|
self.cpuHostPercent = cpuHostPercent
|
||||||
|
self.cpuGuestPercent = cpuGuestPercent
|
||||||
|
self.curmem = curmem
|
||||||
|
self.currMemPercent = currMemPercent
|
||||||
|
self.diskRdKiB = diskRdBytes // 1024
|
||||||
|
self.diskWrKiB = diskWrBytes // 1024
|
||||||
|
self.netRxKiB = netRxBytes // 1024
|
||||||
|
self.netTxKiB = netTxBytes // 1024
|
||||||
|
|
||||||
|
# These are set in _VMStatsList.append_stats
|
||||||
|
self.diskRdRate = None
|
||||||
|
self.diskWrRate = None
|
||||||
|
self.netRxRate = None
|
||||||
|
self.netTxRate = None
|
||||||
|
|
||||||
|
|
||||||
|
class _VMStatsList(vmmGObject):
|
||||||
|
"""
|
||||||
|
Tracks a list of VMStatsRecords for a single VM
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
vmmGObject.__init__(self)
|
||||||
|
self._stats = []
|
||||||
|
|
||||||
|
self.diskRdMaxRate = 10.0
|
||||||
|
self.diskWrMaxRate = 10.0
|
||||||
|
self.netRxMaxRate = 10.0
|
||||||
|
self.netTxMaxRate = 10.0
|
||||||
|
|
||||||
|
self.mem_stats_period_is_set = False
|
||||||
|
self.stats_disk_skip = []
|
||||||
|
self.stats_net_skip = []
|
||||||
|
|
||||||
|
def _cleanup(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def append_stats(self, newstats):
|
||||||
|
expected = self.config.get_stats_history_length()
|
||||||
|
current = len(self._stats)
|
||||||
|
if current > expected:
|
||||||
|
del(self._stats[expected:current])
|
||||||
|
|
||||||
|
def _calculate_rate(record_name):
|
||||||
|
ret = 0.0
|
||||||
|
if self._stats:
|
||||||
|
oldstats = self._stats[0]
|
||||||
|
ratediff = (getattr(newstats, record_name) -
|
||||||
|
getattr(oldstats, record_name))
|
||||||
|
timediff = newstats.timestamp - oldstats.timestamp
|
||||||
|
ret = float(ratediff) / float(timediff)
|
||||||
|
return max(ret, 0.0)
|
||||||
|
|
||||||
|
newstats.diskRdRate = _calculate_rate("diskRdKiB")
|
||||||
|
newstats.diskWrRate = _calculate_rate("diskWrKiB")
|
||||||
|
newstats.netRxRate = _calculate_rate("netRxKiB")
|
||||||
|
newstats.netTxRate = _calculate_rate("netTxKiB")
|
||||||
|
|
||||||
|
self.diskRdMaxRate = max(newstats.diskRdRate, self.diskRdMaxRate)
|
||||||
|
self.diskWrMaxRate = max(newstats.diskWrRate, self.diskWrMaxRate)
|
||||||
|
self.netRxMaxRate = max(newstats.netRxRate, self.netRxMaxRate)
|
||||||
|
self.netTxMaxRate = max(newstats.netTxRate, self.netTxMaxRate)
|
||||||
|
|
||||||
|
self._stats.insert(0, newstats)
|
||||||
|
|
||||||
|
def get_record(self, record_name):
|
||||||
|
if not self._stats:
|
||||||
|
return 0
|
||||||
|
return getattr(self._stats[0], record_name)
|
||||||
|
|
||||||
|
def get_vector(self, record_name, limit, ceil=100.0):
|
||||||
|
vector = []
|
||||||
|
statslen = self.config.get_stats_history_length() + 1
|
||||||
|
if limit is not None:
|
||||||
|
statslen = min(statslen, limit)
|
||||||
|
|
||||||
|
for i in range(statslen):
|
||||||
|
if i < len(self._stats):
|
||||||
|
vector.append(getattr(self._stats[i], record_name) / ceil)
|
||||||
|
else:
|
||||||
|
vector.append(0)
|
||||||
|
return vector
|
||||||
|
|
||||||
|
def get_in_out_vector(self, name1, name2, limit, ceil):
|
||||||
|
if ceil is None:
|
||||||
|
ceil = max(self.get_record(name1), self.get_record(name2), 10.0)
|
||||||
|
return (self.get_vector(name1, limit, ceil=ceil),
|
||||||
|
self.get_vector(name2, limit, ceil=ceil))
|
||||||
|
|
||||||
|
|
||||||
class vmmStatsManager(vmmGObject):
|
class vmmStatsManager(vmmGObject):
|
||||||
"""
|
"""
|
||||||
Class for polling statistics
|
Class for polling statistics
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
vmmGObject.__init__(self)
|
vmmGObject.__init__(self)
|
||||||
|
self._vm_stats = {}
|
||||||
self._latest_all_stats = []
|
self._latest_all_stats = []
|
||||||
self._all_stats_supported = True
|
self._all_stats_supported = True
|
||||||
self._enable_mem_stats = False
|
self._enable_mem_stats = False
|
||||||
@ -31,7 +134,6 @@ class vmmStatsManager(vmmGObject):
|
|||||||
self._disk_stats_supported = True
|
self._disk_stats_supported = True
|
||||||
self._disk_stats_lxc_supported = True
|
self._disk_stats_lxc_supported = True
|
||||||
self._mem_stats_supported = True
|
self._mem_stats_supported = True
|
||||||
self._mem_stats_period_is_set = False
|
|
||||||
|
|
||||||
self._on_config_sample_network_traffic_changed()
|
self._on_config_sample_network_traffic_changed()
|
||||||
self._on_config_sample_disk_io_changed()
|
self._on_config_sample_disk_io_changed()
|
||||||
@ -80,15 +182,11 @@ class vmmStatsManager(vmmGObject):
|
|||||||
if not self._enable_cpu_stats:
|
if not self._enable_cpu_stats:
|
||||||
return 0, 0, 0, 0
|
return 0, 0, 0, 0
|
||||||
|
|
||||||
prevCpuTime = 0
|
|
||||||
prevTimestamp = 0
|
|
||||||
cpuTime = 0
|
cpuTime = 0
|
||||||
pcentHostCpu = 0
|
cpuHostPercent = 0
|
||||||
pcentGuestCpu = 0
|
cpuGuestPercent = 0
|
||||||
|
prevTimestamp = self.get_vm_statslist(vm).get_record("timestamp")
|
||||||
if len(vm.stats) > 0:
|
prevCpuTime = self.get_vm_statslist(vm).get_record("cpuTimeAbs")
|
||||||
prevTimestamp = vm.stats[0]["timestamp"]
|
|
||||||
prevCpuTime = vm.stats[0]["cpuTimeAbs"]
|
|
||||||
|
|
||||||
if allstats:
|
if allstats:
|
||||||
state = allstats.get("state.state", 0)
|
state = allstats.get("state.state", 0)
|
||||||
@ -109,15 +207,15 @@ class vmmStatsManager(vmmGObject):
|
|||||||
|
|
||||||
pcentbase = (((cpuTime) * 100.0) /
|
pcentbase = (((cpuTime) * 100.0) /
|
||||||
((now - prevTimestamp) * 1000.0 * 1000.0 * 1000.0))
|
((now - prevTimestamp) * 1000.0 * 1000.0 * 1000.0))
|
||||||
pcentHostCpu = pcentbase / hostcpus
|
cpuHostPercent = pcentbase / hostcpus
|
||||||
# Under RHEL-5.9 using a XEN HV guestcpus can be 0 during shutdown
|
# Under RHEL-5.9 using a XEN HV guestcpus can be 0 during shutdown
|
||||||
# so play safe and check it.
|
# so play safe and check it.
|
||||||
pcentGuestCpu = guestcpus > 0 and pcentbase / guestcpus or 0
|
cpuGuestPercent = guestcpus > 0 and pcentbase / guestcpus or 0
|
||||||
|
|
||||||
pcentHostCpu = max(0.0, min(100.0, pcentHostCpu))
|
cpuHostPercent = max(0.0, min(100.0, cpuHostPercent))
|
||||||
pcentGuestCpu = max(0.0, min(100.0, pcentGuestCpu))
|
cpuGuestPercent = max(0.0, min(100.0, cpuGuestPercent))
|
||||||
|
|
||||||
return cpuTime, cpuTimeAbs, pcentHostCpu, pcentGuestCpu
|
return cpuTime, cpuTimeAbs, cpuHostPercent, cpuGuestPercent
|
||||||
|
|
||||||
|
|
||||||
######################
|
######################
|
||||||
@ -125,6 +223,7 @@ class vmmStatsManager(vmmGObject):
|
|||||||
######################
|
######################
|
||||||
|
|
||||||
def _old_net_stats_helper(self, vm, dev):
|
def _old_net_stats_helper(self, vm, dev):
|
||||||
|
statslist = self.get_vm_statslist(vm)
|
||||||
try:
|
try:
|
||||||
io = vm.get_backend().interfaceStats(dev)
|
io = vm.get_backend().interfaceStats(dev)
|
||||||
if io:
|
if io:
|
||||||
@ -141,7 +240,7 @@ class vmmStatsManager(vmmGObject):
|
|||||||
vm.get_name(), dev, err)
|
vm.get_name(), dev, err)
|
||||||
if vm.is_active():
|
if vm.is_active():
|
||||||
logging.debug("Adding %s to skip list", dev)
|
logging.debug("Adding %s to skip list", dev)
|
||||||
vm.stats_net_skip.append(dev)
|
statslist.stats_net_skip.append(dev)
|
||||||
else:
|
else:
|
||||||
logging.debug("Aren't running, don't add to skiplist")
|
logging.debug("Aren't running, don't add to skiplist")
|
||||||
|
|
||||||
@ -150,10 +249,11 @@ class vmmStatsManager(vmmGObject):
|
|||||||
def _sample_net_stats(self, vm, allstats):
|
def _sample_net_stats(self, vm, allstats):
|
||||||
rx = 0
|
rx = 0
|
||||||
tx = 0
|
tx = 0
|
||||||
|
statslist = self.get_vm_statslist(vm)
|
||||||
if (not self._net_stats_supported or
|
if (not self._net_stats_supported or
|
||||||
not self._enable_net_stats or
|
not self._enable_net_stats or
|
||||||
not vm.is_active()):
|
not vm.is_active()):
|
||||||
vm.stats_net_skip = []
|
statslist.stats_net_skip = []
|
||||||
return rx, tx
|
return rx, tx
|
||||||
|
|
||||||
if allstats:
|
if allstats:
|
||||||
@ -168,7 +268,7 @@ class vmmStatsManager(vmmGObject):
|
|||||||
dev = iface.target_dev
|
dev = iface.target_dev
|
||||||
if not dev:
|
if not dev:
|
||||||
continue
|
continue
|
||||||
if dev in vm.stats_net_skip:
|
if dev in statslist.stats_net_skip:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
devrx, devtx = self._old_net_stats_helper(vm, dev)
|
devrx, devtx = self._old_net_stats_helper(vm, dev)
|
||||||
@ -183,6 +283,7 @@ class vmmStatsManager(vmmGObject):
|
|||||||
#######################
|
#######################
|
||||||
|
|
||||||
def _old_disk_stats_helper(self, vm, dev):
|
def _old_disk_stats_helper(self, vm, dev):
|
||||||
|
statslist = self.get_vm_statslist(vm)
|
||||||
try:
|
try:
|
||||||
io = vm.get_backend().blockStats(dev)
|
io = vm.get_backend().blockStats(dev)
|
||||||
if io:
|
if io:
|
||||||
@ -199,7 +300,7 @@ class vmmStatsManager(vmmGObject):
|
|||||||
vm.get_name(), dev, err)
|
vm.get_name(), dev, err)
|
||||||
if vm.is_active():
|
if vm.is_active():
|
||||||
logging.debug("Adding %s to skip list", dev)
|
logging.debug("Adding %s to skip list", dev)
|
||||||
vm.stats_disk_skip.append(dev)
|
statslist.stats_disk_skip.append(dev)
|
||||||
else:
|
else:
|
||||||
logging.debug("Aren't running, don't add to skiplist")
|
logging.debug("Aren't running, don't add to skiplist")
|
||||||
|
|
||||||
@ -208,10 +309,11 @@ class vmmStatsManager(vmmGObject):
|
|||||||
def _sample_disk_stats(self, vm, allstats):
|
def _sample_disk_stats(self, vm, allstats):
|
||||||
rd = 0
|
rd = 0
|
||||||
wr = 0
|
wr = 0
|
||||||
|
statslist = self.get_vm_statslist(vm)
|
||||||
if (not self._disk_stats_supported or
|
if (not self._disk_stats_supported or
|
||||||
not self._enable_disk_stats or
|
not self._enable_disk_stats or
|
||||||
not vm.is_active()):
|
not vm.is_active()):
|
||||||
vm.stats_disk_skip = []
|
statslist.stats_disk_skip = []
|
||||||
return rd, wr
|
return rd, wr
|
||||||
|
|
||||||
if allstats:
|
if allstats:
|
||||||
@ -238,7 +340,7 @@ class vmmStatsManager(vmmGObject):
|
|||||||
dev = disk.target
|
dev = disk.target
|
||||||
if not dev:
|
if not dev:
|
||||||
continue
|
continue
|
||||||
if dev in vm.stats_disk_skip:
|
if dev in statslist.stats_disk_skip:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
diskrd, diskwr = self._old_disk_stats_helper(vm, dev)
|
diskrd, diskwr = self._old_disk_stats_helper(vm, dev)
|
||||||
@ -288,15 +390,16 @@ class vmmStatsManager(vmmGObject):
|
|||||||
return totalmem, curmem
|
return totalmem, curmem
|
||||||
|
|
||||||
def _sample_mem_stats(self, vm, allstats):
|
def _sample_mem_stats(self, vm, allstats):
|
||||||
|
statslist = self.get_vm_statslist(vm)
|
||||||
if (not self._mem_stats_supported or
|
if (not self._mem_stats_supported or
|
||||||
not self._enable_mem_stats or
|
not self._enable_mem_stats or
|
||||||
not vm.is_active()):
|
not vm.is_active()):
|
||||||
self._mem_stats_period_is_set = False
|
statslist.mem_stats_period_is_set = False
|
||||||
return 0, 0
|
return 0, 0
|
||||||
|
|
||||||
if self._mem_stats_period_is_set is False:
|
if statslist.mem_stats_period_is_set is False:
|
||||||
self._set_mem_stats_period(vm)
|
self._set_mem_stats_period(vm)
|
||||||
self._mem_stats_period_is_set = True
|
statslist.mem_stats_period_is_set = True
|
||||||
|
|
||||||
if allstats:
|
if allstats:
|
||||||
totalmem = allstats.get("balloon.current", 1)
|
totalmem = allstats.get("balloon.current", 1)
|
||||||
@ -305,15 +408,15 @@ class vmmStatsManager(vmmGObject):
|
|||||||
else:
|
else:
|
||||||
totalmem, curmem = self._old_mem_stats_helper(vm)
|
totalmem, curmem = self._old_mem_stats_helper(vm)
|
||||||
|
|
||||||
pcentCurrMem = (curmem / float(totalmem)) * 100
|
currMemPercent = (curmem / float(totalmem)) * 100
|
||||||
pcentCurrMem = max(0.0, min(pcentCurrMem, 100.0))
|
currMemPercent = max(0.0, min(currMemPercent, 100.0))
|
||||||
|
|
||||||
return pcentCurrMem, curmem
|
return currMemPercent, curmem
|
||||||
|
|
||||||
|
|
||||||
#####################
|
####################
|
||||||
# allstats handling #
|
# alltats handling #
|
||||||
#####################
|
####################
|
||||||
|
|
||||||
def _get_all_stats(self, conn):
|
def _get_all_stats(self, conn):
|
||||||
if not self._all_stats_supported:
|
if not self._all_stats_supported:
|
||||||
@ -337,8 +440,13 @@ class vmmStatsManager(vmmGObject):
|
|||||||
logging.debug("Error call getAllDomainStats(): %s", err)
|
logging.debug("Error call getAllDomainStats(): %s", err)
|
||||||
return stats
|
return stats
|
||||||
|
|
||||||
|
|
||||||
|
##############
|
||||||
|
# Public API #
|
||||||
|
##############
|
||||||
|
|
||||||
def refresh_vm_stats(self, vm):
|
def refresh_vm_stats(self, vm):
|
||||||
now = time.time()
|
timestamp = time.time()
|
||||||
|
|
||||||
domallstats = None
|
domallstats = None
|
||||||
for _domstat in self._latest_all_stats:
|
for _domstat in self._latest_all_stats:
|
||||||
@ -346,27 +454,24 @@ class vmmStatsManager(vmmGObject):
|
|||||||
domallstats = _domstat[1]
|
domallstats = _domstat[1]
|
||||||
break
|
break
|
||||||
|
|
||||||
cpuTime, cpuTimeAbs, pcentHostCpu, pcentGuestCpu = \
|
cpuTime, cpuTimeAbs, cpuHostPercent, cpuGuestPercent = \
|
||||||
self._sample_cpu_stats(now, vm, domallstats)
|
self._sample_cpu_stats(timestamp, vm, domallstats)
|
||||||
pcentCurrMem, curmem = self._sample_mem_stats(vm, domallstats)
|
currMemPercent, curmem = self._sample_mem_stats(vm, domallstats)
|
||||||
rdBytes, wrBytes = self._sample_disk_stats(vm, domallstats)
|
diskRdBytes, diskWrBytes = self._sample_disk_stats(vm, domallstats)
|
||||||
rxBytes, txBytes = self._sample_net_stats(vm, domallstats)
|
netRxBytes, netTxBytes = self._sample_net_stats(vm, domallstats)
|
||||||
|
|
||||||
newStats = {
|
newstats = _VMStatsRecord(
|
||||||
"timestamp": now,
|
timestamp, cpuTime, cpuTimeAbs,
|
||||||
"cpuTime": cpuTime,
|
cpuHostPercent, cpuGuestPercent,
|
||||||
"cpuTimeAbs": cpuTimeAbs,
|
curmem, currMemPercent,
|
||||||
"cpuHostPercent": pcentHostCpu,
|
diskRdBytes, diskWrBytes,
|
||||||
"cpuGuestPercent": pcentGuestCpu,
|
netRxBytes, netTxBytes)
|
||||||
"curmem": curmem,
|
self.get_vm_statslist(vm).append_stats(newstats)
|
||||||
"currMemPercent": pcentCurrMem,
|
|
||||||
"diskRdKiB": rdBytes // 1024,
|
|
||||||
"diskWrKiB": wrBytes // 1024,
|
|
||||||
"netRxKiB": rxBytes // 1024,
|
|
||||||
"netTxKiB": txBytes // 1024,
|
|
||||||
}
|
|
||||||
|
|
||||||
return newStats
|
|
||||||
|
|
||||||
def cache_all_stats(self, conn):
|
def cache_all_stats(self, conn):
|
||||||
self._latest_all_stats = self._get_all_stats(conn)
|
self._latest_all_stats = self._get_all_stats(conn)
|
||||||
|
|
||||||
|
def get_vm_statslist(self, vm):
|
||||||
|
if vm.get_connkey() not in self._vm_stats:
|
||||||
|
self._vm_stats[vm.get_connkey()] = _VMStatsList()
|
||||||
|
return self._vm_stats[vm.get_connkey()]
|
||||||
|
Reference in New Issue
Block a user