新增设备巡检模块核心功能,包括: - 巡检数据存储与调度系统 - 华为/H3C交换机及Linux服务器采集器 - 设备扩展配置与告警规则管理 - 主机详情页巡检配置入口 - 产品名称自定义设置功能 - 网络设备SSH exec通道兼容处理
103 lines
2.9 KiB
JavaScript
103 lines
2.9 KiB
JavaScript
"use strict";
|
||
|
||
/**
|
||
* Linux 服务器采集器
|
||
*
|
||
* 采集指标(告警相关):
|
||
* - cpu_usage CPU 使用率(%)
|
||
* - memory_usage 内存使用率(%)
|
||
* - disk_usage 磁盘使用率(%,只显示超过 80% 的挂载点)
|
||
*
|
||
* 实现说明:
|
||
* 直接使用 POSIX shell 命令,命令与 NetMesh System Manager 的概览一致。
|
||
* 传入 exec 函数来执行远程命令(由调度器注入,复用 SSH 连接池)。
|
||
*/
|
||
|
||
const BaseAdapter = require("./baseAdapter.cjs");
|
||
|
||
class LinuxServerAdapter extends BaseAdapter {
|
||
constructor(connectionInfo, options = {}) {
|
||
super(connectionInfo, options);
|
||
this.adapterName = "linux_server";
|
||
// 支持外部注入 exec 函数(用于复用 SSH 连接)
|
||
if (options.execFn) {
|
||
this.execute = options.execFn;
|
||
}
|
||
}
|
||
|
||
getSupportedMetrics() {
|
||
return [
|
||
"cpu_usage",
|
||
"memory_usage",
|
||
"disk_usage",
|
||
];
|
||
}
|
||
|
||
async collectMetrics() {
|
||
const metrics = {};
|
||
const raw = {};
|
||
|
||
// 1. CPU 使用率(采样 top)
|
||
try {
|
||
raw.cpu = await this.execute("top -bn1 2>/dev/null | head -n 5");
|
||
const cpuMatch = (raw.cpu || "").match(/Cpu\(s\):\s*([\d.]+)\s*us,\s*([\d.]+)\s*sy/i);
|
||
if (cpuMatch) {
|
||
metrics.cpu_usage = Math.round(parseFloat(cpuMatch[1]) + parseFloat(cpuMatch[2]));
|
||
}
|
||
} catch (e) {
|
||
throw e; // SSH 失败或其他错误必须向上传播
|
||
}
|
||
|
||
// 2. 内存使用率
|
||
try {
|
||
raw.mem = await this.execute("free -k 2>/dev/null | head -n 2 | tail -n 1");
|
||
// 支持中英文输出: "Mem:" 或 "内存:"
|
||
const memMatch = (raw.mem || "").match(/(?:Mem:|内存[::])\s+(\d+)\s+(\d+)/);
|
||
if (memMatch) {
|
||
const total = parseInt(memMatch[1], 10);
|
||
const used = parseInt(memMatch[2], 10);
|
||
if (total > 0) {
|
||
metrics.memory_usage = Math.min(100, Math.round((used / total) * 100));
|
||
}
|
||
}
|
||
} catch (e) {
|
||
throw e;
|
||
}
|
||
|
||
// 3. 磁盘使用率(显示所有挂载点)
|
||
try {
|
||
raw.disk = await this.execute("df -h 2>/dev/null | tail -n +2 | grep -v '/dev/loop'");
|
||
const disks = this.parseDiskUsage(raw.disk);
|
||
if (disks.length > 0) metrics.disk_usage = disks;
|
||
} catch (e) {
|
||
throw e;
|
||
}
|
||
|
||
return metrics;
|
||
}
|
||
|
||
/**
|
||
* 解析磁盘使用率(df -h 输出格式),返回所有挂载点
|
||
*/
|
||
parseDiskUsage(text) {
|
||
const disks = [];
|
||
const lines = (text || "").split("\n");
|
||
for (const line of lines) {
|
||
const parts = line.trim().split(/\s+/);
|
||
if (parts.length < 6) continue;
|
||
const usageStr = parts[4] || "";
|
||
const usageMatch = usageStr.match(/^(\d+)%/);
|
||
if (!usageMatch) continue;
|
||
const usagePercent = parseInt(usageMatch[1], 10);
|
||
disks.push({
|
||
filesystem: parts[0],
|
||
usage_percent: usagePercent,
|
||
mount: parts[parts.length - 1],
|
||
});
|
||
}
|
||
return disks;
|
||
}
|
||
}
|
||
|
||
module.exports = LinuxServerAdapter;
|