项目初始化
This commit is contained in:
183
src/main/java/com/mini/capi/utils/HostRuntime.java
Normal file
183
src/main/java/com/mini/capi/utils/HostRuntime.java
Normal file
@@ -0,0 +1,183 @@
|
||||
package com.mini.capi.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class HostRuntime {
|
||||
|
||||
|
||||
/**
|
||||
* 统一的数据载体
|
||||
*/
|
||||
|
||||
public static class Snapshot {
|
||||
public String hostName; // 主机名
|
||||
public long timestamp; // 采集时间戳(毫秒)
|
||||
public double cpuUsage; // CPU 使用率 0~1
|
||||
public long memTotal; // 内存总量(Byte)
|
||||
public long memFree; // 空闲内存(Byte)
|
||||
public long memUsed; // 已用内存(Byte)
|
||||
public double memUsage; // 内存使用率 0~1
|
||||
public long swapTotal; // Swap 总量
|
||||
public long swapUsed; // Swap 已用
|
||||
public List<DiskUsage> disks; // 各挂载点磁盘
|
||||
public long netRxBytes; // 累计接收字节
|
||||
public long netTxBytes; // 累计发送字节
|
||||
public double load1; // 1 分钟平均负载
|
||||
public int processCount; // 进程数
|
||||
public long uptimeSec; // 开机时间(秒)
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Snapshot{" +
|
||||
"hostName='" + hostName + '\'' +
|
||||
", ts=" + Instant.ofEpochMilli(timestamp) +
|
||||
", cpu=" + String.format("%.2f", cpuUsage * 100) + "%" +
|
||||
", mem=" + String.format("%.2f", memUsage * 100) + "%" +
|
||||
", load=" + load1 +
|
||||
", uptime=" + uptimeSec + "s}";
|
||||
}
|
||||
}
|
||||
|
||||
public static class DiskUsage {
|
||||
public String path;
|
||||
public long total;
|
||||
public long free;
|
||||
public long used;
|
||||
public double usage;
|
||||
|
||||
public DiskUsage(String path, long total, long free, long used, double usage) {
|
||||
this.path = path;
|
||||
this.total = total;
|
||||
this.free = free;
|
||||
this.used = used;
|
||||
this.usage = usage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 采集一次主机状态
|
||||
*/
|
||||
public static Snapshot collect() {
|
||||
Snapshot s = new Snapshot();
|
||||
s.timestamp = System.currentTimeMillis();
|
||||
try {
|
||||
s.hostName = InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
s.hostName = "unknown";
|
||||
}
|
||||
|
||||
OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
|
||||
s.load1 = os.getSystemLoadAverage();
|
||||
s.uptimeSec = getUptimeSec();
|
||||
s.processCount = getProcessCount();
|
||||
|
||||
/* ------ CPU ------ */
|
||||
s.cpuUsage = getCpuUsage();
|
||||
|
||||
/* ------ Memory ------ */
|
||||
long[] mem = getMemInfo();
|
||||
s.memTotal = mem[0];
|
||||
s.memFree = mem[1];
|
||||
s.memUsed = s.memTotal - s.memFree;
|
||||
s.memUsage = s.memTotal == 0 ? 0 : (double) s.memUsed / s.memTotal;
|
||||
s.swapTotal = mem[2];
|
||||
s.swapUsed = mem[3];
|
||||
|
||||
/* ------ Disk ------ */
|
||||
s.disks = new ArrayList<>();
|
||||
java.io.File[] roots = java.io.File.listRoots();
|
||||
for (java.io.File f : roots) {
|
||||
long total = f.getTotalSpace();
|
||||
long free = f.getFreeSpace();
|
||||
long used = total - free;
|
||||
double usage = total == 0 ? 0 : (double) used / total;
|
||||
s.disks.add(new DiskUsage(f.getPath(), total, free, used, usage));
|
||||
}
|
||||
|
||||
/* ------ Network ------ */
|
||||
long[] net = getNetInfo();
|
||||
s.netRxBytes = net[0];
|
||||
s.netTxBytes = net[1];
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* ----------------- 私有工具方法 ----------------- */
|
||||
|
||||
private static double getCpuUsage() {
|
||||
// 利用 com.sun.management.OperatingSystemMXBean(JDK 自带)
|
||||
com.sun.management.OperatingSystemMXBean sunOs =
|
||||
(com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
|
||||
return sunOs.getProcessCpuLoad(); // 进程级
|
||||
// 若想系统级:sunOs.getSystemCpuLoad();
|
||||
}
|
||||
|
||||
private static long getUptimeSec() {
|
||||
// 通过 JVM 启动时间计算
|
||||
return ManagementFactory.getRuntimeMXBean().getUptime() / 1000;
|
||||
}
|
||||
|
||||
private static int getProcessCount() {
|
||||
// 简单实现:线程数,不够精确;若要精确需解析 /proc
|
||||
return ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors(); // 仅作示例
|
||||
}
|
||||
|
||||
private static long[] getMemInfo() {
|
||||
long total = 0, free = 0, swapTotal = 0, swapUsed = 0;
|
||||
try (BufferedReader br = new BufferedReader(new FileReader("/proc/meminfo"))) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
if (line.startsWith("MemTotal:")) total = parseMemLine(line);
|
||||
if (line.startsWith("MemAvailable:")) free = parseMemLine(line);
|
||||
if (line.startsWith("SwapTotal:")) swapTotal = parseMemLine(line);
|
||||
if (line.startsWith("SwapFree:")) swapUsed = swapTotal - parseMemLine(line);
|
||||
}
|
||||
} catch (IOException | NumberFormatException ignore) {
|
||||
// fallback to OperatingSystemMXBean
|
||||
OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
|
||||
if (os instanceof com.sun.management.OperatingSystemMXBean) {
|
||||
com.sun.management.OperatingSystemMXBean sunOs =
|
||||
(com.sun.management.OperatingSystemMXBean) os;
|
||||
total = sunOs.getTotalMemorySize();
|
||||
free = sunOs.getFreeMemorySize();
|
||||
}
|
||||
}
|
||||
return new long[]{total, free, swapTotal, swapUsed};
|
||||
}
|
||||
|
||||
private static long parseMemLine(String line) {
|
||||
String[] parts = line.split("\\s+");
|
||||
return Long.parseLong(parts[1]) * 1024; // kB -> Byte
|
||||
}
|
||||
|
||||
private static long[] getNetInfo() {
|
||||
// 读取 /proc/net/dev 第一行即可拿到累计字节
|
||||
long rx = 0, tx = 0;
|
||||
try (BufferedReader br = new BufferedReader(new FileReader("/proc/net/dev"))) {
|
||||
br.readLine();
|
||||
br.readLine(); // 跳过表头
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
line = line.trim();
|
||||
if (line.startsWith("lo:")) continue; // 忽略回环
|
||||
String[] parts = line.split("\\s+");
|
||||
if (parts.length >= 10) {
|
||||
rx += Long.parseLong(parts[1]);
|
||||
tx += Long.parseLong(parts[9]);
|
||||
}
|
||||
}
|
||||
} catch (IOException | NumberFormatException ignore) {
|
||||
// 非 Linux 平台直接返回 0
|
||||
}
|
||||
return new long[]{rx, tx};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user