- Fix hermes invocation: 'hermes -q' → 'hermes chat -q' with proper flags
- Replace fragile string.includes('PASS') with llmExtract judge
(previous false positive: matched '--pass-session-id' in usage text)
小橘 🍊(NEKO Team)
121 lines
2.7 KiB
JavaScript
121 lines
2.7 KiB
JavaScript
import { readFile } from "node:fs/promises";
|
|
import { linuxTcpSocketStats } from "./schema.ts";
|
|
|
|
const SOCKSTAT_PATH = "/proc/net/sockstat";
|
|
const RAW_MAX = 4096;
|
|
|
|
function parseInt10(s) {
|
|
const n = Number.parseInt(String(s), 10);
|
|
return Number.isFinite(n) ? Math.trunc(n) : NaN;
|
|
}
|
|
|
|
function parseSockstat(content) {
|
|
let socketsUsed = 0;
|
|
let tcpInuse = 0;
|
|
let tcpOrphan = 0;
|
|
let tcpTw = 0;
|
|
let tcpAlloc = 0;
|
|
let tcpMemPages = 0;
|
|
let parseOk = 1;
|
|
|
|
let socketsOk = false;
|
|
let tcpOk = false;
|
|
|
|
for (const line of content.split("\n")) {
|
|
const trimmed = line.trim();
|
|
if (trimmed.startsWith("sockets:")) {
|
|
const parts = trimmed.split(/\s+/);
|
|
const usedIdx = parts.indexOf("used");
|
|
if (usedIdx !== -1 && usedIdx + 1 < parts.length) {
|
|
const v = parseInt10(parts[usedIdx + 1]);
|
|
if (Number.isFinite(v)) {
|
|
socketsUsed = v;
|
|
socketsOk = true;
|
|
}
|
|
}
|
|
} else if (trimmed.startsWith("TCP:")) {
|
|
const parts = trimmed.split(/\s+/);
|
|
const map = {};
|
|
for (let i = 1; i + 1 < parts.length; i += 2) {
|
|
map[parts[i]] = parseInt10(parts[i + 1]);
|
|
}
|
|
const keys = ["inuse", "orphan", "tw", "alloc", "mem"];
|
|
if (keys.every((k) => Number.isFinite(map[k]))) {
|
|
tcpInuse = map.inuse;
|
|
tcpOrphan = map.orphan;
|
|
tcpTw = map.tw;
|
|
tcpAlloc = map.alloc;
|
|
tcpMemPages = map.mem;
|
|
tcpOk = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!socketsOk || !tcpOk) {
|
|
parseOk = 0;
|
|
socketsUsed = 0;
|
|
tcpInuse = 0;
|
|
tcpOrphan = 0;
|
|
tcpTw = 0;
|
|
tcpAlloc = 0;
|
|
tcpMemPages = 0;
|
|
}
|
|
|
|
return {
|
|
socketsUsed,
|
|
tcpInuse,
|
|
tcpOrphan,
|
|
tcpTw,
|
|
tcpAlloc,
|
|
tcpMemPages,
|
|
parseOk,
|
|
};
|
|
}
|
|
|
|
export async function compute(db, _peers) {
|
|
const ts = Date.now();
|
|
let rawSockstat = "";
|
|
let row = {
|
|
socketsUsed: 0,
|
|
tcpInuse: 0,
|
|
tcpOrphan: 0,
|
|
tcpTw: 0,
|
|
tcpAlloc: 0,
|
|
tcpMemPages: 0,
|
|
parseOk: 0,
|
|
};
|
|
|
|
try {
|
|
const content = await readFile(SOCKSTAT_PATH, "utf8");
|
|
rawSockstat =
|
|
content.length > RAW_MAX ? content.slice(0, RAW_MAX) : content;
|
|
row = parseSockstat(content);
|
|
} catch {
|
|
rawSockstat = "";
|
|
}
|
|
|
|
await db.insert(linuxTcpSocketStats).values({
|
|
ts,
|
|
socketsUsed: row.socketsUsed,
|
|
tcpInuse: row.tcpInuse,
|
|
tcpOrphan: row.tcpOrphan,
|
|
tcpTw: row.tcpTw,
|
|
tcpAlloc: row.tcpAlloc,
|
|
tcpMemPages: row.tcpMemPages,
|
|
parseOk: row.parseOk,
|
|
rawSockstat,
|
|
});
|
|
|
|
return {
|
|
ts,
|
|
socketsUsed: row.socketsUsed,
|
|
tcpInuse: row.tcpInuse,
|
|
tcpOrphan: row.tcpOrphan,
|
|
tcpTw: row.tcpTw,
|
|
tcpAlloc: row.tcpAlloc,
|
|
tcpMemPages: row.tcpMemPages,
|
|
parseOk: row.parseOk,
|
|
rawSockstat,
|
|
};
|
|
}
|