mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-11 04:36:48 +00:00
perf(instances): the VM stats no longer wait a second per poll
Each stats answer carries a signed sample of the counters, bound to the VM, its compute and UUID. The next poll sends it back and the rates are the averages since then; a sample from another run of the VM (domain ID), another host CPU count or device list, or older than 30 s falls back to one second as before. Windows are measured on the monotonic clock. Now that a poll is cheap, the Stats tab polls every 5 s like the host graph, the first time as soon as it opens (pollWhileVisible takes the delay of the first request). A counter the host reports as unsupported (-1) or that went back gives no value instead of 0 or a jump; a NIC without a target keeps its chart, a pool volume disk is measured, and a disk or NIC attached after the page loaded no longer stops the other charts. Disk rates are MB/s (they were MiB/s labelled Mb/s), network Mbit/s; the CPU tooltip names the window.
This commit is contained in:
parent
27f4845086
commit
24231813d7
8 changed files with 501 additions and 152 deletions
|
|
@ -381,8 +381,13 @@
|
|||
<script src="{% static 'js/Chart.bundle.min.js' %}"></script>
|
||||
<script src="{% static 'js/poll.js' %}"></script>
|
||||
<script>
|
||||
{% trans "average over" as average_over %}
|
||||
var stats_tab = document.querySelector('#graphics-tab');
|
||||
var stats_poll = null;
|
||||
// the seconds each CPU point averages
|
||||
var cpuWindows = [];
|
||||
// the usage sample of the previous answer: the next one averages since then
|
||||
var statsSample = null;
|
||||
// The charts are polled while the Stats tab is shown; they are made once.
|
||||
stats_tab.addEventListener('hidden.bs.tab', function (event) {
|
||||
stats_poll.stop();
|
||||
|
|
@ -436,7 +441,9 @@
|
|||
if (label) {
|
||||
label += ': ';
|
||||
}
|
||||
return label += tooltipItem.yLabel + ' %';
|
||||
label += tooltipItem.yLabel + ' %';
|
||||
var span = cpuWindows[tooltipItem.index];
|
||||
return span ? label + ' ({{ average_over|escapejs }} ' + span + ' s)' : label;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -530,7 +537,7 @@
|
|||
suggestedmax: 100,
|
||||
suggestedMin: 0,
|
||||
callback: function(value, index, values) {
|
||||
return value + ' Mb/s';
|
||||
return value + ' MB/s';
|
||||
}
|
||||
},
|
||||
}],
|
||||
|
|
@ -542,7 +549,7 @@
|
|||
if (label) {
|
||||
label += ': ';
|
||||
}
|
||||
return label += tooltipItem.yLabel + ' Mb/s';
|
||||
return label += tooltipItem.yLabel + ' MB/s';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -608,14 +615,21 @@
|
|||
});
|
||||
{% endfor %}
|
||||
|
||||
stats_poll = pollWhileVisible(10000, function () {
|
||||
return $.getJSON("{% url 'instances:stats' instance.id %}");
|
||||
// the first point at once, then every 5 s like the host graph
|
||||
stats_poll = pollWhileVisible(5000, function () {
|
||||
return $.getJSON("{% url 'instances:stats' instance.id %}", statsSample ? {sample: statsSample} : {})
|
||||
.fail(function () {
|
||||
statsSample = null;
|
||||
});
|
||||
}, function graph_usage(data) {
|
||||
statsSample = data.sample || null;
|
||||
cpuChart.data.labels.push(data.timeline);
|
||||
cpuChart.data.datasets[0].data.push(data.cpudata);
|
||||
cpuWindows.push(data.window);
|
||||
if (cpuChart.data.datasets[0].data.length > 10){
|
||||
cpuChart.data.labels.shift();
|
||||
cpuChart.data.datasets[0].data.shift();
|
||||
cpuWindows.shift();
|
||||
}
|
||||
cpuChart.update();
|
||||
|
||||
|
|
@ -629,32 +643,24 @@
|
|||
}
|
||||
memChart.update();
|
||||
|
||||
for (let j = 0; j < data.blkdata.length; j++) {
|
||||
diskChart[data.blkdata[j].dev].data.labels.push(data.timeline);
|
||||
|
||||
diskChart[data.blkdata[j].dev].data.datasets[0].data.push(data.blkdata[j].data[0]);
|
||||
diskChart[data.blkdata[j].dev].data.datasets[1].data.push(data.blkdata[j].data[1]);
|
||||
if (diskChart[data.blkdata[j].dev].data.datasets[0].data.length > 10){
|
||||
diskChart[data.blkdata[j].dev].data.labels.shift();
|
||||
diskChart[data.blkdata[j].dev].data.datasets[0].data.shift();
|
||||
diskChart[data.blkdata[j].dev].data.datasets[1].data.shift();
|
||||
// a disk or NIC added after the page loaded has no chart until a reload
|
||||
function push(chart, values) {
|
||||
if (!chart) {
|
||||
return;
|
||||
}
|
||||
diskChart[data.blkdata[j].dev].update();
|
||||
}
|
||||
|
||||
for (let j = 0; j < data.netdata.length; j++) {
|
||||
netChart[data.netdata[j].dev].data.labels.push(data.timeline);
|
||||
|
||||
netChart[data.netdata[j].dev].data.datasets[0].data.push(data.netdata[j].data[0]);
|
||||
netChart[data.netdata[j].dev].data.datasets[1].data.push(data.netdata[j].data[1]);
|
||||
if (netChart[data.netdata[j].dev].data.datasets[0].data.length > 10){
|
||||
netChart[data.netdata[j].dev].data.labels.shift();
|
||||
netChart[data.netdata[j].dev].data.datasets[0].data.shift();
|
||||
netChart[data.netdata[j].dev].data.datasets[1].data.shift();
|
||||
chart.data.labels.push(data.timeline);
|
||||
chart.data.datasets[0].data.push(values[0]);
|
||||
chart.data.datasets[1].data.push(values[1]);
|
||||
if (chart.data.datasets[0].data.length > 10){
|
||||
chart.data.labels.shift();
|
||||
chart.data.datasets[0].data.shift();
|
||||
chart.data.datasets[1].data.shift();
|
||||
}
|
||||
netChart[data.netdata[j].dev].update();
|
||||
chart.update();
|
||||
}
|
||||
});
|
||||
data.blkdata.forEach(function (disk) { push(diskChart[disk.dev], disk.data); });
|
||||
data.netdata.forEach(function (nic) { push(netChart[nic.dev], nic.data); });
|
||||
}, 0);
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue