manager: Make disk/net graphs all on the same scale

Not very useful to try and compare multiple graphs using unreported and
different scales. Make every network/disk graph scale to the highest
value the manager has seen yet.
This commit is contained in:
Cole Robinson 2011-07-25 15:09:42 -04:00
parent 156bd2f17b
commit 29fc8cc340
3 changed files with 55 additions and 21 deletions

View File

@ -1534,6 +1534,8 @@ class vmmConnection(vmmGObject):
wrRate = 0 wrRate = 0
rxRate = 0 rxRate = 0
txRate = 0 txRate = 0
diskMaxRate = self.disk_io_max_rate() or 10.0
netMaxRate = self.network_traffic_max_rate() or 10.0
for uuid in vms: for uuid in vms:
vm = vms[uuid] vm = vms[uuid]
@ -1547,6 +1549,9 @@ class vmmConnection(vmmGObject):
rxRate += vm.network_rx_rate() rxRate += vm.network_rx_rate()
txRate += vm.network_tx_rate() txRate += vm.network_tx_rate()
netMaxRate = max(netMaxRate, vm.network_traffic_max_rate())
diskMaxRate = max(diskMaxRate, vm.disk_io_max_rate())
pcentHostCpu = 0 pcentHostCpu = 0
pcentMem = mem * 100.0 / self.host_memory_size() pcentMem = mem * 100.0 / self.host_memory_size()
@ -1572,6 +1577,8 @@ class vmmConnection(vmmGObject):
"diskWrRate" : wrRate, "diskWrRate" : wrRate,
"netRxRate" : rxRate, "netRxRate" : rxRate,
"netTxRate" : txRate, "netTxRate" : txRate,
"diskMaxRate" : diskMaxRate,
"netMaxRate" : netMaxRate,
} }
self.record.insert(0, newStats) self.record.insert(0, newStats)
@ -1616,6 +1623,9 @@ class vmmConnection(vmmGObject):
def stats_memory(self): def stats_memory(self):
return self._get_record_helper("memory") return self._get_record_helper("memory")
def pretty_stats_memory(self):
return util.pretty_mem(self.stats_memory())
def host_cpu_time_percentage(self): def host_cpu_time_percentage(self):
return self._get_record_helper("cpuHostPercent") return self._get_record_helper("cpuHostPercent")
guest_cpu_time_percentage = host_cpu_time_percentage guest_cpu_time_percentage = host_cpu_time_percentage
@ -1626,9 +1636,8 @@ class vmmConnection(vmmGObject):
return self._get_record_helper("netTxRate") return self._get_record_helper("netTxRate")
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 pretty_stats_memory(self): return self._get_record_helper("netMaxRate")
return util.pretty_mem(self.stats_memory())
def disk_read_rate(self): def disk_read_rate(self):
return self._get_record_helper("diskRdRate") return self._get_record_helper("diskRdRate")
@ -1636,7 +1645,8 @@ class vmmConnection(vmmGObject):
return self._get_record_helper("diskWrRate") return self._get_record_helper("diskWrRate")
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):
return self._get_record_helper("diskMaxRate")
#################################### ####################################
# Per-Connection gconf preferences # # Per-Connection gconf preferences #

View File

@ -1180,6 +1180,8 @@ class vmmDomain(vmmLibvirtObject):
def _set_max_rate(self, record, what): def _set_max_rate(self, record, what):
if record[what] > self.maxRecord[what]: if record[what] > self.maxRecord[what]:
self.maxRecord[what] = record[what] self.maxRecord[what] = record[what]
def _get_max_rate(self, name1, name2):
return float(max(self.maxRecord[name1], self.maxRecord[name2]))
def _get_record_helper(self, record_name): def _get_record_helper(self, record_name):
if len(self.record) == 0: if len(self.record) == 0:
@ -1196,11 +1198,13 @@ class vmmDomain(vmmLibvirtObject):
vector.append(0) vector.append(0)
return vector return vector
def _in_out_vector_helper(self, name1, name2): def _in_out_vector_helper(self, name1, name2, ceil):
vector = [] vector = []
stats = self.record stats = self.record
ceil = float(max(self.maxRecord[name1], self.maxRecord[name2])) if ceil is None:
ceil = self._get_max_rate(name1, name2)
maxlen = self.config.get_stats_history_length() maxlen = self.config.get_stats_history_length()
for n in [name1, name2]: for n in [name1, name2]:
for i in range(maxlen + 1): for i in range(maxlen + 1):
if i < len(stats): if i < len(stats):
@ -1270,8 +1274,12 @@ class vmmDomain(vmmLibvirtObject):
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):
return self._get_max_rate("netRxRate", "netTxRate")
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):
return self._get_max_rate("diskRdRate", "diskWrRate")
def host_cpu_time_vector(self): def host_cpu_time_vector(self):
return self._vector_helper("cpuHostPercent") return self._vector_helper("cpuHostPercent")
@ -1279,10 +1287,10 @@ class vmmDomain(vmmLibvirtObject):
return self._vector_helper("cpuGuestPercent") return self._vector_helper("cpuGuestPercent")
def stats_memory_vector(self): def stats_memory_vector(self):
return self._vector_helper("currMemPercent") return self._vector_helper("currMemPercent")
def network_traffic_vector(self): def network_traffic_vector(self, ceil=None):
return self._in_out_vector_helper("netRxRate", "netTxRate") return self._in_out_vector_helper("netRxRate", "netTxRate", ceil)
def disk_io_vector(self): def disk_io_vector(self, ceil=None):
return self._in_out_vector_helper("diskRdRate", "diskWrRate") return self._in_out_vector_helper("diskRdRate", "diskWrRate", ceil)
def host_cpu_time_vector_limit(self, limit): def host_cpu_time_vector_limit(self, limit):
cpudata = self.host_cpu_time_vector() cpudata = self.host_cpu_time_vector()
@ -1294,10 +1302,11 @@ class vmmDomain(vmmLibvirtObject):
if len(cpudata) > limit: if len(cpudata) > limit:
cpudata = cpudata[0:limit] cpudata = cpudata[0:limit]
return cpudata return cpudata
def network_traffic_vector_limit(self, limit): def network_traffic_vector_limit(self, limit, ceil=None):
return self.in_out_vector_limit(self.network_traffic_vector(), limit) return self.in_out_vector_limit(self.network_traffic_vector(ceil),
def disk_io_vector_limit(self, limit): limit)
return self.in_out_vector_limit(self.disk_io_vector(), limit) def disk_io_vector_limit(self, limit, ceil=None):
return self.in_out_vector_limit(self.disk_io_vector(ceil), limit)
################### ###################

View File

@ -141,6 +141,9 @@ class vmmManager(vmmGObjectUI):
self.widget("vm-list").get_selection().connect("changed", self.widget("vm-list").get_selection().connect("changed",
self.vm_selected) self.vm_selected)
self.max_disk_rate = 10.0
self.max_net_rate = 10.0
# Initialize stat polling columns based on global polling # Initialize stat polling columns based on global polling
# preferences (we want signal handlers for this) # preferences (we want signal handlers for this)
for typ, init_val in [ for typ, init_val in [
@ -789,7 +792,7 @@ class vmmManager(vmmGObjectUI):
conn.connect("vm-added", self.vm_added) conn.connect("vm-added", self.vm_added)
conn.connect("vm-removed", self.vm_removed) conn.connect("vm-removed", self.vm_removed)
conn.connect("resources-sampled", self.conn_refresh_resources) conn.connect("resources-sampled", self.conn_resources_sampled)
conn.connect("state-changed", self.conn_state_changed) conn.connect("state-changed", self.conn_state_changed)
conn.connect("connect-error", self._connect_error) conn.connect("connect-error", self._connect_error)
@ -814,7 +817,7 @@ class vmmManager(vmmGObjectUI):
continue continue
newname = conn.get_pretty_desc_inactive(False, True) newname = conn.get_pretty_desc_inactive(False, True)
self.conn_refresh_resources(conn, newname) self.conn_resources_sampled(conn, newname)
def remove_conn(self, engine_ignore, uri): def remove_conn(self, engine_ignore, uri):
model = self.widget("vm-list").get_model() model = self.widget("vm-list").get_model()
@ -904,10 +907,10 @@ class vmmManager(vmmGObjectUI):
return None return None
def conn_state_changed(self, conn): def conn_state_changed(self, conn):
self.conn_refresh_resources(conn) self.conn_resources_sampled(conn)
self.vm_selected() self.vm_selected()
def conn_refresh_resources(self, conn, newname=None): def conn_resources_sampled(self, conn, newname=None):
vmlist = self.widget("vm-list") vmlist = self.widget("vm-list")
model = vmlist.get_model() model = vmlist.get_model()
row = self.rows[conn.get_uri()] row = self.rows[conn.get_uri()]
@ -928,9 +931,15 @@ class vmmManager(vmmGObjectUI):
if parent is not None: if parent is not None:
child = model.iter_children(parent) child = model.iter_children(parent)
while child is not None: while child is not None:
del self.rows[self.vm_row_key(model.get_value(child, ROW_HANDLE))] del self.rows[self.vm_row_key(model.get_value(child,
ROW_HANDLE))]
model.remove(child) model.remove(child)
child = model.iter_children(parent) child = model.iter_children(parent)
self.max_disk_rate = max(self.max_disk_rate, conn.disk_io_max_rate())
self.max_net_rate = max(self.max_net_rate,
conn.network_traffic_max_rate())
model.row_changed(row.path, row.iter) model.row_changed(row.path, row.iter)
def change_run_text(self, can_restore): def change_run_text(self, can_restore):
@ -1152,7 +1161,10 @@ class vmmManager(vmmGObjectUI):
if obj is None: if obj is None:
return return
data = obj.disk_io_vector_limit(40) if not hasattr(obj, "conn"):
return
data = obj.disk_io_vector_limit(40, self.max_disk_rate)
cell.set_property('data_array', data) cell.set_property('data_array', data)
def network_traffic_img(self, column_ignore, cell, model, _iter, data): def network_traffic_img(self, column_ignore, cell, model, _iter, data):
@ -1160,7 +1172,10 @@ class vmmManager(vmmGObjectUI):
if obj is None: if obj is None:
return return
data = obj.network_traffic_vector_limit(40) if not hasattr(obj, "conn"):
return
data = obj.network_traffic_vector_limit(40, self.max_net_rate)
cell.set_property('data_array', data) cell.set_property('data_array', data)
vmmGObjectUI.type_register(vmmManager) vmmGObjectUI.type_register(vmmManager)