comparison console/src/main.ts @ 6:b1043d39e493

start web console
author drewp@bigasterisk.com
date Mon, 13 Mar 2023 18:53:45 -0700
parents
children
comparison
equal deleted inserted replaced
5:5a99bde7a506 6:b1043d39e493
1 import { startOfDay, subDays, differenceInMinutes, getUnixTime, addDays, format, min, formatISO } from "date-fns";
2 import * as echarts from "echarts";
3 import { TabulatorFull as Tabulator } from "tabulator-tables";
4
5 const QUERY_RANGE = "https://bigasterisk.com/m/prometheus/api/v1/query_range";
6 const MAC = new Map([
7 ]);
8
9 function progQueryUrl(prog: string, s: Date, e: Date): URL {
10 const rangeMins = differenceInMinutes(e, s);
11 const out = new URL(QUERY_RANGE);
12
13 const host = "Kelsis-iMac";
14 const isRunningQl = `racc_running{prog="${prog}",host="${host}"}`;
15 const isNonIdleQl = `max(racc_idle{host="${host}"}) < 100`;
16 const countedTimeQl = `(${isRunningQl}) if (${isNonIdleQl})`;
17 const integralQl = `integrate((${countedTimeQl})[${rangeMins}m])`;
18 const hoursQl = `${integralQl}/1h`;
19
20 out.searchParams.append("query", hoursQl);
21 out.searchParams.append("start", "" + getUnixTime(s));
22 out.searchParams.append("end", "" + getUnixTime(e));
23 out.searchParams.append("step", "1m");
24 return out;
25 }
26
27 async function queryLastRow(queryUrl: URL): Promise<string> {
28 const response = await fetch(queryUrl);
29 const body = await response.json();
30 if (!body?.data?.result) {
31 return "0";
32 }
33 const m = body.data.result[0];
34 if (m?.values?.length) {
35 const lastRow = m.values[m.values.length - 1];
36 return parseFloat(lastRow[1]).toFixed(2);
37 }
38 return "0";
39 }
40
41 async function makeSeries(now: Date, meas: string, prog: string, numDays: number): Promise<echarts.BarSeriesOption> {
42 const rows = [];
43 const sod = startOfDay(now);
44
45 for (let i = numDays-1 ; i >= 0; i--) {
46 const s = subDays(sod, i);
47 const e = min([now, addDays(s, 1)]);
48 console.log(i, formatISO(s), formatISO(e));
49 rows.push(queryLastRow(progQueryUrl(prog, s, e)));
50 }
51 const mc = await Promise.all(rows);
52
53 return {
54 name: meas,
55 type: "bar",
56 animation: false,
57 data: mc,
58 emphasis: { focus: "series" },
59 label: { show: true },
60 stack: "total",
61
62 };
63 }
64
65 function dateRowLabels(now: Date, days: number) {
66 const rowNames = [];
67 for (let d = subDays(now, days - 1); d < now; d = addDays(d, 1)) {
68 rowNames.push(format(d, "MM/dd EEE"));
69 }
70 rowNames.push(format(now, "MM/dd EEE") + " (today)");
71 return rowNames;
72 }
73
74 function fillDebugTable(el: HTMLElement) {
75 var rows = [];
76
77 const vmui = (expr: string, range: string): string =>
78 "https://bigasterisk.com/m/vmui/?" +
79 "g0.expr=" +
80 encodeURIComponent(expr) + //
81 "&g0.range_input=" +
82 encodeURIComponent(range);
83 const view = (url: string): string => `<a href="${url}">view</a>`;
84 for (let host of ["Kelsis-iMac", "dash", "dot", "plus"]) {
85 rows.push({
86 id: rows.length,
87 host: host,
88 metrics: view(`http://${host}:5150/metrics`),
89 uptime: view(vmui(`python_info{job="racc",instance="${host}:5150"}`, "14d")),
90 traffic: view(vmui(`rate(lan_bytes_sent_from_total{mac="${MAC.get(host)}"})`, "6h")),
91 });
92 }
93 var table = new Tabulator(el, {
94 data: rows,
95 columns: [
96 { title: "Host", field: "host" },
97 { title: "current /metrics", field: "metrics", formatter: "html" },
98 { title: "racc uptime history", field: "uptime", formatter: "html" },
99 { title: "outgoing net traffic", field: "traffic", formatter: "html" },
100 ],
101 });
102 }
103
104 async function main() {
105 fillDebugTable(document.getElementById("debug1")!);
106
107 const now = new Date();
108
109 const chartDom = document.getElementById("chart1")!;
110 const chart = echarts.init(chartDom);
111
112 const nDays = 8;
113 const rowNames = dateRowLabels(now, nDays);
114
115 const option: echarts.EChartsOption = {
116 tooltip: {
117 trigger: "axis",
118 axisPointer: {
119 type: "shadow",
120 },
121 },
122 legend: {},
123 grid: {
124 left: "0%",
125 containLabel: true,
126 },
127 xAxis: {
128 type: "value",
129 max: 10,
130 },
131 yAxis: {
132 type: "category",
133 data: rowNames,
134 },
135 series: await Promise.all([
136 makeSeries(now, "Minecraft hours", "minecraft", nDays), //
137 makeSeries(now, "Roblox hours", "roblox", nDays),
138 ]),
139 };
140 console.log(option);
141 chart.setOption(option);
142 }
143 main();