diff --git a/src/globaldata.js b/src/globaldata.js index a804cb2..273e7ca 100644 --- a/src/globaldata.js +++ b/src/globaldata.js @@ -5,5 +5,9 @@ export var GLOBAL = { latestHostVMSList: {}, // latest parsed&successful VDSM's getAllVmStats() result latestEngineVmsList: {}, // latest parsed&successful engine VMS list vmUsage: {}, // historical usage statistics, see addVmUsage() + vmUsageMax: { + disk: 0, + net: 0 + }, hosts: {} // map host-id : host } diff --git a/src/helpers.js b/src/helpers.js index 6220f92..d6a4002 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -113,3 +113,9 @@ export function pruneArray (ar) { debugMsg('pruneArray(): starting length: ' + ar.length + ', resulting length: ' + result.length) return result } + +export function computePercent (val, max) { + var f = (max > 0) ? (val / max) : (0) + f = f.toFixed(4) + return f * 100.0 +} diff --git a/src/hostvms.js b/src/hostvms.js index 1c5da1b..6b98de2 100644 --- a/src/hostvms.js +++ b/src/hostvms.js @@ -8,7 +8,7 @@ import {CONFIG} from './constants' import {GLOBAL} from './globaldata' import {downloadConsole, forceoff, shutdown, renderVmDetailActual, guestIPsToHtml, vmStatusToHtml} from './vmdetail' -import {debugMsg, normalizePercentage, spawnVdsm, parseVdsmJson, printError, goTo, getActualTimeStamp, registerBtnOnClickListener, pruneArray, formatHumanReadableSecsToTime} from './helpers' +import {debugMsg, normalizePercentage, spawnVdsm, parseVdsmJson, printError, goTo, getActualTimeStamp, registerBtnOnClickListener, pruneArray, formatHumanReadableSecsToTime, computePercent} from './helpers' var vdsmDataVmsList = '' // might be partial output from the VDSM process TODO: risk of data overlapping function vdsmOutput (data) { @@ -34,11 +34,11 @@ function getAllVmStatsSuccess () { } function renderHostVms (vmsFull) { - // the 'vmsFull' is parsed json result of getAllVmStats() + // the 'vmsFull' is parsed json result of getAllVmStats() if (vmsFull.hasOwnProperty('items') && vmsFull.items.length > 0) { var vms = [] - // prepare data + // prepare data var timestamp = getActualTimeStamp() vmsFull.items.forEach(function translate (srcVm) { var vm = _getVmDetails(srcVm) @@ -48,18 +48,20 @@ function renderHostVms (vmsFull) { var diskWrite = getVmDeviceRate(srcVm, 'disks', 'writeRate') var netRx = getVmDeviceRate(srcVm, 'network', 'rxRate') var netTx = getVmDeviceRate(srcVm, 'network', 'txRate') - addVmUsage(vm.id, vm.vcpuCount, timestamp, parseFloat(vm.cpuUser), parseFloat(vm.cpuSys), parseFloat(vm.memUsage), - diskRead, diskWrite, netRx, netTx) + + var lastUsageRecord = addVmUsage(vm.id, vm.vcpuCount, timestamp, parseFloat(vm.cpuUser), + parseFloat(vm.cpuSys), parseFloat(vm.memUsage), diskRead, diskWrite, netRx, netTx) + appendVmUsage(vm, lastUsageRecord) }) - // render vms list from template + // render vms list from template var data = {units: vms} var template = $('#vms-list-templ').html() var html = Mustache.to_html(template, data) $('#virtual-machines-list').html(html) $('#virtual-machines-novm-message').hide() - // register button event listeners + // register button event listeners registerBtnOnClickListener('btn-download-console-', downloadConsole) registerBtnOnClickListener('btn-forceoff-vm-', forceoff) registerBtnOnClickListener('btn-shutdown-vm-', shutdown) @@ -91,6 +93,19 @@ export function onVmClick (vmId) { // show vm detail } // --- vms-screen usage charts ------------------------------------------ +// var diskMax = 0 +// var netMax = 0 +function computeUsageMaxs (lastRecord) { + /* $.each(GLOBAL.vmUsage, function (key, usageRecords) { + var last = usageRecords[usageRecords.length - 1] + diskMax = Math.max(last.diskRead, last.diskWrite, diskMax) + netMax = Math.max(last.netRx, last.netTx, netMax) + }) */ + GLOBAL.vmUsageMax.disk = Math.max(lastRecord.diskRead, lastRecord.diskWrite, GLOBAL.vmUsageMax.disk) + GLOBAL.vmUsageMax.net = Math.max(lastRecord.netRx, lastRecord.netTx, GLOBAL.vmUsageMax.net) + debugMsg('Max diskMax=' + GLOBAL.vmUsageMax.disk + ', netMax=' + GLOBAL.vmUsageMax.net) +} + function addVmUsage (vmId, vcpuCount, timestamp, cpuUser, cpuSys, mem, diskRead, diskWrite, netRx, netTx) { var record = { timestamp: timestamp, @@ -112,6 +127,10 @@ function addVmUsage (vmId, vcpuCount, timestamp, cpuUser, cpuSys, mem, diskRead, GLOBAL.vmUsage[vmId] = pruneArray(GLOBAL.vmUsage[vmId]) } GLOBAL.vmUsage[vmId].push(record) + + computeUsageMaxs(record) + + return record } function getUsageElementId (device, vmId) { @@ -145,7 +164,7 @@ function refreshMemoryChart (chartDivId, usageRecord) { var labels = [used + '%'] refreshDonutChart(chartDivId, labels, [['Free', free], ['Used', used]], [['available', 'used']]) } - +/* function refreshDiskIOChart (chartDivId, usageRecord, diskMax) { var r = usageRecord.diskRead var w = usageRecord.diskWrite @@ -159,7 +178,7 @@ function refreshNetworkIOChart (chartDivId, usageRecord, netMax) { refreshDoubleBarChart(chartDivId, 'Net MB/s', 'Rx', r, 'Tx', w, netMax) } - +*/ function refreshDonutChart (chartDivId, labels, columns, groups) { var chartConfig = $().c3ChartDefaults().getDefaultDonutConfig() chartConfig.bindto = chartDivId @@ -178,7 +197,7 @@ function refreshDonutChart (chartDivId, labels, columns, groups) { c3.generate(chartConfig) - // add labels + // add labels var donutChartTitle = d3.select(chartDivId).select('text.c3-chart-arcs-title') donutChartTitle.text('') donutChartTitle.insert('tspan').text(labels[0]).classed('donut-title-small-pf', true).attr('dy', 0).attr('x', 0) @@ -186,7 +205,7 @@ function refreshDonutChart (chartDivId, labels, columns, groups) { donutChartTitle.insert('tspan').text(labels[1]).classed('donut-title-small-pf', true).attr('dy', 20).attr('x', 0) } } - +/* function refreshDoubleBarChart (chartElemId, categoryName, leftDescr, leftVal, rightDescr, rightVal, maximum) { var height = $(chartElemId).attr('chartHeight') height = height || 100 @@ -226,38 +245,29 @@ function refreshDoubleBarChart (chartElemId, categoryName, leftDescr, leftVal, r } chartConfig.data = { columns: [ - [leftDescr, leftVal], - [rightDescr, rightVal] + [leftDescr, leftVal], + [rightDescr, rightVal] ], type: 'bar' } c3.generate(chartConfig) } - -var diskMax = 0 -var netMax = 0 +*/ function refreshUsageCharts () { - $.each(GLOBAL.vmUsage, function (key, usageRecords) { - var last = usageRecords[usageRecords.length - 1] - diskMax = Math.max(last.diskRead, last.diskWrite, diskMax) - netMax = Math.max(last.netRx, last.netTx, netMax) - }) - debugMsg('Max diskMax=' + diskMax + ', netMax=' + netMax) - $.each(GLOBAL.vmUsage, function (key, usageRecords) { if (usageRecords.length > 0) { var last = usageRecords[usageRecords.length - 1] refreshCpuChart(getUsageElementId('cpu', key), last) refreshMemoryChart(getUsageElementId('mem', key), last) - refreshDiskIOChart(getUsageElementId('diskio', key), last, diskMax) - refreshNetworkIOChart(getUsageElementId('networkio', key), last, netMax) + // refreshDiskIOChart(getUsageElementId('diskio', key), last, diskMax) + // refreshNetworkIOChart(getUsageElementId('networkio', key), last, netMax) } }) } // ---------------------------------------------------------------------- -export function _getVmDetails (src) { // src is one item from parsed getAllVmStats +export function _getVmDetails (src, usageRecord) { // src is one item from parsed getAllVmStats if (!src) { return undefined } @@ -293,5 +303,26 @@ export function _getVmDetails (src) { // src is one item from parsed getAllVmSta kvmEnable: src.kvmEnable, acpiEnable: src.acpiEnable } + return vm } + +function appendVmUsage (vm, usageRecord) { + vm['diskUsage'] = { + Read: usageRecord.diskRead, + ReadMax: GLOBAL.vmUsageMax.disk, + ReadPercent: computePercent(usageRecord.diskRead, GLOBAL.vmUsageMax.disk), + Write: usageRecord.diskWrite, + WriteMax: GLOBAL.vmUsageMax.disk, + WritePercent: computePercent(usageRecord.diskWrite, GLOBAL.vmUsageMax.disk) + } + + vm['netUsage'] = { + Rx: usageRecord.netRx, + RxMax: GLOBAL.vmUsageMax.net, + RxPercent: computePercent(5, GLOBAL.vmUsageMax.net), + Tx: usageRecord.netTx, + TxMax: GLOBAL.vmUsageMax.net, + TxPercent: computePercent(50, GLOBAL.vmUsageMax.net) + } +} diff --git a/src/vmdetail.js b/src/vmdetail.js index b44984a..15eafa7 100644 --- a/src/vmdetail.js +++ b/src/vmdetail.js @@ -10,7 +10,7 @@ import {VM_STATUS_ICONS, VM_STATUS_ICONS_PATH_PREFIX} from './constants' import {CONFIG} from './constants' import {GLOBAL} from './globaldata' -import {printError, spawnVdsm, vdsmFail} from './helpers' +import {printError, spawnVdsm, vdsmFail, debugMsg} from './helpers' import {_getVmDetails, readVmsList} from './hostvms' // depends on hostvms.js::latestHostVMSList @@ -32,6 +32,7 @@ export function downloadConsole (vmId) { } export function shutdown (vmId) { + debugMsg('shutdown of: ' + vmId) spawnVdsm('shutdown', null, null, shutdownSuccess, vdsmFail, vmId) } @@ -40,6 +41,7 @@ function shutdownSuccess () { } export function forceoff (vmId) { + debugMsg('forceoff of: ' + vmId) spawnVdsm('destroy', null, null, shutdownSuccess, vdsmFail, vmId) } @@ -59,12 +61,12 @@ export function renderVmDetail (vmId) { return } + $('#vm-detail-not-available').hide() + var template = $('#vm-detail-templ').html() var html = Mustache.to_html(template, vm) $('#vm-detail-content').html(html) - $('#vm-detail-not-available').hide() - renderUsageChartsDetail(vmId) } diff --git a/static/ovirt.html b/static/ovirt.html index 70ae0e1..c74c8f5 100644 --- a/static/ovirt.html +++ b/static/ovirt.html @@ -221,12 +221,48 @@