|
|
@@ -1,11 +1,16 @@
|
|
|
package org.ruoyi.chat.service;
|
|
|
|
|
|
+import com.fasterxml.jackson.annotation.JsonProperty;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import lombok.Data;
|
|
|
+import org.ruoyi.chat.util.HttpUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import oshi.SystemInfo;
|
|
|
import oshi.hardware.CentralProcessor;
|
|
|
import oshi.hardware.GlobalMemory;
|
|
|
import oshi.hardware.HardwareAbstractionLayer;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
|
|
|
import java.util.List;
|
|
|
import java.util.stream.Collectors;
|
|
|
@@ -15,20 +20,26 @@ public class HardwareInfoService {
|
|
|
|
|
|
private final SystemInfo systemInfo = new SystemInfo();
|
|
|
private final HardwareAbstractionLayer hal = systemInfo.getHardware();
|
|
|
+ private final ObjectMapper objectMapper = new ObjectMapper();
|
|
|
private long[] prevTicks = null;
|
|
|
+ @Value("${enflame.url}")
|
|
|
+ private String enflameApiUrl;
|
|
|
|
|
|
+ /**
|
|
|
+ * 获取本机硬件 + 集群 Supervisor 节点信息
|
|
|
+ */
|
|
|
public HardwareData getHardwareData() {
|
|
|
CentralProcessor processor = hal.getProcessor();
|
|
|
GlobalMemory memory = hal.getMemory();
|
|
|
|
|
|
- // CPU 使用率(准确版)
|
|
|
- double cpuLoad = getCpuLoad(processor);
|
|
|
+ // 1. 本机 CPU 使用率
|
|
|
+ double cpuUsage = getCpuLoad(processor);
|
|
|
|
|
|
- // 内存信息
|
|
|
+ // 2. 本机内存
|
|
|
long totalMemory = memory.getTotal();
|
|
|
long availableMemory = memory.getAvailable();
|
|
|
|
|
|
- // 磁盘信息
|
|
|
+ // 3. 磁盘信息
|
|
|
List<DiskData> disks = systemInfo.getOperatingSystem().getFileSystem().getFileStores().stream()
|
|
|
.map(store -> new DiskData(
|
|
|
store.getMount(),
|
|
|
@@ -36,47 +47,87 @@ public class HardwareInfoService {
|
|
|
store.getUsableSpace()))
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
- // 网络信息
|
|
|
+ // 4. 网络信息
|
|
|
List<NetworkData> networks = hal.getNetworkIFs().stream()
|
|
|
+ .filter(net -> net.getBytesRecv() > 0 || net.getBytesSent() > 0) // 可选:过滤无流量的网卡
|
|
|
.map(net -> new NetworkData(
|
|
|
net.getName(),
|
|
|
net.getBytesRecv(),
|
|
|
net.getBytesSent()))
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
- return new HardwareData(cpuLoad, totalMemory, availableMemory, disks, networks);
|
|
|
+ // 5. 获取集群中 Supervisor 节点信息
|
|
|
+ ClusterNodeInfo clusterNodeInfo = getSupervisorNodeInfo();
|
|
|
+
|
|
|
+ // 6. 返回合并数据
|
|
|
+ return new HardwareData(cpuUsage, totalMemory, availableMemory, disks, networks, clusterNodeInfo);
|
|
|
}
|
|
|
|
|
|
- public double getCpuLoad(CentralProcessor processor) {
|
|
|
+ /**
|
|
|
+ * 计算 CPU 使用率(两次采样之间)
|
|
|
+ */
|
|
|
+ private double getCpuLoad(CentralProcessor processor) {
|
|
|
if (prevTicks == null) {
|
|
|
prevTicks = processor.getSystemCpuLoadTicks();
|
|
|
- return 0; // 第一次调用无法计算,返回0或其他默认值
|
|
|
+ return 0.0;
|
|
|
}
|
|
|
long[] ticks = processor.getSystemCpuLoadTicks();
|
|
|
double load = processor.getSystemCpuLoadBetweenTicks(prevTicks);
|
|
|
prevTicks = ticks;
|
|
|
- return load * 100;
|
|
|
+ return Math.round(load * 10000) / 100.0; // 保留两位小数
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从燧原集群 API 获取 Supervisor 节点信息
|
|
|
+ */
|
|
|
+ private ClusterNodeInfo getSupervisorNodeInfo() {
|
|
|
+ String url = enflameApiUrl + "/v1/cluster/info?detailed=true";
|
|
|
+ try {
|
|
|
+ String jsonResponse = HttpUtils.sendHttpGet(url);
|
|
|
+ if (jsonResponse == null || jsonResponse.trim().isEmpty()) {
|
|
|
+ System.err.println("API 返回为空或连接失败: " + url);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析为 ClusterNodeInfo 列表
|
|
|
+ List<ClusterNodeInfo> nodes = objectMapper.readValue(jsonResponse, new TypeReference<List<ClusterNodeInfo>>() {});
|
|
|
+
|
|
|
+ // 查找 node_type 为 "Supervisor" 的节点
|
|
|
+ return nodes.stream()
|
|
|
+ .filter(node -> "Worker".equals(node.getNodeType()))
|
|
|
+ .findFirst()
|
|
|
+ .orElse(null);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.err.println("请求或解析集群信息失败: " + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ return null; // 前端可据此显示“集群离线”或“加载中”
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- // DTO 类
|
|
|
+ // ==================== DTO 数据传输对象 ====================
|
|
|
+
|
|
|
@Data
|
|
|
public static class HardwareData {
|
|
|
- private double cpuUsage; // %
|
|
|
- private long totalMemory; // bytes
|
|
|
- private long availableMemory; // bytes
|
|
|
+ private double cpuUsage; // 本机 CPU 使用率 (%)
|
|
|
+ private long totalMemory; // 本机总内存 (bytes)
|
|
|
+ private long availableMemory; // 本机可用内存 (bytes)
|
|
|
private List<DiskData> disks;
|
|
|
private List<NetworkData> networks;
|
|
|
+ private ClusterNodeInfo clusterNodeInfo; // 集群 Supervisor 节点信息
|
|
|
|
|
|
-
|
|
|
- public HardwareData(double cpuUsage, long totalMemory, long availableMemory, List<DiskData> disks, List<NetworkData> networks) {
|
|
|
+ public HardwareData(double cpuUsage, long totalMemory, long availableMemory,
|
|
|
+ List<DiskData> disks, List<NetworkData> networks,
|
|
|
+ ClusterNodeInfo clusterNodeInfo) {
|
|
|
this.cpuUsage = cpuUsage;
|
|
|
this.totalMemory = totalMemory;
|
|
|
this.availableMemory = availableMemory;
|
|
|
this.disks = disks;
|
|
|
this.networks = networks;
|
|
|
+ this.clusterNodeInfo = clusterNodeInfo;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
+
|
|
|
@Data
|
|
|
public static class DiskData {
|
|
|
private String mountPoint;
|
|
|
@@ -88,8 +139,8 @@ public class HardwareInfoService {
|
|
|
this.totalSpace = totalSpace;
|
|
|
this.usableSpace = usableSpace;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
+
|
|
|
@Data
|
|
|
public static class NetworkData {
|
|
|
private String name;
|
|
|
@@ -101,6 +152,38 @@ public class HardwareInfoService {
|
|
|
this.bytesReceived = bytesReceived;
|
|
|
this.bytesSent = bytesSent;
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ @Data
|
|
|
+ public static class ClusterNodeInfo {
|
|
|
+ @JsonProperty("node_type")
|
|
|
+ private String nodeType;
|
|
|
+
|
|
|
+ @JsonProperty("ip_address")
|
|
|
+ private String ipAddress;
|
|
|
+
|
|
|
+ @JsonProperty("gpu_count")
|
|
|
+ private Integer gpuCount;
|
|
|
+
|
|
|
+ @JsonProperty("gpu_vram_total")
|
|
|
+ private Long gpuVramTotal;
|
|
|
+
|
|
|
+ @JsonProperty("gpu_vram_available")
|
|
|
+ private Long gpuVramAvailable;
|
|
|
+
|
|
|
+ @JsonProperty("cpu_available")
|
|
|
+ private Double cpuAvailable;
|
|
|
+
|
|
|
+ @JsonProperty("cpu_count")
|
|
|
+ private Integer cpuCount;
|
|
|
+
|
|
|
+ @JsonProperty("mem_used")
|
|
|
+ private Long memUsed;
|
|
|
+
|
|
|
+ @JsonProperty("mem_available")
|
|
|
+ private Long memAvailable;
|
|
|
|
|
|
+ @JsonProperty("mem_total")
|
|
|
+ private Long memTotal;
|
|
|
}
|
|
|
}
|