Initial commit for Dashboard VM Metrics.

This commit is contained in:
SimonFair
2024-02-18 07:15:12 +00:00
parent 27bb4f7799
commit c9f20e7934
3 changed files with 166 additions and 3 deletions

View File

@@ -1,5 +1,5 @@
Menu="Dashboard"
Nchan="wg_poller,update_1,update_2,update_3,ups_status:stop"
Nchan="wg_poller,update_1,update_2,update_3,ups_status:stop,vm_dashusage:stop"
---
<?PHP
/* Copyright 2005-2023, Lime Technology * Copyright 2012-2023, Bergware International.
@@ -73,6 +73,10 @@ $vdisk = exec("grep -Pom1 '^DOCKER_IMAGE_TYPE=\"\\K[^\"]+' /boot/config/docker.c
$dot = _var($display,'number','.,')[0];
$zfs = count(array_filter(array_column($disks,'fsType'),function($fs){return str_replace('luks:','',$fs??'')=='zfs';}));
$domain_cfgfile = "/boot/config/domain.cfg";
$domain_cfg = parse_ini_file($domain_cfgfile);
if (!isset($domain_cfg['USAGE'])) $vmusage = "N" ; else $vmusage = $domain_cfg['USAGE'];
// enable/disable graph elements by making hook script executable or not
chmod("$docroot/webGui/system/VM_usage",$libvirtd ? 0755 : 0644);
chmod("$docroot/webGui/system/ZFS_cache",$zfs ? 0755 : 0644);
@@ -424,6 +428,13 @@ echo "</td></tr>";
<a href='/Dashboard/Settings/VMSettings' title="_(Go to VM settings)_"><i class='fa fa-fw fa-cog control'></i></a>
</td></tr>
</tbody>
<?if ($vmusage == "Y"):?>
<tbody id='vm_view_usage' title="_(Virtual Machines Usage)_" >
<tr><td><i class='icon-virtualization f32'></i><div class='section'>_(Virtual Machines Usage)_</div>
<a href='/Dashboard/Settings/VMSettings' title="_(Go to VM settings)_"><i class='fa fa-fw fa-cog control'></i></a>
</td></tr>
</tbody>
<?endif;?>
<?endif;?>
<tbody title="_(Shares Information)_"<?if ($group):?> class="mixed"<?endif;?>>
@@ -932,7 +943,7 @@ function loadlist(init) {
$('#vms').is(':checked') ? $.cookie('my_vms','startedOnly',{expires:3650}) : $.removeCookie('my_vms');
});
}
$.post('/webGui/include/DashboardApps.php',{docker:'<?=$dockerd?>',vms:'<?=$libvirtd?>'},function(d) {
$.post('/webGui/include/DashboardApps.php',{docker:'<?=$dockerd?>',vms:'<?=$libvirtd?>',vmusage:'<?=$vmusage?>'},function(d) {
var data = d.split('\0');
$('#docker_view tr.updated').remove();
$('#docker_view').append(data[0]).hideMe();
@@ -944,6 +955,8 @@ function loadlist(init) {
var started_vms = $('#vm_view').find('span.outer.vms.started').length;
var stopped_vms = $('#vm_view').find('span.outer.vms.stopped').length;
var paused_vms = $('#vm_view').find('span.outer.vms.paused').length;
$('#vm_view_usage tr.useupdated').remove();
$('#vm_view_usage').append(data[2]).hideMe();
$('.apps.switch').html("_(Containers)_ -- _(Started)_: "+started_apps+", _(Stopped)_: "+stopped_apps+", _(Paused)_: "+paused_apps);
$('.vms.switch').html("_(VMs)_ -- _(Started)_: "+started_vms+", _(Stopped)_: "+stopped_vms+", _(Paused)_: "+paused_vms);
if ($.cookie('my_apps')!=null) $('span.apps.stopped').hide(0,noApps());
@@ -1501,6 +1514,18 @@ function cpu_parse(msg) {
return parse;
}
<?if ($vmusage == "Y"):?>
var vmdashusage = new NchanSubscriber('/sub/vm_dashusage',{subscriber:'websocket'});
vmdashusage.on('message', function(msg){
var data = JSON.parse(msg);
for (const [vm, vmdata] of Object.entries(data)) {
for (const [displayitem, value] of Object.entries(vmdata)) {
$('#vmmetrics-'+displayitem + '-' + vm ).html(value);
}
}
});
<?endif;?>
var dashboard = new NchanSubscriber('/sub/cpuload,update1,update2,update3<?=$wireguard?",wireguard":""?>',{subscriber:'websocket'});
dashboard.on('message',function(msg,meta) {
switch (meta.id.channel()) {
@@ -1667,6 +1692,9 @@ $(function() {
dropdown('enter_view');
startup = false;
dashboard.start();
<?if ($vmusage == "Y"):?>
vmdashusage.start();
<?endif;?>
<?if ($apcupsd):?>
apcups.start();
<?endif;?>
@@ -1692,6 +1720,9 @@ $(function() {
window.onunload = function(){
dashboard.stop();
<?if ($vmusage == "Y"):?>
vmdashusage.stop();
<?endif;?>
<?if ($apcupsd):?>
apcups.stop();
<?endif;?>

View File

@@ -68,6 +68,7 @@ if ($_POST['docker']) {
}
echo "\0";
if ($_POST['vms']) {
$vmusage = $_POST['vmusage'];
$user_prefs = '/boot/config/plugins/dynamix.vm.manager/userprefs.cfg';
$vms = $lv->get_domains() ?: [];
if (file_exists($user_prefs)) {
@@ -78,6 +79,7 @@ if ($_POST['vms']) {
natcasesort($vms);
}
echo "<tr title='' class='updated'><td>";
$running = 0;
foreach ($vms as $vm) {
$res = $lv->get_domain_by_name($vm);
$uuid = libvirt_domain_get_uuid_string($res);
@@ -123,6 +125,7 @@ if ($_POST['vms']) {
$shape = 'play';
$status = 'started';
$color = 'green-text';
$running++;
break;
case 'paused':
case 'pmsuspended':
@@ -140,6 +143,47 @@ if ($_POST['vms']) {
echo "<span class='outer solid vms $status'><span id='vm-$uuid' $menu class='hand'>$image</span><span class='inner'>$vm<br><i class='fa fa-$shape $status $color'></i><span class='state'>"._($status)."</span></span></span>";
}
$none = count($vms) ? _('No running virtual machines') : _('No virtual machines defined');
echo "<span id='no_vms' style='display:none'>$none<br><br></span>";
if ($running == 0) $nodisplay = "style='display:none'"; else $nodisplay = "";
echo "<span id='no_vms' $nodisplay >$none<br><br></span>";
echo "</td></tr>";
echo "\0";
echo "<tr title='' class='useupdated'><td>";
$running = 0;
if ($vmusage == "Y") {
foreach ($vms as $vm) {
$res = $lv->get_domain_by_name($vm);
$uuid = libvirt_domain_get_uuid_string($res);
$dom = $lv->domain_get_info($res);
$id = $lv->domain_get_id($res);
$fstype ="QEMU";
if (($diskcnt = $lv->get_disk_count($res)) > 0) $fstype = $lv->get_disk_fstype($res);
$state = $lv->domain_state_translate($dom['state']);
$template = $lv->_get_single_xpath_result($res, '//domain/metadata/*[local-name()=\'vmtemplate\']/@name');
if (empty($template)) $template = 'Custom';
$log = (is_file("/var/log/libvirt/qemu/$vm.log") ? "libvirt/qemu/$vm.log" : '');
if (!isset($domain_cfg["CONSOLE"])) $vmrcconsole = "web" ; else $vmrcconsole = $domain_cfg["CONSOLE"] ;
$icon = $lv->domain_get_icon_url($res);
if ($state != "running") continue;
$running++;
switch ($state) {
case 'running':
$shape = 'play';
$status = 'started';
$color = 'green-text';
break;
}
$image = substr($icon,-4)=='.png' ? "<img src='$icon' class='img'>" : (substr($icon,0,5)=='icon-' ? "<i class='$icon img'></i>" : "<i class='fa fa-$icon img'></i>");
echo "<span class='outer solid vmsuse $status'><span id='vm-$uuid' >$image</span><span class='inner'>$vm<br><i class='fa fa-$shape $status $color'></i><span class='state'>"._($status)."</span></span>";
echo "<br><br><span id='vmmetrics-gcpu-".$uuid."'>Loading....</span>";
echo "<br><span id='vmmetrics-hcpu-".$uuid."'>Loading....</span>";
echo "<br><span id='vmmetrics-mem-".$uuid."'>Loading....</span>";
echo "<br><span id='vmmetrics-disk-".$uuid."'>Loading....</span>";
echo "<br><span id='vmmetrics-net-".$uuid."'>Loading....</span>";
echo "</span>";
}
if (!count($vms)) echo "<span id='no_usagevms'><br> "._('No running virtual machines')."<br></span>";
if ($running < 1 && count($vms)) echo "<span id='no_usagevms'><br>". _('No running virtual machines')."<br></span>";
echo "</td></tr>";
}
}

View File

@@ -0,0 +1,88 @@
#!/usr/bin/php -q
<?PHP
/* Copyright 2005-2024, Lime Technology
* Copyright 2024-2024, Simon Fairweather.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
?>
<?
$docroot = '/usr/local/emhttp';
$varroot = '/var/local/emhttp';
$md5_old = -1;
require_once "$docroot/webGui/include/Helpers.php";
require_once "$docroot/webGui/include/publish.php";
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
global $vmusagestats;
extract(parse_plugin_cfg('dynamix',true));
get_vm_usage_stats();
sleep(1);
// add translations
$_SERVER['REQUEST_URI'] = 'dashboard';
$login_locale = _var($display,'locale');
require_once "$docroot/webGui/include/Translations.php";
// remember current language
$locale_init = $locale;
function update_translation($locale) {
global $docroot,$language;
$language = [];
if ($locale) {
$text = "$docroot/languages/$locale/translations.txt";
if (file_exists($text)) {
$store = "$docroot/languages/$locale/translations.dot";
if (!file_exists($store)) file_put_contents($store,serialize(parse_lang_file($text)));
$language = unserialize(file_get_contents($store));
}
$text = "$docroot/languages/$locale/dashboard.txt";
if (file_exists($text)) {
$store = "$docroot/languages/$locale/dashboard.dot";
if (!file_exists($store)) file_put_contents($store,serialize(parse_lang_file($text)));
$language = array_merge($language,unserialize(file_get_contents($store)));
}
}
}
$domain_cfgfile = "/boot/config/domain.cfg";
$domain_cfg = parse_ini_file($domain_cfgfile);
if (isset($domain_cfg['USAGE']) && $domain_cfg['USAGE'] != 'Y' ) return;
if (!isset($domain_cfg['USAGETIMER'])) $timer = 3 ; else $timer = $domain_cfg['USAGETIMER'];
while (true) {
extract(parse_plugin_cfg('dynamix',true));
if (_var($display,'locale') != $locale_init) {
$locale_init = _var($display,'locale');
update_translation($locale_init);
}
get_vm_usage_stats();
$echo = [];
foreach ($vmusagestats as $vm => $vmdata) {
if ($vmdata['state'] == 1) {
$vmencode = str_replace(" "," ",$vm);
$vmencode = $lv->domain_get_uuid($vm);
$echo[$vmencode ]['gcpu'] = "<span class='advanced'>"._("Guest CPU").": <span class='cpug-".$vm."'>".$vmdata['cpuguest']."%</span><div class='usage-disk mm'><span id='cpug-".$vm."' style='width:".$vmdata['cpuguest']."%;'></span><span></span></div></span>";
$echo[$vmencode ]['hcpu'] = "<span class='advanced'>"._("Host CPU").": <span class='cpug-".$vm."'>".$vmdata['cpuhost']."%</span><div class='usage-disk mm'><span id='cpug-".$vm."' style='width:".$vmdata['cpuhost']."%;'></span><span></span></div></span>";
$echo[$vmencode ]['mem'] .= "<span>Mem: ".my_scale($vmdata['mem'],$unit)."$unit / ".my_scale($vmdata['maxmem'],$unit)."$unit</span>";
$echo[$vmencode ]['disk'] .= "<span>Disk: "._("Rd").": ".my_scale($vmdata['rdrate'],$unit)."$unit/s "._("Wr").": ".my_scale($vmdata['wrrate'],$unit)."$unit/s</span>";
$echo[$vmencode ]['net'] .= "<span>Net: "._("RX").": ".my_scale($vmdata['rxrate'],$unit)."$unit/s "._("TX").": ".my_scale($vmdata['txrate'],$unit)."$unit/s</span>";
}
}
$echo = json_encode($echo);
file_put_contents("/tmp/vm_dashusage", $echo);
$md5_new = md5($echo,true);
if ($md5_new !== $md5_old) {
$md5_old = publish('vm_dashusage',$echo)!==false ? $md5_new : -1;
}
sleep($timer);
}
?>