增加主机信息功能

This commit is contained in:
2026-04-18 11:07:46 +08:00
parent 1821d266af
commit 9e1bb5cd70
3 changed files with 0 additions and 199 deletions

View File

@@ -32,9 +32,4 @@ public class SftpResult implements Serializable {
public boolean isSuccess() { return success; }
public String getMessage() { return message; }
public Object getData() { return data; }
@Override
public String toString() {
return "SftpResult{success=" + success + ", message='" + message + "'}";
}
}

View File

@@ -204,17 +204,4 @@ public class MonitorUtil {
}
return out.toString(StandardCharsets.UTF_8);
}
public static void main(String[] args) {
MySftpAccounts sftpAccounts = new MySftpAccounts();
sftpAccounts.setHostIp("192.168.31.194");
sftpAccounts.setHostPort(22);
sftpAccounts.setUsername("ogsapp");
sftpAccounts.setPassword("Sys@2026#me");
sftpAccounts.setRootPath("/ogsapp");
sftpAccounts.setAuthType("password");
SftpResult sftpResult = MonitorUtil.monitor(sftpAccounts);
System.out.println(sftpResult.getData());
}
}

View File

@@ -299,187 +299,6 @@ public class SftpUtil {
}
}
// ------------------------------------------------------------------ 系统监控
/**
* 获取远程主机系统信息CPU、内存、磁盘、负载、在线时长
* 通过 SSH exec 执行系统命令采集
*
* @param account SSH账号
* @return SftpResultdata 为 Map 结构
*/
public static SftpResult systemInfo(MySftpAccounts account) {
Session session = null;
ChannelExec exec = null;
try {
session = openSession(account);
exec = (ChannelExec) session.openChannel("exec");
// 一次性采集所有指标
exec.setCommand(
"echo '===HOSTNAME===' && hostname && " +
"echo '===UPTIME===' && uptime -p 2>/dev/null || uptime && " +
"echo '===CPU===' && top -bn1 | head -5 && " +
"echo '===MEM===' && free -m && " +
"echo '===DISK===' && df -h"
);
InputStream in = exec.getInputStream();
InputStream errIn = exec.getErrStream();
exec.connect(SSH_TIMEOUT);
String output = readStream(in);
String err = readStream(errIn);
if (!err.isEmpty() && output.isEmpty()) {
return SftpResult.fail("采集失败: " + err);
}
Map<String, Object> info = new LinkedHashMap<>();
info.put("hostname", extract(output, "HOSTNAME", true));
info.put("uptime", extract(output, "UPTIME", true));
info.put("cpu", parseCpu(extract(output, "CPU", false)));
info.put("memory", parseMemory(extract(output, "MEM", false)));
info.put("disk", parseDisk(extract(output, "DISK", false)));
return SftpResult.ok("采集成功", info);
} catch (Exception e) {
return SftpResult.fail("采集失败: " + e.getMessage());
} finally {
if (exec != null && exec.isConnected()) exec.disconnect();
if (session != null && session.isConnected()) session.disconnect();
}
}
// ---- session 工具 ----
private static Session openSession(MySftpAccounts account) throws JSchException {
JSch jsch = new JSch();
int port = Optional.ofNullable(account.getHostPort()).orElse(22);
if ("key".equalsIgnoreCase(account.getAuthType())
&& StringUtils.isNotBlank(account.getPrivateKey())) {
jsch.addIdentity("tempKey",
account.getPrivateKey().getBytes(StandardCharsets.UTF_8),
null, null);
}
Session session = jsch.getSession(account.getUsername(), account.getHostIp(), port);
session.setTimeout(SSH_TIMEOUT);
if (!"key".equalsIgnoreCase(account.getAuthType())) {
session.setPassword(account.getPassword());
}
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect(SSH_TIMEOUT);
return session;
}
private static String readStream(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
return out.toString(StandardCharsets.UTF_8);
}
// ---- 解析工具 ----
/**
* 按 ===MARK=== 分割提取段落
*/
private static String extract(String output, String mark, boolean singleLine) {
String start = "===" + mark + "===";
int s = output.indexOf(start);
if (s < 0) return "";
s += start.length();
if (s >= output.length()) return "";
// 跳过紧跟的换行
if (output.charAt(s) == '\n') s++;
if (singleLine) {
int e = output.indexOf('\n', s);
return (e < 0 ? output.substring(s) : output.substring(s, e)).trim();
}
// 取到下一个 === 或末尾
int e = output.indexOf("\n===", s);
return (e < 0 ? output.substring(s) : output.substring(s, e)).trim();
}
/**
* 解析 CPU 段top -bn1 输出头部)
* 格式Cpu(s): 1.2 us, 0.3 sy, 0.0 ni, 98.3 id, 0.1 wa, 0.1 si
*/
private static Map<String, String> parseCpu(String block) {
Map<String, String> cpu = new LinkedHashMap<>();
for (String line : block.split("\n")) {
if (line.startsWith("Cpu") || line.startsWith("%Cpu")) {
// 统一去掉 %Cpu(s): 前缀
String data = line.replaceFirst(".*?:\\s*", "").replaceFirst("^%Cpu\\(s?\\):\\s*", "");
for (String part : data.split(",")) {
part = part.trim();
String[] kv = part.split("\\s+", 2);
if (kv.length >= 2) {
cpu.put(kv[1].trim(), kv[0].trim());
}
}
break;
}
}
return cpu;
}
/**
* 解析内存段free -m 输出)
* Mem: total used free shared buff/cache available
*/
private static Map<String, String> parseMemory(String block) {
Map<String, String> mem = new LinkedHashMap<>();
for (String line : block.split("\n")) {
if (line.startsWith("Mem:")) {
String[] cols = line.trim().split("\\s+");
if (cols.length >= 7) {
mem.put("total", cols[1] + " MB");
mem.put("used", cols[2] + " MB");
mem.put("free", cols[3] + " MB");
mem.put("available", cols[6] + " MB");
// 使用率
try {
double total = Double.parseDouble(cols[1]);
double used = Double.parseDouble(cols[2]);
double pct = total > 0 ? used / total * 100 : 0;
mem.put("usagePercent", String.format("%.1f%%", pct));
} catch (NumberFormatException ignored) {
}
}
break;
}
}
return mem;
}
/**
* 解析磁盘段df -h 输出)
* Filesystem Size Used Avail Use% Mounted on
*/
private static List<Map<String, String>> parseDisk(String block) {
List<Map<String, String>> disks = new ArrayList<>();
String[] lines = block.split("\n");
for (int i = 0; i < lines.length; i++) {
String line = lines[i].trim();
if (i == 0 && (line.startsWith("Filesystem") || line.startsWith("文件系统"))) continue;
if (line.isEmpty()) continue;
String[] cols = line.split("\\s+");
if (cols.length >= 6) {
Map<String, String> d = new LinkedHashMap<>();
d.put("filesystem", cols[0]);
d.put("size", cols[1]);
d.put("used", cols[2]);
d.put("avail", cols[3]);
d.put("usePercent", cols[4]);
d.put("mounted", cols[5]);
disks.add(d);
}
}
return disks;
}
// ------------------------------------------------------------------ 重命名/移动
/**