diff --git a/dashboard/src/components/CpuUsage.vue b/dashboard/src/components/CpuUsage.vue index 1c798a8d5..b6eb0ca06 100644 --- a/dashboard/src/components/CpuUsage.vue +++ b/dashboard/src/components/CpuUsage.vue @@ -19,10 +19,7 @@ async function refresh() { return moment(v[1]*1000).format('hh:mm'); }); - const data = result.cpu.map(v => { - // v[0] is in percent, need to scale up depending on cpu count 2 cpus => 200% max - return parseInt(v[0]); - }); + const data = result.cpu.map(v => v[0]); // already scaled to cpu*100 new Chart(graph.value, { type: 'line', @@ -31,9 +28,12 @@ async function refresh() { datasets: [{ label: 'CPU', data: data, - radius: 0, + pointRadius: 0, + // https://www.chartjs.org/docs/latest/charts/line.html#line-styling borderWidth: 1, tension: 0.4, + showLine: true, + fill: true }] }, options: { @@ -41,9 +41,23 @@ async function refresh() { legend: false }, scales: { + x: { + ticks: { + autoSkip: true, // skip tick labels as needed + autoSkipPadding: 20, // padding between ticks + maxRotation: 0 // don't rotate the labels + } + }, y: { + ticks: { + callback: (value) => { + return `${value}%`; + }, + maxTicksLimit: 6 // max tick labels to show + }, min: 0, - max: result.cpuCount*100 + max: result.cpuCount * 100, + beginAtZero: true, } }, interaction: { diff --git a/dashboard/src/components/MemoryUsage.vue b/dashboard/src/components/MemoryUsage.vue index 16f7f56a1..ce580d9e8 100644 --- a/dashboard/src/components/MemoryUsage.vue +++ b/dashboard/src/components/MemoryUsage.vue @@ -34,9 +34,12 @@ async function refresh() { datasets: [{ label: 'Memory', data: data, - radius: 0, + pointRadius: 0, + // https://www.chartjs.org/docs/latest/charts/line.html#line-styling borderWidth: 1, tension: 0.4, + showLine: true, + fill: true }] }; const options = { @@ -45,14 +48,18 @@ async function refresh() { }, scales: { x: { - ticks: { autoSkipPadding: 50, maxRotation: 0 } + ticks: { + autoSkip: true, // skip tick labels as needed + autoSkipPadding: 20, // padding between ticks + maxRotation: 0 // don't rotate the labels + } }, y: { ticks: { callback: (value) => { return `${value} GiB`; }, - maxTicksLimit: 6 + maxTicksLimit: 6 // max tick labels to show }, min: 0, max: roundedMemoryGiB, diff --git a/src/graphs.js b/src/graphs.js index d21e1d1c2..51f9a098d 100644 --- a/src/graphs.js +++ b/src/graphs.js @@ -89,8 +89,12 @@ async function getSystemStats(options) { const graphiteUrl = await getGraphiteUrl(); + // example: curl 'http://172.18.30.5:8000/graphite-web/render?target=cloudron.system.cpu-user&target=cloudron.system.cpu-sys&format=json&from=-1min&until=now&noNullPoints=false' | python3 -m json.tool const targets = [ - `summarize(cloudron.system.cpu-used, "${intervalSecs}s", "avg")`, + // perSecond is nonNegativeDerivative over time . this value is the cpu usage in msecs . + // (cpu usage msecs) / (cpus * 1000) is the percent but over all cpus. times 100 is the percent. + // but the y-scale is cpus times 100. so, we only need to scale by 0.1 + `scale(perSecond(sumSeries(cloudron.system.cpu-user,cloudron.system.cpu-sys)),0.1)`, `summarize(cloudron.system.memory-used, "${intervalSecs}s", "avg")` ];