Files
NetMesh/electron/bridges/inspection/promptParser.cjs
zhaolei c64e00d835 feat: 新增设备巡检模块实现完整的巡检告警功能
新增设备巡检模块核心功能,包括:
- 巡检数据存储与调度系统
- 华为/H3C交换机及Linux服务器采集器
- 设备扩展配置与告警规则管理
- 主机详情页巡检配置入口
- 产品名称自定义设置功能
- 网络设备SSH exec通道兼容处理
2026-10-09 10:37:48 +08:00

174 lines
4.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use strict";
/**
* Prompt 解析器 - 从命令输出中提取指标
*
* 分层策略:
* 1. 正则匹配(快,简单场景够用)
* 2. 返回原始输出(解析失败时让用户看原始数据)
*/
/**
* 华为/H3C 交换机命令解析配置
*/
const HUAWEI_H3C_PATTERNS = {
cpu_usage: {
// CPU 使用率:多种可能的格式
patterns: [
/CPU\s+Usage\s*:\s*(\d+)%/i,
/CPU\s+utilization.*one\s+minute:\s*(\d+)%/i,
/CPU\s+Usage\s+:\s*(\d+)%/i,
],
default: null,
},
memory_usage: {
// 内存使用率:多种格式
patterns: [
/Memory\s+Using\s+Percentage\s+Is:\s*(\d+)%/i,
/Memory\s+utilization.*:\s*(\d+)%/i,
],
default: null,
},
};
/**
* 解析单行指标
* @param {string} output - 命令原始输出
* @param {object} config - { patterns: RegExp[], default: any }
* @returns {any} 解析结果
*/
function parseMetric(output, config) {
if (!output || !config?.patterns) return config?.default ?? null;
for (const pattern of config.patterns) {
const match = output.match(pattern);
if (match) {
return parseFloat(match[1]);
}
}
return config.default ?? null;
}
/**
* 解析端口状态
* @param {string} output - 命令输出
* @returns {object} { up_count, down_count, ports }
*/
function parseInterfaceBrief(output) {
const lines = output.split("\n");
const ports = [];
let upCount = 0;
let downCount = 0;
for (const line of lines) {
// 匹配端口行:GigabitEthernet0/0/1 up up
const portMatch = line.match(/^(GigabitEthernet|FastEthernet|Ethernet)(\S+)\s+(\w+)\s+(\w+)/);
if (portMatch) {
const phy = portMatch[3].toLowerCase();
const proto = portMatch[4].toLowerCase();
ports.push({
name: portMatch[1] + portMatch[2],
phy,
protocol: proto,
is_up: phy === "up" && proto === "up",
});
if (phy === "up") upCount++;
else downCount++;
}
}
return { up_count: upCount, down_count: downCount, ports };
}
/**
* 解析电源状态
* @param {string} output - 命令输出
* @returns {object} { normal_count, abnormal_count }
*/
function parsePowerStatus(output) {
const lines = output.split("\n");
let normalCount = 0;
let abnormalCount = 0;
for (const line of lines) {
// 匹配电源状态行
if (/Normal|Supply|OK/i.test(line)) {
normalCount++;
} else if (/Absent|Fault|Error/i.test(line)) {
abnormalCount++;
}
}
return { normal_count: normalCount, abnormal_count: abnormalCount };
}
/**
* 清理交换机输出
* @param {string} output - 原始输出
* @returns {string} 清理后的输出
*/
function cleanOutput(output) {
return output
// 移除提示符
.replace(/<\w+[-A-Za-z0-9]*>/g, "")
// 移除分页标记
.replace(/---- More ----/g, "")
// 移除命令回显
.replace(/^[^\r\n]*\r?\n/, "")
// 移除空行
.replace(/\n{3,}/g, "\n\n")
.trim();
}
/**
* 使用 prompt 风格解析交换机输出
* @param {string} output - 原始命令输出
* @param {object} context - { catalog_id, device_info }
* @returns {object} 结构化指标
*/
function parseSwitchOutput(output, context = {}) {
const cleaned = cleanOutput(output);
const lines = cleaned.split("\n");
const metrics = {
cpu_usage: null,
memory_usage: null,
port_status: [],
power_status: [],
fan_status: [],
};
// 解析 CPU
metrics.cpu_usage = parseMetric(cleaned, HUAWEI_H3C_PATTERNS.cpu_usage);
// 解析内存
metrics.memory_usage = parseMetric(cleaned, HUAWEI_H3C_PATTERNS.memory_usage);
// 解析端口
metrics.port_status = parseInterfaceBrief(cleaned);
// 解析电源
metrics.power_status = parsePowerStatus(cleaned);
// 原始输出(便于调试)
metrics._raw_output = cleaned;
metrics._parse_errors = [];
if (metrics.cpu_usage === null) {
metrics._parse_errors.push("cpu_usage: 无法解析");
}
if (metrics.memory_usage === null) {
metrics._parse_errors.push("memory_usage: 无法解析");
}
return metrics;
}
module.exports = {
parseMetric,
parseInterfaceBrief,
parsePowerStatus,
cleanOutput,
parseSwitchOutput,
};