From bb6598d2f9973440018b257f6402c0ad0db60f16 Mon Sep 17 00:00:00 2001 From: SimonFair <39065407+SimonFair@users.noreply.github.com> Date: Fri, 9 Feb 2024 07:09:47 +0000 Subject: [PATCH 1/6] Add initial functions to collect VM usage data --- .../dynamix.vm.manager/include/libvirt.php | 9 ++- .../include/libvirt_helpers.php | 77 +++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix.vm.manager/include/libvirt.php b/emhttp/plugins/dynamix.vm.manager/include/libvirt.php index 3436482b9..b5566a6b7 100644 --- a/emhttp/plugins/dynamix.vm.manager/include/libvirt.php +++ b/emhttp/plugins/dynamix.vm.manager/include/libvirt.php @@ -1694,8 +1694,8 @@ else { $doms = libvirt_list_domains($this->conn); foreach ($doms as $dom) { - $tmp = $this->domain_get_name($dom); - $ret[$tmp] = libvirt_domain_get_info($dom); + $tmp = $this->get_domain_object($dom); + $ret[$dom] = libvirt_domain_get_info($tmp); } } @@ -1771,6 +1771,11 @@ return ($tmp) ? $tmp : $this->_set_last_error(); } + function domain_get_all_domain_stats() { + $tmp = libvirt_connect_get_all_domain_stats($this->conn); + return ($tmp) ? $tmp : $this->_set_last_error(); + } + function domain_start($dom) { $dom=$this->get_domain_object($dom); if ($dom) { diff --git a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php index b8b66d638..79de185b5 100644 --- a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php +++ b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php @@ -2528,4 +2528,81 @@ function addtemplatexml($post) { return $reply; } +function get_vm_usage_stats($collectcpustats = true,$collectdiskstats = true,$collectnicstats = true, $collectmemstats = true) { + global $lv, $vmusagestats; + + $hostcpus = $lv->host_get_node_info(); + $timestamp = time(); + $allstats=$lv->domain_get_all_domain_stats(); + + foreach ($allstats as $vm => $data) { + $state = $data["state.state"]; + # CPU Metrics + $cpuTime = 0; + $cpuHostPercent = 0; + $cpuGuestPercent = 0; + $cpuTimeAbs = $data["cpu.time"]; + if ($state == 1 && $collectcpustats == true) { + $guestcpus = $data["vcpu.current"]; + $cpuTime = $cpuTimeAbs - $vmusagestats[$vm]["cpuTimeAbs"]; + $pcentbase = ((($cpuTime) * 100.0) / ((($timestamp) - $vmusagestats[$vm]["timestamp"] ) * 1000.0 * 1000.0 * 1000.0)); + $cpuHostPercent = round($pcentbase / $hostcpus['cpus'],1); + $cpuGuestPercent = round($pcentbase / $guestcpus, 1) ; + $cpuHostPercent = max(0.0, min(100.0, $cpuHostPercent)); + $cpuGuestPercent = max(0.0, min(100.0, $cpuGuestPercent)); + } + + # Memory Metrics + if ($state == 1 && $collectmemstats) { + $currentmem = $data["balloon.current"]; + $unusedmem = $data["balloon.unused"]; + $meminuse = $currentmem - $unusedmem; + } else $currentmem = $meminuse = 0; + + # Disk + if ($state == 1 && $collectdiskstats) { + $disknum = $data["block.count"]; + $rd=$wr=$i=0; + for ($i = 0; $i < $disknum; $i++) { + if ($data["block.$i.name"] == "hda" || $data["block.$i.name"] == "hdb") continue; + $rd += $data["block.$i.rd.bytes"] ; + $wr += $data["block.$i.wr.bytes"] ; + } + $rdrate = ($rd - $vmusagestats[$vm]['rdp'])/1024; + $wrrate = ($wr - $vmusagestats[$vm]['wrp'])/1024; + } else $rdrate=$wrrate=0; + + # Net + if ($state == 1 && $collectnicstats) { + $nicnum = $data["net.count"]; + $rx=$tx=$i=0; + for ($i = 0; $i < $nicnum; $i++) { + $rx += $data["net.$i.rx.bytes"] ; + $tx += $data["net.$i.tx.bytes"] ; + } + $rxrate = round(($rx - $vmusagestats[$vm]['rxp'])/1024,0); + $txrate = round(($tx - $vmusagestats[$vm]['txp'])/1024,0); + } else $rxrate=$txrate=0; + + $vmusagestats[$vm] = [ + "cpuTime" => $cpuTime, + "cpuTimeAbs" => $cpuTimeAbs, + "cpuhost" => $cpuHostPercent, + "cpuguest" => $cpuGuestPercent, + "timestamp" => $timestamp, + "mem" => $meminuse, + "maxmem" => $currentmem, + "rxrate" => $rxrate, + "rxp" => $rx, + "txrate" => $txrate, + "txp" => $tx, + "rdp" => $rd, + "rdrate" => $rdrate, + "wrp" => $wr, + "wrrate" => $wrrate, + "state" => $state, + ]; + } +} + ?> From 71f655cd05506d3f53d26222fe0b5a8b6161bc46 Mon Sep 17 00:00:00 2001 From: SimonFair <39065407+SimonFair@users.noreply.github.com> Date: Sun, 11 Feb 2024 15:22:22 +0000 Subject: [PATCH 2/6] Add Stats page --- .../dynamix.vm.manager/VMUsageStats.page | 41 ++++++++ .../include/libvirt_helpers.php | 8 +- .../plugins/dynamix.vm.manager/nchan/vm_usage | 94 +++++++++++++++++++ 3 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 emhttp/plugins/dynamix.vm.manager/VMUsageStats.page create mode 100644 emhttp/plugins/dynamix.vm.manager/nchan/vm_usage diff --git a/emhttp/plugins/dynamix.vm.manager/VMUsageStats.page b/emhttp/plugins/dynamix.vm.manager/VMUsageStats.page new file mode 100644 index 000000000..4a75e8180 --- /dev/null +++ b/emhttp/plugins/dynamix.vm.manager/VMUsageStats.page @@ -0,0 +1,41 @@ +Menu="VMs:0" +Title="VM Usage Statisics" +Cond="exec(\"grep -o '^SERVICE=.enable' /boot/config/domain.cfg 2>/dev/null\")" +Nchan="vm_usage:stop" +--- + + + + + + +
_(Name)__(Guest CPU)__(Host CPU)__(Memory)__(Disk IO)__(Network IO)_
+ + \ No newline at end of file diff --git a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php index 79de185b5..c870c97ba 100644 --- a/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php +++ b/emhttp/plugins/dynamix.vm.manager/include/libvirt_helpers.php @@ -2568,8 +2568,8 @@ function get_vm_usage_stats($collectcpustats = true,$collectdiskstats = true,$co $rd += $data["block.$i.rd.bytes"] ; $wr += $data["block.$i.wr.bytes"] ; } - $rdrate = ($rd - $vmusagestats[$vm]['rdp'])/1024; - $wrrate = ($wr - $vmusagestats[$vm]['wrp'])/1024; + $rdrate = ($rd - $vmusagestats[$vm]['rdp']); + $wrrate = ($wr - $vmusagestats[$vm]['wrp']); } else $rdrate=$wrrate=0; # Net @@ -2580,8 +2580,8 @@ function get_vm_usage_stats($collectcpustats = true,$collectdiskstats = true,$co $rx += $data["net.$i.rx.bytes"] ; $tx += $data["net.$i.tx.bytes"] ; } - $rxrate = round(($rx - $vmusagestats[$vm]['rxp'])/1024,0); - $txrate = round(($tx - $vmusagestats[$vm]['txp'])/1024,0); + $rxrate = round(($rx - $vmusagestats[$vm]['rxp']),0); + $txrate = round(($tx - $vmusagestats[$vm]['txp']),0); } else $rxrate=$txrate=0; $vmusagestats[$vm] = [ diff --git a/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage b/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage new file mode 100644 index 000000000..cf700aae4 --- /dev/null +++ b/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage @@ -0,0 +1,94 @@ +#!/usr/bin/php -q + + $vmdata) { + + if ($vmdata['state'] == 1) { + $running++; + $echodata .= "$vm" ; + #".$vmdata['cpuguest']."%".$vmdata['cpuhost']."%"; + $echodata .= "".$vmdata['cpuguest']."%
"; + $echodata .= "".$vmdata['cpuhost']."%
"; + $echodata .= my_scale($vmdata['mem'],$unit)."$unit / ".my_scale($vmdata['maxmem'],$unit)."$unit"; + $echodata .= _("Read").": ".my_scale($vmdata['rxrate'],$unit)."$unit/s
"._("Write").": ".my_scale($vmdata['txrate'],$unit)."$unit/s"; + $echodata .= _("RX").": ".my_scale($vmdata['rdrate'],$unit)."$unit/s
"._("TX").": ".my_scale($vmdata['wrrate'],$unit)."$unit/s"; + } + $echo = $echodata ; + } + if ($running < 1) $echo = ""._("No VMs Running").""; + + $echo = json_encode($echo); + $md5_new = md5($echo,true); + if ($md5_new !== $md5_old) { + $md5_old = publish('vm_usage',$echo)!==false ? $md5_new : -1; + $time0 = $time1; + } + + sleep(3); +} +?> From 954969c2e483faa54c44ec810710d39ad7c33c1b Mon Sep 17 00:00:00 2001 From: SimonFair <39065407+SimonFair@users.noreply.github.com> Date: Sun, 11 Feb 2024 15:25:18 +0000 Subject: [PATCH 3/6] Make script executable --- emhttp/plugins/dynamix.vm.manager/nchan/vm_usage | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 emhttp/plugins/dynamix.vm.manager/nchan/vm_usage diff --git a/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage b/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage old mode 100644 new mode 100755 From eef77dc64de8d2fc39fc5e1f13113d8b4059cb20 Mon Sep 17 00:00:00 2001 From: SimonFair <39065407+SimonFair@users.noreply.github.com> Date: Sun, 11 Feb 2024 18:34:13 +0000 Subject: [PATCH 4/6] Fix graphs --- emhttp/plugins/dynamix.vm.manager/nchan/vm_usage | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage b/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage index cf700aae4..f72b094d6 100755 --- a/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage +++ b/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage @@ -71,12 +71,11 @@ while (true) { if ($vmdata['state'] == 1) { $running++; $echodata .= "$vm" ; - #".$vmdata['cpuguest']."%".$vmdata['cpuhost']."%"; - $echodata .= "".$vmdata['cpuguest']."%
"; - $echodata .= "".$vmdata['cpuhost']."%
"; + $echodata .= "".$vmdata['cpuguest']."%
"; + $echodata .= "".$vmdata['cpuhost']."%
"; $echodata .= my_scale($vmdata['mem'],$unit)."$unit / ".my_scale($vmdata['maxmem'],$unit)."$unit"; - $echodata .= _("Read").": ".my_scale($vmdata['rxrate'],$unit)."$unit/s
"._("Write").": ".my_scale($vmdata['txrate'],$unit)."$unit/s"; - $echodata .= _("RX").": ".my_scale($vmdata['rdrate'],$unit)."$unit/s
"._("TX").": ".my_scale($vmdata['wrrate'],$unit)."$unit/s"; + $echodata .= _("Read").": ".my_scale($vmdata['rdrate'],$unit)."$unit/s
"._("Write").": ".my_scale($vmdata['wrrate'],$unit)."$unit/s"; + $echodata .= _("RX").": ".my_scale($vmdata['rxrate'],$unit)."$unit/s
"._("TX").": ".my_scale($vmdata['txrate'],$unit)."$unit/s"; } $echo = $echodata ; } From 034b41726e32e15d581aaf1b07e7549e751eb40f Mon Sep 17 00:00:00 2001 From: SimonFair <39065407+SimonFair@users.noreply.github.com> Date: Sun, 11 Feb 2024 18:42:11 +0000 Subject: [PATCH 5/6] Update vm_usage --- emhttp/plugins/dynamix.vm.manager/nchan/vm_usage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage b/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage index f72b094d6..031ac219e 100755 --- a/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage +++ b/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage @@ -79,7 +79,7 @@ while (true) { } $echo = $echodata ; } - if ($running < 1) $echo = ""._("No VMs Running").""; + if ($running < 1) $echo = ""._('No VMs running').""; $echo = json_encode($echo); $md5_new = md5($echo,true); From 9f3047d2ff8283f04e034f8ea60516ae54ddf4ca Mon Sep 17 00:00:00 2001 From: SimonFair <39065407+SimonFair@users.noreply.github.com> Date: Mon, 12 Feb 2024 22:04:37 +0000 Subject: [PATCH 6/6] Add options to settings to disable/enable + refresh rate --- emhttp/languages/en_US/helptext.txt | 8 ++++++++ emhttp/plugins/dynamix.vm.manager/VMSettings.page | 13 +++++++++++++ emhttp/plugins/dynamix.vm.manager/VMUsageStats.page | 2 +- emhttp/plugins/dynamix.vm.manager/nchan/vm_usage | 6 +++++- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/emhttp/languages/en_US/helptext.txt b/emhttp/languages/en_US/helptext.txt index 1de7bb595..0604c2d21 100644 --- a/emhttp/languages/en_US/helptext.txt +++ b/emhttp/languages/en_US/helptext.txt @@ -1675,6 +1675,14 @@ For setting the console options to show on context menus. Web will show only inb Virtual Manager Remote Viewer will only show the Remote Viewer option. Both will show both Web and Remote Viewer. :end +:vms_usage_help: +Show metrics for CPU both guest and host percentage, memory, disk io and network io. +:end + +:vms_usage_timer_help: +Setting in seconds for metrics refresh time. +:end + :vms_acs_override_help: *PCIe ACS override* allows various hardware components to expose themselves as isolated devices. Typically it is sufficient to isolate *Downstream* ports. diff --git a/emhttp/plugins/dynamix.vm.manager/VMSettings.page b/emhttp/plugins/dynamix.vm.manager/VMSettings.page index 68246e5df..ea87c12a5 100644 --- a/emhttp/plugins/dynamix.vm.manager/VMSettings.page +++ b/emhttp/plugins/dynamix.vm.manager/VMSettings.page @@ -183,6 +183,19 @@ _(Console Options)_: :vms_console_help: +_(Show VM Usage)_: +: + +:vms_usage_help: + +_(VM Usage refresh timer(seconds))_: +: + +:vms_usage_timer_help: + _(PCIe ACS override)_: :