Loading cloudcontrol/cli/commands/stats.py 0 → 100644 +134 −0 Original line number Diff line number Diff line #coding=utf8 # This file is part of CloudControl. # # CloudControl is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # CloudControl 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 Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with CloudControl. If not, see <http://www.gnu.org/licenses/>. """ CloudControl server command """ from collections import defaultdict from cloudcontrol.cli.exception import cmdBadArgument from cloudcontrol.cli.printer import color from cloudcontrol.cli.command import RemoteCommand class Command_stats(RemoteCommand): """VM allocation command""" def __init__(self, cli, argv0): RemoteCommand.__init__(self, cli, argv0) self.set_usage("%prog [options] (hv [tql] | hvpop pop1 [pop2] [...])") def __call__(self, argv): self.parse_args(argv) if len(self.args) == 0: raise cmdBadArgument() if hasattr(self, "stats_" + self.args[0]): func = getattr(self, "stats_" + self.args[0]) func(*self.args[1:]) else: raise cmdBadArgument() def remote_functions(self): return set(("list",)) def stats_hvpop(self, *args): if not args: args = ["all"] for pop in args: self.printer.out(color["light"] + pop + ": " + color["reset"]) self.printer.out(color["light"] + "=" * (len(pop) + 1) + color["reset"]) if pop == "all": self.stats_hv() else: self.stats_hv("pop=%s" % pop) def stats_hv(self, tql="id", *args): tql = "(%s)&r=hv&con$alloc$cpu$cpualloc$mem$memalloc$sto*$nvm$vmstarted$vmstopped$hmodel" % tql response = self.rpc.call("list", tql) count_hv = 0 count_hv_allocatable = 0 count_vm = 0 count_vm_started = 0 count_vm_stopped = 0 count_cpu_allocated = 0 count_cpu_total = 0 count_memory_allocated = 0 count_memory_total = 0 count_disk_allocated = 0 count_disk_total = 0 count_by_model = defaultdict(lambda: 0) # Sum each metric iterating over matching HVs: for hv in response["objects"]: try: count_hv += 1 count_hv_allocatable += 1 if hv.get("alloc") == "yes" else 0 count_vm += int(hv.get("nvm", 0)) count_vm_started += int(hv.get("vmstarted", 0)) count_vm_stopped += int(hv.get("vmstopped", 0)) count_cpu_allocated += int(hv.get("cpualloc", 0)) count_cpu_total += int(hv.get("cpu", 0)) count_memory_allocated += int(hv.get("memalloc", 0)) count_memory_total += int(hv.get("mem", 0)) count_disk_allocated += sum(int(hv.get("sto%s_used" % x, 0)) for x in hv.get("sto", "").split()) count_disk_total += sum(int(hv.get("sto%s_size" % x, 0)) for x in hv.get("sto", "").split()) count_by_model[hv.get("hmodel", "Unknown")] += 1 except ValueError: pass # Ignore errors casting tags as int (most likely a tag timeout error "#ERR") # Compute ratios: try: ratio_cpu = float(count_cpu_allocated) / count_cpu_total * 100 except ZeroDivisionError: ratio_cpu = 0 try: ratio_memory = float(count_memory_allocated) / count_memory_total * 100 except ZeroDivisionError: ratio_memory = 0 try: ratio_disk = float(count_disk_allocated) / count_disk_total * 100 except ZeroDivisionError: ratio_disk = 0 # Print stats: self._print_stats("Number of hypervisors", "%s (%s are allocatable)", count_hv, count_hv_allocatable) self._print_stats("Number of VM", "%s (%s are started, %s are stopped)", count_vm, count_vm_started, count_vm_stopped) self._print_stats("CPU (threads)", "%s allocated, %s total (%0.1f%% allocated)", count_cpu_allocated, count_cpu_total, ratio_cpu) self._print_stats("Memory", "%sB allocated, %sB total (%0.1f%% allocated)", self.cli.tagdisplay.type_bit(unicode(count_memory_allocated)), self.cli.tagdisplay.type_bit(unicode(count_memory_total)), ratio_memory) self._print_stats("Storage", "%sB allocated, %sB total (%0.1f%% allocated)", self.cli.tagdisplay.type_bit(unicode(count_disk_allocated)), self.cli.tagdisplay.type_bit(unicode(count_disk_total)), ratio_disk) self._print_stats("Hardware", ["%s: %s" % (k, v) for k, v in count_by_model.iteritems()]) self.printer.out("") # Empty line def _print_stats(self, key, value, *args): if isinstance(value, list): padding = len(key) + 2 value = ("\n" + " " * padding).join(value) self.printer.out(color["light"] + key + ":" + color["reset"] + " " + value % args) Loading
cloudcontrol/cli/commands/stats.py 0 → 100644 +134 −0 Original line number Diff line number Diff line #coding=utf8 # This file is part of CloudControl. # # CloudControl is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # CloudControl 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 Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with CloudControl. If not, see <http://www.gnu.org/licenses/>. """ CloudControl server command """ from collections import defaultdict from cloudcontrol.cli.exception import cmdBadArgument from cloudcontrol.cli.printer import color from cloudcontrol.cli.command import RemoteCommand class Command_stats(RemoteCommand): """VM allocation command""" def __init__(self, cli, argv0): RemoteCommand.__init__(self, cli, argv0) self.set_usage("%prog [options] (hv [tql] | hvpop pop1 [pop2] [...])") def __call__(self, argv): self.parse_args(argv) if len(self.args) == 0: raise cmdBadArgument() if hasattr(self, "stats_" + self.args[0]): func = getattr(self, "stats_" + self.args[0]) func(*self.args[1:]) else: raise cmdBadArgument() def remote_functions(self): return set(("list",)) def stats_hvpop(self, *args): if not args: args = ["all"] for pop in args: self.printer.out(color["light"] + pop + ": " + color["reset"]) self.printer.out(color["light"] + "=" * (len(pop) + 1) + color["reset"]) if pop == "all": self.stats_hv() else: self.stats_hv("pop=%s" % pop) def stats_hv(self, tql="id", *args): tql = "(%s)&r=hv&con$alloc$cpu$cpualloc$mem$memalloc$sto*$nvm$vmstarted$vmstopped$hmodel" % tql response = self.rpc.call("list", tql) count_hv = 0 count_hv_allocatable = 0 count_vm = 0 count_vm_started = 0 count_vm_stopped = 0 count_cpu_allocated = 0 count_cpu_total = 0 count_memory_allocated = 0 count_memory_total = 0 count_disk_allocated = 0 count_disk_total = 0 count_by_model = defaultdict(lambda: 0) # Sum each metric iterating over matching HVs: for hv in response["objects"]: try: count_hv += 1 count_hv_allocatable += 1 if hv.get("alloc") == "yes" else 0 count_vm += int(hv.get("nvm", 0)) count_vm_started += int(hv.get("vmstarted", 0)) count_vm_stopped += int(hv.get("vmstopped", 0)) count_cpu_allocated += int(hv.get("cpualloc", 0)) count_cpu_total += int(hv.get("cpu", 0)) count_memory_allocated += int(hv.get("memalloc", 0)) count_memory_total += int(hv.get("mem", 0)) count_disk_allocated += sum(int(hv.get("sto%s_used" % x, 0)) for x in hv.get("sto", "").split()) count_disk_total += sum(int(hv.get("sto%s_size" % x, 0)) for x in hv.get("sto", "").split()) count_by_model[hv.get("hmodel", "Unknown")] += 1 except ValueError: pass # Ignore errors casting tags as int (most likely a tag timeout error "#ERR") # Compute ratios: try: ratio_cpu = float(count_cpu_allocated) / count_cpu_total * 100 except ZeroDivisionError: ratio_cpu = 0 try: ratio_memory = float(count_memory_allocated) / count_memory_total * 100 except ZeroDivisionError: ratio_memory = 0 try: ratio_disk = float(count_disk_allocated) / count_disk_total * 100 except ZeroDivisionError: ratio_disk = 0 # Print stats: self._print_stats("Number of hypervisors", "%s (%s are allocatable)", count_hv, count_hv_allocatable) self._print_stats("Number of VM", "%s (%s are started, %s are stopped)", count_vm, count_vm_started, count_vm_stopped) self._print_stats("CPU (threads)", "%s allocated, %s total (%0.1f%% allocated)", count_cpu_allocated, count_cpu_total, ratio_cpu) self._print_stats("Memory", "%sB allocated, %sB total (%0.1f%% allocated)", self.cli.tagdisplay.type_bit(unicode(count_memory_allocated)), self.cli.tagdisplay.type_bit(unicode(count_memory_total)), ratio_memory) self._print_stats("Storage", "%sB allocated, %sB total (%0.1f%% allocated)", self.cli.tagdisplay.type_bit(unicode(count_disk_allocated)), self.cli.tagdisplay.type_bit(unicode(count_disk_total)), ratio_disk) self._print_stats("Hardware", ["%s: %s" % (k, v) for k, v in count_by_model.iteritems()]) self.printer.out("") # Empty line def _print_stats(self, key, value, *args): if isinstance(value, list): padding = len(key) + 2 value = ("\n" + " " * padding).join(value) self.printer.out(color["light"] + key + ":" + color["reset"] + " " + value % args)