portal/web/webstat.mjs

122 lines
3.5 KiB
JavaScript

//import Chart from "https://esm.run/chart.js@4.2.1/auto"
import Chart from "https://cdn.jsdelivr.net/npm/chart.js@4.2.1/auto/+esm"
const Millisecond = 1
const Second = 1000 * Millisecond
const Minute = 60 * Second
function qpush(arr, val, len) {
arr.push(val)
if (arr.length > len) {
arr.shift()
}
}
class Stat {
constructor(text) {
let lines = text.split("\n")
for (let line of lines) {
let parts = line.split(/\s+/)
let key = parts.shift()
let vals = parts.map(Number)
if (key.startsWith("cpu")) {
this[key] = {
user: vals[0],
nice: vals[1],
sys: vals[2],
idle: vals[3],
wait: vals[4],
irq: vals[5],
softirq: vals[6],
steal: vals[7],
guest: vals[8],
guestNice: vals[9],
}
} else {
this[key] = vals
}
}
}
}
class StatUpdater {
constructor(interval, width=60) {
this.width = width
this.canvas = document.querySelector("#stats")
this.data ={
labels: [],
datasets: []
}
this.datasets = {}
for (let label of ["user", "nice", "sys", "idle", "wait"]) {
let d = []
this.data.datasets.push({
label: label,
data: d,
})
this.datasets[label] = d
}
this.chart = new Chart(
this.canvas,
{
type: "line",
data: this.data,
options: {
responsive: true,
pointStyle: false,
scales: {
x: {
title: { display: false },
ticks: { display: false },
grid: { display: false },
},
y: {
stacked: true,
ticks: { display: false },
}
}
}
}
)
setInterval(() => this.update(), interval)
this.update()
}
async update() {
let now = Date.now()
let resp = await fetch("proc/stat")
let stext = await resp.text()
let stat = new Stat(stext)
if (this.last) {
let user = stat.cpu.user - this.last.cpu.user
let nice = stat.cpu.nice - this.last.cpu.nice
let sys = stat.cpu.sys - this.last.cpu.sys
let idle = stat.cpu.idle - this.last.cpu.idle
let wait = stat.cpu.wait - this.last.cpu.wait
let total = user + nice + sys + idle + wait
qpush(this.data.labels, now, this.width)
qpush(this.datasets.user, user/total, this.width)
qpush(this.datasets.nice, nice/total, this.width)
qpush(this.datasets.sys, sys/total, this.width)
qpush(this.datasets.idle, idle/total, this.width)
qpush(this.datasets.wait, wait/total, this.width)
//this.data.datasets[0].label= `user: ${user/total*100}`
}
this.last = stat
this.chart.update()
}
}
function init() {
new StatUpdater(2*Second)
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init)
} else {
init()
}