From b04d1ce00589b550ce608a1a5cd3cea004b992b0 Mon Sep 17 00:00:00 2001 From: o Date: Mon, 4 Apr 2016 15:48:40 +0200 Subject: [PATCH] new qvm-top utility Display cpu and mem similar to qvm-ls but ordered by cpu time. Also a one line summary switch which includes the top n cpu consuming vms and total memory consumption. Intended usage is to e.g. embed in a window manager widget. --- qvm-tools/qvm-top | 128 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100755 qvm-tools/qvm-top diff --git a/qvm-tools/qvm-top b/qvm-tools/qvm-top new file mode 100755 index 00000000..eb54379a --- /dev/null +++ b/qvm-tools/qvm-top @@ -0,0 +1,128 @@ +#!/usr/bin/python2 +# -*- encoding: utf8 -*- +# +# The Qubes OS Project, http://www.qubes-os.org +# +# Copyright (C) 2010 Joanna Rutkowska +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# + +from qubes.qubes import QubesVmCollection +from qubes.qubes import QubesHost +from qubes.qubes import QubesException +from optparse import OptionParser +import sys + +def main(): + usage = "usage: %prog [options]" + parser = OptionParser (usage) + + parser.add_option("--list", dest="list_top", + action="store_true", default=False, + help="n m : One line summary of top n vms with more than m cpu_time %") + + + (options, args) = parser.parse_args () + + + qvm_collection = QubesVmCollection() + qvm_collection.lock_db_for_reading() + qvm_collection.load() + qvm_collection.unlock_db() + + fields_to_display = ["name", "cpu", "mem"] + + cpu_usages = None + + qhost = QubesHost() + + (measure_time, cpu_usages) = qhost.measure_cpu_usage(qvm_collection) + + vms_list = [vm for vm in qvm_collection.values() if vm.is_running()] + vms_list = sorted(vms_list, key= lambda vm: 1-cpu_usages[vm.get_xid()]['cpu_usage']) + + no_vms = len (vms_list) + vms_to_display = vms_list + + if options.list_top: + any_shown = False + ndisp = 3 + cputh = 0 + if len(args) > 0: + ndisp = int(args[0]) + if len(args) > 1: + cputh = int(args[1]) + + for vm in vms_to_display[:ndisp]: + cpu = cpu_usages[vm.get_xid()]['cpu_usage'] + if cpu > cputh: + any_shown = True + sys.stdout.write("%d %s, " % (cpu, vm.name)) + + if any_shown: + sys.stdout.write(" ... | ") + + totalMem = 0 + dom0mem = 0 + for vm in vms_to_display: + if not vm.name == "dom0": + totalMem += vm.get_mem() + else: + dom0mem = vm.get_mem() + totalMem /= 1024.0 * 1024.0 + dom0mem /= 1024.0 * 1024.0 + sys.stdout.write("%.1f G + %.1f G" % (totalMem, dom0mem)) + return + + max_width = { 'name': 0, 'cpu': 0, 'mem': 0 } + data_to_display = [] + for vm in vms_to_display: + data_row = {} + data_row['name'] = vm.name + max_width['name'] = max(max_width['name'], len(data_row['name'])) + data_row['cpu'] = "%.1f" % (cpu_usages[vm.get_xid()]['cpu_usage']) + max_width['cpu'] = max(max_width['cpu'], len(data_row['cpu'])) + data_row['mem'] = "%d" % (vm.get_mem() / (1024.0)) + max_width['mem'] = max(max_width['mem'], len(data_row['mem'])) + data_to_display.append(data_row) + + # Display the header + s = "" + for f in fields_to_display: + fmt="{{0:-^{0}}}-+".format(max_width[f] + 1) + s += fmt.format('-') + print s + s = "" + for f in fields_to_display: + fmt="{{0:>{0}}} |".format(max_width[f] + 1) + s += fmt.format(f) + print s + s = "" + for f in fields_to_display: + fmt="{{0:-^{0}}}-+".format(max_width[f] + 1) + s += fmt.format('-') + print s + + # ... and the actual data + for row in data_to_display: + s = "" + for f in fields_to_display: + fmt="{{0:>{0}}} |".format(max_width[f] + 1) + s += fmt.format(row[f]) + print s + +main()