Mercurial > code > home > repos > racc
view console/src/main.ts @ 6:b1043d39e493
start web console
author | drewp@bigasterisk.com |
---|---|
date | Mon, 13 Mar 2023 18:53:45 -0700 |
parents | |
children |
line wrap: on
line source
import { startOfDay, subDays, differenceInMinutes, getUnixTime, addDays, format, min, formatISO } from "date-fns"; import * as echarts from "echarts"; import { TabulatorFull as Tabulator } from "tabulator-tables"; const QUERY_RANGE = "https://bigasterisk.com/m/prometheus/api/v1/query_range"; const MAC = new Map([ ]); function progQueryUrl(prog: string, s: Date, e: Date): URL { const rangeMins = differenceInMinutes(e, s); const out = new URL(QUERY_RANGE); const host = "Kelsis-iMac"; const isRunningQl = `racc_running{prog="${prog}",host="${host}"}`; const isNonIdleQl = `max(racc_idle{host="${host}"}) < 100`; const countedTimeQl = `(${isRunningQl}) if (${isNonIdleQl})`; const integralQl = `integrate((${countedTimeQl})[${rangeMins}m])`; const hoursQl = `${integralQl}/1h`; out.searchParams.append("query", hoursQl); out.searchParams.append("start", "" + getUnixTime(s)); out.searchParams.append("end", "" + getUnixTime(e)); out.searchParams.append("step", "1m"); return out; } async function queryLastRow(queryUrl: URL): Promise<string> { const response = await fetch(queryUrl); const body = await response.json(); if (!body?.data?.result) { return "0"; } const m = body.data.result[0]; if (m?.values?.length) { const lastRow = m.values[m.values.length - 1]; return parseFloat(lastRow[1]).toFixed(2); } return "0"; } async function makeSeries(now: Date, meas: string, prog: string, numDays: number): Promise<echarts.BarSeriesOption> { const rows = []; const sod = startOfDay(now); for (let i = numDays-1 ; i >= 0; i--) { const s = subDays(sod, i); const e = min([now, addDays(s, 1)]); console.log(i, formatISO(s), formatISO(e)); rows.push(queryLastRow(progQueryUrl(prog, s, e))); } const mc = await Promise.all(rows); return { name: meas, type: "bar", animation: false, data: mc, emphasis: { focus: "series" }, label: { show: true }, stack: "total", }; } function dateRowLabels(now: Date, days: number) { const rowNames = []; for (let d = subDays(now, days - 1); d < now; d = addDays(d, 1)) { rowNames.push(format(d, "MM/dd EEE")); } rowNames.push(format(now, "MM/dd EEE") + " (today)"); return rowNames; } function fillDebugTable(el: HTMLElement) { var rows = []; const vmui = (expr: string, range: string): string => "https://bigasterisk.com/m/vmui/?" + "g0.expr=" + encodeURIComponent(expr) + // "&g0.range_input=" + encodeURIComponent(range); const view = (url: string): string => `<a href="${url}">view</a>`; for (let host of ["Kelsis-iMac", "dash", "dot", "plus"]) { rows.push({ id: rows.length, host: host, metrics: view(`http://${host}:5150/metrics`), uptime: view(vmui(`python_info{job="racc",instance="${host}:5150"}`, "14d")), traffic: view(vmui(`rate(lan_bytes_sent_from_total{mac="${MAC.get(host)}"})`, "6h")), }); } var table = new Tabulator(el, { data: rows, columns: [ { title: "Host", field: "host" }, { title: "current /metrics", field: "metrics", formatter: "html" }, { title: "racc uptime history", field: "uptime", formatter: "html" }, { title: "outgoing net traffic", field: "traffic", formatter: "html" }, ], }); } async function main() { fillDebugTable(document.getElementById("debug1")!); const now = new Date(); const chartDom = document.getElementById("chart1")!; const chart = echarts.init(chartDom); const nDays = 8; const rowNames = dateRowLabels(now, nDays); const option: echarts.EChartsOption = { tooltip: { trigger: "axis", axisPointer: { type: "shadow", }, }, legend: {}, grid: { left: "0%", containLabel: true, }, xAxis: { type: "value", max: 10, }, yAxis: { type: "category", data: rowNames, }, series: await Promise.all([ makeSeries(now, "Minecraft hours", "minecraft", nDays), // makeSeries(now, "Roblox hours", "roblox", nDays), ]), }; console.log(option); chart.setOption(option); } main();