64 lines
1.9 KiB
JavaScript
64 lines
1.9 KiB
JavaScript
'use strict';
|
||
|
||
const si = require('systeminformation');
|
||
const os = require('os');
|
||
|
||
/**
|
||
* 采集当前系统指标,返回符合 claw 协议的 metrics 对象
|
||
* 所有数值均保留 2 位小数,内存/磁盘单位为 KB
|
||
*/
|
||
async function collect() {
|
||
const [load, mem, fsArr, temp] = await Promise.allSettled([
|
||
si.currentLoad(),
|
||
si.mem(),
|
||
si.fsSize(),
|
||
si.cpuTemperature(),
|
||
]);
|
||
|
||
const r2 = (v) => (typeof v === 'number' && isFinite(v)) ? Math.round(v * 100) / 100 : null;
|
||
const toKB = (bytes) => (typeof bytes === 'number') ? Math.round(bytes / 1024) : null;
|
||
|
||
// CPU
|
||
const cpu = load.status === 'fulfilled'
|
||
? r2(load.value.currentLoad)
|
||
: null;
|
||
|
||
// 内存(bytes → KB);用 total - available 反映真实占用,与 free -h 一致
|
||
const memVal = mem.status === 'fulfilled' ? mem.value : {};
|
||
const mem_total = toKB(memVal.total);
|
||
const mem_used = toKB((memVal.total || 0) - (memVal.available || 0));
|
||
|
||
// 磁盘:聚合所有真实挂载点,排除虚拟文件系统
|
||
const VIRTUAL_FS = new Set(['tmpfs', 'devtmpfs', 'overlay', 'squashfs', 'ramfs', 'sysfs', 'proc']);
|
||
let disk_total = null, disk_used = null;
|
||
if (fsArr.status === 'fulfilled' && fsArr.value.length > 0) {
|
||
const realFs = fsArr.value.filter(f => f.size > 0 && !VIRTUAL_FS.has(f.type));
|
||
if (realFs.length > 0) {
|
||
disk_total = toKB(realFs.reduce((s, f) => s + f.size, 0));
|
||
disk_used = toKB(realFs.reduce((s, f) => s + f.used, 0));
|
||
}
|
||
}
|
||
|
||
// 温度
|
||
const temperature = temp.status === 'fulfilled'
|
||
? r2(temp.value.main)
|
||
: null;
|
||
|
||
// 负载(/proc/loadavg,Linux 原生)
|
||
const [load_1m, load_5m, load_15m] = os.loadavg().map(r2);
|
||
|
||
// 运行时间(秒)
|
||
const uptime = Math.floor(os.uptime());
|
||
|
||
return {
|
||
cpu,
|
||
mem_total, mem_used,
|
||
disk_total, disk_used,
|
||
temperature,
|
||
load_1m, load_5m, load_15m,
|
||
uptime,
|
||
};
|
||
}
|
||
|
||
module.exports = { collect };
|