mirror of
https://github.com/khairul169/home-lab.git
synced 2025-04-28 08:39:34 +07:00
114 lines
3.0 KiB
TypeScript
114 lines
3.0 KiB
TypeScript
import { Hono } from "hono";
|
|
import { cors } from "hono/cors";
|
|
import { zValidator } from "@hono/zod-validator";
|
|
import z from "zod";
|
|
import si from "systeminformation";
|
|
|
|
const formatBytes = (bytes: number) => {
|
|
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
|
|
if (bytes === 0) return "n/a";
|
|
const i = parseInt(String(Math.floor(Math.log(bytes) / Math.log(1024))), 10);
|
|
if (i === 0) return `${bytes} ${sizes[i]}`;
|
|
return `${(bytes / 1024 ** i).toFixed(2)} ${sizes[i]}`;
|
|
};
|
|
|
|
const secondsToTime = (seconds: number) => {
|
|
const d = Math.floor(seconds / (3600 * 24));
|
|
const h = Math.floor((seconds % (3600 * 24)) / 3600);
|
|
const m = Math.floor((seconds % 3600) / 60);
|
|
const s = Math.floor(seconds % 60);
|
|
return `${d}d ${h}h ${m}m`;
|
|
};
|
|
|
|
const app = new Hono()
|
|
.use(cors())
|
|
|
|
.get("/", (c) => c.text("It works!"))
|
|
|
|
.get("/system", async (c) => {
|
|
const date = new Date().toISOString();
|
|
const uptime = secondsToTime(si.time().uptime || 0);
|
|
const system = await si.system();
|
|
|
|
const cpuSpeed = await si.cpuCurrentSpeed();
|
|
const cpuTemp = await si.cpuTemperature();
|
|
const cpuLoad = await si.currentLoad();
|
|
const mem = await si.mem();
|
|
|
|
const perf = {
|
|
cpu: {
|
|
load: cpuLoad.currentLoad,
|
|
speed: cpuSpeed.avg,
|
|
temp: cpuTemp.main,
|
|
},
|
|
mem: {
|
|
total: formatBytes(mem.total),
|
|
percent: (mem.active / mem.total) * 100,
|
|
used: formatBytes(mem.active),
|
|
free: formatBytes(mem.total - mem.active),
|
|
},
|
|
};
|
|
|
|
const fsMounts = await si.fsSize();
|
|
const storage = fsMounts
|
|
.filter((i) => i.size > 32 * 1024 * 1024 * 1024)
|
|
.map((i) => ({
|
|
type: i.type,
|
|
mount: i.mount,
|
|
used: formatBytes(i.used),
|
|
percent: (i.used / i.size) * 100,
|
|
total: formatBytes(i.size),
|
|
free: formatBytes(i.available),
|
|
}));
|
|
|
|
return c.json({ uptime, date, system, perf, storage });
|
|
})
|
|
|
|
.get(
|
|
"/process",
|
|
zValidator(
|
|
"query",
|
|
z
|
|
.object({ sort: z.enum(["cpu", "mem"]), limit: z.coerce.number() })
|
|
.partial()
|
|
.optional()
|
|
),
|
|
async (c) => {
|
|
const memTotal = (await si.mem()).total;
|
|
const sort = c.req.query("sort") || "mem";
|
|
const limit = parseInt(c.req.query("limit") || "") || 10;
|
|
|
|
let processList = (await si.processes()).list;
|
|
|
|
if (sort) {
|
|
switch (sort) {
|
|
case "cpu":
|
|
processList = processList.sort((a, b) => b.cpu - a.cpu);
|
|
break;
|
|
case "mem":
|
|
processList = processList.sort((a, b) => b.mem - a.mem);
|
|
break;
|
|
}
|
|
}
|
|
|
|
const list = processList
|
|
.map((p) => ({
|
|
name: p.name,
|
|
cmd: [p.name, p.params].filter(Boolean).join(" "),
|
|
cpu: p.cpu,
|
|
cpuPercent: p.cpu.toFixed(1) + "%",
|
|
mem: p.mem,
|
|
memUsage: formatBytes((p.mem / 100) * memTotal),
|
|
path: p.path,
|
|
user: p.user,
|
|
}))
|
|
.slice(0, limit);
|
|
|
|
return c.json({ list });
|
|
}
|
|
);
|
|
|
|
export type AppType = typeof app;
|
|
|
|
export default app;
|