package com.ediagnosis.cdr.dashBoard; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Map; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; public class HostMonitor { private static final Logger log = LoggerFactory.getLogger(HostMonitor.class); public static Optional> getHostIpAndName() { String hostname = ""; String ip = ""; Optional optionalHostname = executeCommand("hostname"); Optional optionalIp = executeCommand("hostname", "-I"); if (optionalHostname.isPresent()) { hostname = optionalHostname.get(); } if (optionalIp.isPresent()) { ip = optionalIp.get(); } Map host = Map.of("hostName", hostname, "ip", ip); log.info("主机信息: " + host); return Optional.of(host); } /** * 执行系统命令并返回第一行输出 */ private static Optional executeCommand(String... command) { ProcessBuilder pb = new ProcessBuilder(command); pb.redirectErrorStream(true); // 合并标准输出和错误输出 Optional optionalString = Optional.empty(); log.info("执行命令: " + String.join(" ", command)); Process process; try { process = pb.start(); } catch (IOException e) { // 可以记录日志 log.error("执行命令失败:" + String.join(" ", command), e); return optionalString; } // 使用 try-with-resources 自动关闭流 try (BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()))) { String line = reader.readLine(); // 通常只关心第一行 optionalString = Optional.of(line); } catch (IOException e) { // 可以记录日志 log.error("读取命令结果失败:" + String.join(" ", command), e); return optionalString; } return optionalString; } public static Optional> getCpuUsage() { Optional> optionalMap = Optional.empty(); ProcessBuilder pb = new ProcessBuilder("top", "-bn1"); log.info("执行命令:top -bn1"); Process process = null; try { process = pb.start(); } catch (IOException e) { log.error("执行命令时,启动进程失败: top -bn1", e); return optionalMap; } String cpuLine = ""; String loadLine = ""; try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { String line; while ((line = reader.readLine()) != null) { if (line.contains("load average:")) { loadLine = line; } else if (line.contains("Cpu(s)")) { cpuLine = line; } if (!cpuLine.isBlank() && !loadLine.isBlank()) { break; } } } catch (IOException e) { log.error("读取cpu信息时失败:top -bn1 ", e); return optionalMap; } // 去掉前缀 "%Cpu(s):",并提取数字 String[] parts = cpuLine .replace("%Cpu(s):", "") .trim() .split(","); // 存储各个字段的值 double id = 0; for (String part : parts) { part = part.trim(); if (part.endsWith("id")) { id = Double.parseDouble(part.replace("id", "").trim()); } } String cpuUsage = Math.round(100 - id) + "%"; String cpuCores = String.valueOf( Runtime.getRuntime().availableProcessors() ); String loadAverage = ""; // 正则匹配 "load average: 数值, 数值, 数值" Pattern pattern = Pattern.compile("load average: ([\\d.]+), ([\\d.]+), ([\\d.]+)"); Matcher matcher = pattern.matcher(loadLine); if (matcher.find()) { double fiveMin = Double.parseDouble(matcher.group(2)); loadAverage = String.valueOf(fiveMin); } // 方法一:100 - idle Map cpu = Map.of( "cpuUsage", cpuUsage, "cpuCores", cpuCores, "loadAverage", loadAverage ); log.info("cpu信息: " + cpu); return Optional.of(cpu); } public static Optional> getMemoryUsage() { Optional> optionalMap = Optional.empty(); ProcessBuilder pb = new ProcessBuilder("free", "-h"); log.info("执行命令:free -h"); Process process = null; try { process = pb.start(); } catch (IOException e) { log.error("执行命令时,启动进程失败: free -h"); return optionalMap; } String memLine = ""; try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { String line; while ((line = reader.readLine()) != null) { if (line.startsWith("Mem:")) { memLine = line; } } } catch (IOException e) { log.error("读取内存信息时失败:free -h "); } // 将多个空格替换为单个空格,便于分割 String[] parts = memLine.trim().replaceAll("\\s+", " ").split(" "); // 解析各字段(单位:KB、M、G) String totalStr = parts[1]; String availableStr = parts[6]; // 转换为统一单位(GB) double total = parseSizeToGB(totalStr); double available = parseSizeToGB(availableStr); // 计算内存使用率:(1 - available / total) * 100% double usagePercent = (1 - (available / total)) * 100; String memoryUsage = Math.round(usagePercent) + "%"; String used = (total - available) + "G"; String size = total + "G"; String free = available + "G"; Map memory = Map.of( "used", used, "size", size, "free", free, "memoryUsage", memoryUsage ); log.info("内存信息: " + memory); return Optional.of(memory); } private static double parseSizeToGB(String size) { double value; if (size.endsWith("G")) { value = Double.parseDouble(size.replace("G", "")); } else if (size.endsWith("M")) { value = Double.parseDouble(size.replace("M", "")) / 1024; } else if (size.endsWith("K")) { value = Double.parseDouble(size.replace("K", "")) / (1024 * 1024); } else { value = Double.parseDouble(size) / (1024 * 1024 * 1024); } return value; } public static Optional> getDiskUsage() { ProcessBuilder pb = new ProcessBuilder("df", "-h", "/"); Optional> optionalMap = Optional.empty(); log.info("执行命令:df -h /"); Process process = null; try { process = pb.start(); } catch (IOException e) { log.error("执行命令时,启动进程失败: df -h /", e); return optionalMap; } String body; try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { body = reader.readLine(); } catch (IOException e) { log.error("读取磁盘信息时失败:df -h /", e); return optionalMap; } String[] parts = body.trim().replaceAll("\\s+", " ").split(" "); // 确保是有效行(至少有6列) if (parts.length < 6 || parts[4].indexOf('%') == -1) { throw new IllegalArgumentException("无效的磁盘使用行"); } // 提取 Use% 字段(如 "69%") String usePercent = parts[4]; String size = parts[1]; String free = parts[3]; String used = parts[2]; // 转换为整数 Map disk = Map.of( "usePercent", usePercent, "size", size, "free", free, "used", used); log.info("磁盘信息: " + disk); return Optional.of(disk); } }