Mercurial > code > home > repos > light9
changeset 2036:00afa5ec081a
restore more of the stats widget including the cpu/mem spinner
author | drewp@bigasterisk.com |
---|---|
date | Sat, 09 Apr 2022 11:44:57 -0700 |
parents | f9faa2ec824f |
children | b731eaad3adf |
files | light9/web/homepage/StatsLine.ts light9/web/homepage/StatsProcess.ts light9/web/homepage/index.html makefile |
diffstat | 4 files changed, 94 insertions(+), 63 deletions(-) [+] |
line wrap: on
line diff
--- a/light9/web/homepage/StatsLine.ts Sat Apr 09 02:49:14 2022 -0700 +++ b/light9/web/homepage/StatsLine.ts Sat Apr 09 11:44:57 2022 -0700 @@ -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 @@ @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 @@ .text() .then((msg) => { this.stats = parsePrometheusTextFormat(msg) as Metrics; + this.extractProcessStats(this.stats); setTimeout(reload, 1000); }) .catch((err) => { @@ -49,6 +53,20 @@ } }); } + 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 @@ } }; -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` - <table> - ${this.stats.filter(nonBoring).map( - (row) => html` - <tr> - <th>${row.name}</th> - <td> - <table> - ${row.metrics.map( - (v) => html` - <tr> - <td>${JSON.stringify(v.labels)}</td> - <td>${v.value}</td> - </tr> + <div> + <table> + ${displayedStats.map( + (row, rowNum) => html` + <tr> + <th>${row.name}</th> + <td> + <table> + ${row.metrics.map( + (v) => html` + <tr> + <td>${JSON.stringify(v.labels)}</td> + <td>${v.value}</td> + </tr> + ` + )} + </table> + </td> + ${rowNum == 0 + ? html` + <td rowspan="${displayedStats.length}"> + <stats-process id="proc" cpu="${this.cpu}" mem="${this.mem}"></stats-process> + </td> ` - )} - </table> - </td> - </tr> - ` - )} - </table> - <stats-process id="proc"></stats-process> + : ""} + </tr> + ` + )} + </table> + </div> `; } }
--- a/light9/web/homepage/StatsProcess.ts Sat Apr 09 02:49:14 2022 -0700 +++ b/light9/web/homepage/StatsProcess.ts Sat Apr 09 11:44:57 2022 -0700 @@ -10,18 +10,18 @@ @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<string, any>) { - 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 @@ 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 @@ ctx.fill(); ctx.restore(); } - updated(changedProperties: Map<string, any>) { - if (changedProperties.has("dataTime")) { - this.shadowRoot!.firstElementChild!.setAttribute("title", `cpu ${this.cpu}% mem ${this.mem}MB`); - } - } static styles = [ css`
--- a/light9/web/homepage/index.html Sat Apr 09 02:49:14 2022 -0700 +++ b/light9/web/homepage/index.html Sat Apr 09 11:44:57 2022 -0700 @@ -7,8 +7,6 @@ <script type="module" src="./ServiceButtonRow.ts"></script> </head> <body> - - --> <h1>light9 home page</h1> <div style="display: grid"> @@ -25,7 +23,7 @@ <service-button-row name="effects"></service-button-row> <service-button-row name="timeline"></service-button-row> <service-button-row name="paint"></service-button-row> - <service-button-row name="effectEval"></service-button-row> + <service-button-row name="effectEval"></service-button-row> <!-- <hr> <service-button-row name="subServer"></service-button-row> <service-button-row name="subComposer"></service-button-row>
--- a/makefile Sat Apr 09 02:49:14 2022 -0700 +++ b/makefile Sat Apr 09 11:44:57 2022 -0700 @@ -21,13 +21,13 @@ pnpm install node_modules/n3/n3-browser.js: - (cd node_modules/n3; nodejs ../browserify/bin/cmd.js --standalone N3 --require n3 -o n3-browser.js) + (cd node_modules/n3; pnpx browserify --standalone N3 --require n3 -o n3-browser.js) light9/web/lib/debug/debug-build.js: - node_modules/browserify/bin/cmd.js light9/web/lib/debug/src/browser.js -o light9/web/lib/debug/debug-build.js --standalone debug + pnpx browserify light9/web/lib/debug/src/browser.js -o light9/web/lib/debug/debug-build.js --standalone debug light9/web/lib/debug/debug-build-es6.js: - node_modules/browserify/bin/cmd.js light9/web/lib/debug/src/browser.js -o light9/web/lib/debug/debug-build-es6.js --standalone debug + pnpx browserify light9/web/lib/debug/src/browser.js -o light9/web/lib/debug/debug-build-es6.js --standalone debug echo "\nexport default window.debug;" >> light9/web/lib/debug/debug-build-es6.js lit_fix: @@ -59,12 +59,6 @@ coffee: zsh -c 'cd light9/web; ../../node_modules/coffeescript/bin/coffee --map -cw {.,live,timeline,paint,effects}/*.coffee' -mypy: - inv mypy - -reformat: - inv reformat - ### show ### qlc_artnet_dmx_proxy: @@ -102,25 +96,25 @@ NOSEARGS="--no-path-adjustment light9.rdfdb.rdflibpatch light9.rdfdb.patch light9.effecteval.test_effect light9.collector light9.rdfdb.graphfile_test light9.paint light9.effect" tests: - eval env/bin/nosetests -x $(NOSEARGS) + eval pdm run nosetests -x $(NOSEARGS) tests_watch: - eval env/bin/nosetests --with-watcher $(NOSEARGS) + eval pdm run nosetests --with-watcher $(NOSEARGS) tests_coverage: - eval env/bin/nosetests --with-coverage --cover-erase --cover-html --cover-html-dir=/tmp/light9-cov/ --cover-package=light9 --cover-branches $(NOSEARGS) + eval pdm run nosetests --with-coverage --cover-erase --cover-html --cover-html-dir=/tmp/light9-cov/ --cover-package=light9 --cover-branches $(NOSEARGS) test_js_init: npm install test_js: - node_modules/coffeescript/bin/coffee -c light9/web/*.coffee - node_modules/mocha/bin/mocha --compilers coffee:coffee-script/register --globals window,N3 light9/web/graph_test.coffee + pnpx coffee -c light9/web/*.coffee + pnpx mocha --compilers coffee:coffee-script/register --globals window,N3 light9/web/graph_test.coffee test_js_watch: # have coffee continuously running - watch -c node_modules/mocha/bin/mocha --compilers coffee:coffee-script/register --globals window,N3 light9/web/graph_test.coffee --colors + watch -c pnpx mocha --compilers coffee:coffee-script/register --globals window,N3 light9/web/graph_test.coffee --colors profile_seq: echo in lib, get https://github.com/uber/pyflame.git and https://github.com/brendangregg/FlameGraph.git