# HG changeset patch
# User drewp@bigasterisk.com
# Date 2022-04-09 18:44:57
# Node ID 00afa5ec081aee1e49b1b674780be85730079e08
# Parent f9faa2ec824fe967c35ea81d07177a04499f63fd
restore more of the stats widget including the cpu/mem spinner
diff --git a/light9/web/homepage/StatsLine.ts b/light9/web/homepage/StatsLine.ts
--- a/light9/web/homepage/StatsLine.ts
+++ b/light9/web/homepage/StatsLine.ts
@@ -1,7 +1,5 @@
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators.js";
-import { rounding } from "significant-rounding";
-import { StatsProcess } from "./StatsProcess";
export { StatsProcess } from "./StatsProcess";
import parsePrometheusTextFormat from "parse-prometheus-text-format";
@@ -22,6 +20,11 @@ export class StatsLine extends LitElemen
@property() name = "?";
@property() stats: Metrics = [];
+ prevCpuNow = 0;
+ prevCpuTotal = 0;
+ @property() cpu = 0;
+ @property() mem = 0;
+
updated(changedProperties: any) {
changedProperties.forEach((oldValue: any, propName: string) => {
if (propName == "name") {
@@ -32,6 +35,7 @@ export class StatsLine extends LitElemen
.text()
.then((msg) => {
this.stats = parsePrometheusTextFormat(msg) as Metrics;
+ this.extractProcessStats(this.stats);
setTimeout(reload, 1000);
})
.catch((err) => {
@@ -49,6 +53,20 @@ export class StatsLine extends LitElemen
}
});
}
+ extractProcessStats(stats: Metrics) {
+ stats.forEach((row) => {
+ if (row.name == "process_resident_memory_bytes") {
+ this.mem = parseFloat(row.metrics[0].value) / 1024 / 1024;
+ }
+ if (row.name == "process_cpu_seconds_total") {
+ const now = Date.now() / 1000;
+ const cpuSecondsTotal = parseFloat(row.metrics[0].value);
+ this.cpu = (cpuSecondsTotal - this.prevCpuTotal) / (now - this.prevCpuNow);
+ this.prevCpuTotal = cpuSecondsTotal;
+ this.prevCpuNow = now;
+ }
+ });
+ }
static styles = [
css`
@@ -195,34 +213,52 @@ export class StatsLine extends LitElemen
}
};
-const nonBoring = (m: Metric)=>{
- return !m.name.endsWith('_created') && m.name!= 'python_info'
-}
+ const nonBoring = (m: Metric) => {
+ return (
+ !m.name.endsWith("_created") && //
+ !m.name.startsWith("python_gc_") &&
+ m.name != "python_info" &&
+ m.name != "process_max_fds" &&
+ m.name != "process_virtual_memory_bytes" &&
+ m.name != "process_resident_memory_bytes" &&
+ m.name != "process_start_time_seconds" &&
+ m.name != "process_cpu_seconds_total"
+ );
+ };
// return table(this.stats, []);
+ const displayedStats = this.stats.filter(nonBoring);
return html`
-
- ${this.stats.filter(nonBoring).map(
- (row) => html`
-
- ${row.name} |
-
-
- ${row.metrics.map(
- (v) => html`
-
- ${JSON.stringify(v.labels)} |
- ${v.value} |
-
+
+
+ ${displayedStats.map(
+ (row, rowNum) => html`
+
+ ${row.name} |
+
+
+ ${row.metrics.map(
+ (v) => html`
+
+ ${JSON.stringify(v.labels)} |
+ ${v.value} |
+
+ `
+ )}
+
+ |
+ ${rowNum == 0
+ ? html`
+
+
+ |
`
- )}
-
-
-
- `
- )}
-
-
+ : ""}
+ |
+ `
+ )}
+
+
`;
}
}
diff --git a/light9/web/homepage/StatsProcess.ts b/light9/web/homepage/StatsProcess.ts
--- a/light9/web/homepage/StatsProcess.ts
+++ b/light9/web/homepage/StatsProcess.ts
@@ -10,18 +10,18 @@ const remap = (x: number, lo: number, hi
@customElement("stats-process")
export class StatsProcess extends LitElement {
- @property() dataTime: number = 0; // millis at last data change
- @property() cpu: number = 12; // process_cpu_seconds_total
- @property() mem: number = 50000000; // process_resident_memory_bytes
+ // inspired by https://codepen.io/qiruiyin/pen/qOopQx
+ @property() cpu = 0; // process_cpu_seconds_total
+ @property() mem = 0; // process_resident_memory_bytes
w = 64;
h = 64;
revs = 0;
prev = 0;
+ canvas?: HTMLCanvasElement;
ctx?: CanvasRenderingContext2D;
- firstUpdated(c: Map) {
- super.firstUpdated(c);
- // inspired by https://codepen.io/qiruiyin/pen/qOopQx
+ connectedCallback() {
+ super.connectedCallback();
this.initCanvas(this.shadowRoot!.firstElementChild as HTMLCanvasElement);
this.prev = Date.now() / 1000;
@@ -32,27 +32,35 @@ export class StatsProcess extends LitEle
animate();
}
initCanvas(canvas: HTMLCanvasElement) {
- var ctx = canvas.getContext("2d")!;
+ if (!canvas) {
+ return;
+ }
+ this.canvas = canvas;
+ this.ctx = this.canvas.getContext("2d")!;
- canvas.width = this.w;
- canvas.height = this.h;
+ this.canvas.width = this.w;
+ this.canvas.height = this.h;
}
redraw() {
+ if (!this.ctx) {
+ this.initCanvas(this.shadowRoot!.firstElementChild as HTMLCanvasElement);
+ }
if (!this.ctx) return;
+
+ this.canvas!.setAttribute("title",
+ `cpu ${new Number(this.cpu).toPrecision(3)}% mem ${new Number(this.mem).toPrecision(3)}MB`);
+
const now = Date.now() / 1000;
const ctx = this.ctx;
ctx.beginPath();
// wrong type of fade- never goes to 0
ctx.fillStyle = "#00000003";
ctx.fillRect(0, 0, this.w, this.h);
- // if (!this.data || this.data.time < now - 2) {
- // return;
- // }
const dt = now - this.prev;
this.prev = now;
- const size = remap(this.mem / 1024 / 1024, /*in*/ 20, 600, /*out*/ 3, 30);
- this.revs += dt * remap(this.cpu, /*in*/ 0, 100, /*out*/ 4, 120);
+ const size = remap(this.mem.valueOf() / 1024 / 1024, /*in*/ 20, 600, /*out*/ 3, 30);
+ this.revs += dt * remap(this.cpu.valueOf(), /*in*/ 0, 100, /*out*/ 4, 120);
const rad = remap(size, /*in*/ 3, 30, /*out*/ 14, 5);
var x = this.w / 2 + rad * Math.cos(this.revs / 6.28),
@@ -65,11 +73,6 @@ export class StatsProcess extends LitEle
ctx.fill();
ctx.restore();
}
- updated(changedProperties: Map) {
- if (changedProperties.has("dataTime")) {
- this.shadowRoot!.firstElementChild!.setAttribute("title", `cpu ${this.cpu}% mem ${this.mem}MB`);
- }
- }
static styles = [
css`
diff --git a/light9/web/homepage/index.html b/light9/web/homepage/index.html
--- a/light9/web/homepage/index.html
+++ b/light9/web/homepage/index.html
@@ -7,8 +7,6 @@
-
- -->
light9 home page
@@ -25,7 +23,7 @@
-
+