diff --git a/dependencies/pom.xml b/dependencies/pom.xml
index 76127f0..6ee4e52 100644
--- a/dependencies/pom.xml
+++ b/dependencies/pom.xml
@@ -62,6 +62,7 @@
2.7.0
3.0.6
4.1.113.Final
+ 6.6.5
2.17.0
1.27.1
@@ -492,6 +493,13 @@
${jsoup.version}
+
+
+ com.github.oshi
+ oshi-core
+ ${oshi-version}
+
+
org.pf4j
pf4j
diff --git a/framework/commons/pom.xml b/framework/commons/pom.xml
index 6bf3c23..61905b8 100644
--- a/framework/commons/pom.xml
+++ b/framework/commons/pom.xml
@@ -144,6 +144,11 @@
easy-trans-anno
+
+ com.github.oshi
+ oshi-core
+
+
org.springframework.boot
diff --git a/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Cpu.java b/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Cpu.java
new file mode 100644
index 0000000..fb660c7
--- /dev/null
+++ b/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Cpu.java
@@ -0,0 +1,44 @@
+package cd.casic.framework.commons.util.monitor;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ *
+ * @author mian-bin
+ * @Description Cpu
+ * @date 2025/1/10 15:29
+ */
+@Data
+@Accessors(chain = true)
+public class Cpu {
+ /**
+ * 核心数
+ */
+ private int cpuNum;
+
+ /**
+ * CPU总的使用率
+ */
+ private double total;
+
+ /**
+ * CPU系统使用率
+ */
+ private double sys;
+
+ /**
+ * CPU用户使用率
+ */
+ private double used;
+
+ /**
+ * CPU当前等待率
+ */
+ private double wait;
+
+ /**
+ * CPU当前空闲率
+ */
+ private double free;
+}
diff --git a/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Jvm.java b/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Jvm.java
new file mode 100644
index 0000000..98673dc
--- /dev/null
+++ b/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Jvm.java
@@ -0,0 +1,39 @@
+package cd.casic.framework.commons.util.monitor;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ *
+ * @author mian-bin
+ * @Description Jvm
+ * @date 2025/1/10 15:31
+ */
+@Data
+@Accessors(chain = true)
+public class Jvm {
+ /**
+ * 当前JVM占用的内存总数(M)
+ */
+ private double total;
+
+ /**
+ * JVM最大可用内存总数(M)
+ */
+ private double max;
+
+ /**
+ * JVM空闲内存(M)
+ */
+ private double free;
+
+ /**
+ * JDK版本
+ */
+ private String version;
+
+ /**
+ * JDK路径
+ */
+ private String home;
+}
diff --git a/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Mem.java b/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Mem.java
new file mode 100644
index 0000000..1417bf4
--- /dev/null
+++ b/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Mem.java
@@ -0,0 +1,46 @@
+package cd.casic.framework.commons.util.monitor;
+
+import cd.casic.framework.commons.util.number.ArithUtil;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+
+/**
+ *
+ * @author mian-bin
+ * @Description Mem
+ * @date 2025/1/10 15:31
+ */
+@Setter
+@Accessors(chain = true)
+public class Mem {
+ /**
+ * 内存总量
+ */
+ private double total;
+
+ /**
+ * 已用内存
+ */
+ private double used;
+
+ /**
+ * 剩余内存
+ */
+ private double free;
+
+ public double getTotal() {
+ return ArithUtil.div(total, (1024 * 1024 * 1024), 2);
+ }
+
+ public double getUsed() {
+ return ArithUtil.div(used, (1024 * 1024 * 1024), 2);
+ }
+
+ public double getFree() {
+ return ArithUtil.div(free, (1024 * 1024 * 1024), 2);
+ }
+
+ public double getUsage() {
+ return ArithUtil.mul(ArithUtil.div(used, total, 4), 100);
+ }
+}
diff --git a/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Server.java b/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Server.java
new file mode 100644
index 0000000..a701bc2
--- /dev/null
+++ b/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Server.java
@@ -0,0 +1,167 @@
+package cd.casic.framework.commons.util.monitor;
+
+import cd.casic.framework.commons.util.network.IpUtil;
+import cd.casic.framework.commons.util.number.ArithUtil;
+import lombok.Data;
+import oshi.SystemInfo;
+import oshi.hardware.CentralProcessor;
+import oshi.hardware.GlobalMemory;
+import oshi.hardware.HardwareAbstractionLayer;
+import oshi.software.os.FileSystem;
+import oshi.software.os.OSFileStore;
+import oshi.software.os.OperatingSystem;
+import oshi.util.Util;
+
+import java.net.UnknownHostException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ *
+ * @author mian-bin
+ * @Description Server
+ * @date 2025/1/10 15:34
+ */
+@Data
+public class Server {
+ private static final int OSHI_WAIT_SECOND = 1000;
+
+ /**
+ * CPU相关信息
+ */
+ private Cpu cpu = new Cpu();
+
+ /**
+ * 內存相关信息
+ */
+ private Mem mem = new Mem();
+
+ /**
+ * JVM相关信息
+ */
+ private Jvm jvm = new Jvm();
+
+ /**
+ * 服务器相关信息
+ */
+ private Sys sys = new Sys();
+
+ /**
+ * 磁盘相关信息
+ */
+ private List sysFiles = new LinkedList();
+
+ public void copyTo() throws Exception {
+ SystemInfo si = new SystemInfo();
+ HardwareAbstractionLayer hal = si.getHardware();
+ setCpuInfo(hal.getProcessor());
+ setMemInfo(hal.getMemory());
+ setSysInfo();
+ setJvmInfo();
+ setSysFiles(si.getOperatingSystem());
+ }
+
+ /**
+ * 设置CPU信息
+ */
+ private void setCpuInfo(CentralProcessor processor) {
+ // CPU信息
+ long[] prevTicks = processor.getSystemCpuLoadTicks();
+ Util.sleep(OSHI_WAIT_SECOND);
+ long[] ticks = processor.getSystemCpuLoadTicks();
+ long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
+ long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
+ long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
+ long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
+ long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
+ long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
+ long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
+ long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
+ long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
+ cpu.setCpuNum(processor.getLogicalProcessorCount()).
+ setTotal(totalCpu).
+ setSys(cSys).
+ setUsed(user).
+ setWait(iowait).
+ setFree(idle);
+ }
+
+ /**
+ * 设置内存信息
+ */
+ private void setMemInfo(GlobalMemory memory) {
+ mem.setTotal(memory.getTotal());
+ mem.setUsed(memory.getTotal() - memory.getAvailable());
+ mem.setFree(memory.getAvailable());
+ }
+
+ /**
+ * 设置服务器信息
+ */
+ private void setSysInfo() {
+ Properties props = System.getProperties();
+ sys.setComputerName(IpUtil.getHostName()).
+ setComputerIp(IpUtil.getHostIp()).
+ setOsName(props.getProperty("os.name")).
+ setUserDir(props.getProperty("user.dir"));
+ }
+
+ /**
+ * 设置Java虚拟机
+ */
+ private void setJvmInfo() throws UnknownHostException {
+ Properties props = System.getProperties();
+ jvm.setTotal(Runtime.getRuntime().
+ totalMemory()).
+ setMax(Runtime.getRuntime().maxMemory()).
+ setFree(Runtime.getRuntime().freeMemory()).
+ setVersion(props.getProperty("java.version")).
+ setHome(props.getProperty("java.home"));
+ }
+
+ /**
+ * 设置磁盘信息
+ */
+ private void setSysFiles(OperatingSystem os) {
+ FileSystem fileSystem = os.getFileSystem();
+ List fsArray = fileSystem.getFileStores();
+ for (OSFileStore fs : fsArray) {
+ long free = fs.getUsableSpace();
+ long total = fs.getTotalSpace();
+ long used = total - free;
+ SysFile sysFile = new SysFile()
+ .setDirName(fs.getMount())
+ .setSysTypeName(fs.getType())
+ .setTypeName(fs.getName())
+ .setTotal(convertFileSize(total))
+ .setFree(convertFileSize(free))
+ .setUsed(convertFileSize(used))
+ .setUsage(ArithUtil.mul(ArithUtil.div(used, total, 4), 100));
+ sysFiles.add(sysFile);
+ }
+ }
+
+ /**
+ * 字节转换
+ *
+ * @param size 字节大小
+ * @return 转换后值
+ */
+ public String convertFileSize(long size) {
+ long kb = 1024;
+ long mb = kb * 1024;
+ long gb = mb * 1024;
+ if (size >= gb) {
+ return String.format("%.1f GB", (float) size / gb);
+ } else if (size >= mb) {
+ float f = (float) size / mb;
+ return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
+ } else if (size >= kb) {
+ float f = (float) size / kb;
+ return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
+ } else {
+ return String.format("%d B", size);
+ }
+ }
+}
diff --git a/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Sys.java b/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Sys.java
new file mode 100644
index 0000000..ad1a86c
--- /dev/null
+++ b/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/Sys.java
@@ -0,0 +1,36 @@
+package cd.casic.framework.commons.util.monitor;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * 系统相关
+ *
+ * @author mian-bin
+ * @Description Sys
+ * @date 2025/1/10 15:35
+ */
+@Data
+@Accessors(chain = true)
+public class Sys {
+ /**
+ * 服务器名称
+ */
+ private String computerName;
+
+ /**
+ * 服务器Ip
+ */
+ private String computerIp;
+
+ /**
+ * 项目路径
+ */
+ private String userDir;
+
+ /**
+ * 操作系统
+ */
+ private String osName;
+
+}
diff --git a/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/SysFile.java b/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/SysFile.java
new file mode 100644
index 0000000..995ff1c
--- /dev/null
+++ b/framework/commons/src/main/java/cd/casic/framework/commons/util/monitor/SysFile.java
@@ -0,0 +1,49 @@
+package cd.casic.framework.commons.util.monitor;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ *
+ * @author mian-bin
+ * @Description SysFile
+ * @date 2025/1/10 15:36
+ */
+@Data
+@Accessors(chain = true)
+public class SysFile {
+ /**
+ * 盘符路径
+ */
+ private String dirName;
+
+ /**
+ * 盘符类型
+ */
+ private String sysTypeName;
+
+ /**
+ * 文件类型
+ */
+ private String typeName;
+
+ /**
+ * 总大小
+ */
+ private String total;
+
+ /**
+ * 剩余大小
+ */
+ private String free;
+
+ /**
+ * 已经使用量
+ */
+ private String used;
+
+ /**
+ * 资源的使用率
+ */
+ private double usage;
+}
diff --git a/framework/commons/src/main/java/cd/casic/framework/commons/util/network/IpUtil.java b/framework/commons/src/main/java/cd/casic/framework/commons/util/network/IpUtil.java
new file mode 100644
index 0000000..3567d4a
--- /dev/null
+++ b/framework/commons/src/main/java/cd/casic/framework/commons/util/network/IpUtil.java
@@ -0,0 +1,101 @@
+package cd.casic.framework.commons.util.network;
+
+import jakarta.servlet.http.HttpServletRequest;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Ip工具类
+ *
+ * @author mian-bin
+ * @Description Ip工具类
+ * @date 2025/1/10 15:29
+ */
+
+public class IpUtil {
+
+ /**
+ * 获取Ip
+ *
+ * @param request request
+ * @return String
+ */
+ public static String getIpAddr(HttpServletRequest request) {
+ String ipAddress = null;
+ try {
+ ipAddress = request.getHeader("x-forwarded-for");
+ if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+ ipAddress = request.getHeader("Proxy-Client-IP");
+ }
+ if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+ ipAddress = request.getHeader("WL-Proxy-Client-IP");
+ }
+ if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+ ipAddress = request.getRemoteAddr();
+ if ("127.0.0.1".equals(ipAddress)) {
+ // 根据网卡取本机配置的IP
+ InetAddress inet = null;
+ try {
+ inet = InetAddress.getLocalHost();
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
+ }
+ ipAddress = inet.getHostAddress();
+ }
+ }
+ if (ipAddress != null && ipAddress.length() > 15) {
+ // = 15
+ if (ipAddress.indexOf(",") > 0) {
+ ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
+ }
+ }
+ } catch (Exception e) {
+ ipAddress = "";
+ }
+ return ipAddress;
+ }
+
+
+ /**
+ * 获取当前服务的ip和端口
+ */
+ public static String getUrl(int serverPort) {
+ InetAddress address = null;
+ try {
+ address = InetAddress.getLocalHost();
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
+ }
+ return "http://" + address.getHostAddress() + ":" + serverPort;
+ }
+
+ public static String getHostIp() {
+ try {
+ return InetAddress.getLocalHost().getHostAddress();
+ } catch (UnknownHostException e) {
+ }
+ return "127.0.0.1";
+ }
+
+ public static String getHostName() {
+ try {
+ return InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException e) {
+ }
+ return "未知";
+ }
+
+ /**
+ * 基路径
+ *
+ * @param request
+ * @return
+ */
+ public static String basePath(HttpServletRequest request) {
+ String bathPath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
+ // log.info("当前域名:[{}]", bathPath);
+ return bathPath;
+ // return "http://wuwenbin.me/";
+ }
+}
diff --git a/framework/commons/src/main/java/cd/casic/framework/commons/util/number/ArithUtil.java b/framework/commons/src/main/java/cd/casic/framework/commons/util/number/ArithUtil.java
new file mode 100644
index 0000000..77231de
--- /dev/null
+++ b/framework/commons/src/main/java/cd/casic/framework/commons/util/number/ArithUtil.java
@@ -0,0 +1,108 @@
+package cd.casic.framework.commons.util.number;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+/**
+ * 计算内存需要用到的算数帮助类
+ *
+ * @author mian-bin
+ * @Description ArithUtil
+ * @date 2025/1/10 15:33
+ */
+public class ArithUtil {
+ /**
+ * 默认除法运算精度
+ */
+ private static final int DEF_DIV_SCALE = 10;
+
+ /**
+ * 这个类不能实例化
+ */
+ private ArithUtil() {
+ }
+
+ /**
+ * 提供精确的加法运算。
+ * @param v1 被加数
+ * @param v2 加数
+ * @return 两个参数的和
+ */
+ public static double add(double v1, double v2) {
+ BigDecimal b1 = new BigDecimal(Double.toString(v1));
+ BigDecimal b2 = new BigDecimal(Double.toString(v2));
+ return b1.add(b2).doubleValue();
+ }
+
+ /**
+ * 提供精确的减法运算。
+ * @param v1 被减数
+ * @param v2 减数
+ * @return 两个参数的差
+ */
+ public static double sub(double v1, double v2) {
+ BigDecimal b1 = new BigDecimal(Double.toString(v1));
+ BigDecimal b2 = new BigDecimal(Double.toString(v2));
+ return b1.subtract(b2).doubleValue();
+ }
+
+ /**
+ * 提供精确的乘法运算。
+ * @param v1 被乘数
+ * @param v2 乘数
+ * @return 两个参数的积
+ */
+ public static double mul(double v1, double v2) {
+ BigDecimal b1 = new BigDecimal(Double.toString(v1));
+ BigDecimal b2 = new BigDecimal(Double.toString(v2));
+ return b1.multiply(b2).doubleValue();
+ }
+
+ /**
+ * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
+ * 小数点以后10位,以后的数字四舍五入。
+ * @param v1 被除数
+ * @param v2 除数
+ * @return 两个参数的商
+ */
+ public static double div(double v1, double v2) {
+ return div(v1, v2, DEF_DIV_SCALE);
+ }
+
+ /**
+ * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
+ * 定精度,以后的数字四舍五入。
+ * @param v1 被除数
+ * @param v2 除数
+ * @param scale 表示表示需要精确到小数点以后几位。
+ * @return 两个参数的商
+ */
+ public static double div(double v1, double v2, int scale) {
+ if (scale < 0) {
+ throw new IllegalArgumentException(
+ "The scale must be a positive integer or zero");
+ }
+ BigDecimal b1 = new BigDecimal(Double.toString(v1));
+ BigDecimal b2 = new BigDecimal(Double.toString(v2));
+ if (b1.compareTo(BigDecimal.ZERO) == 0) {
+ return BigDecimal.ZERO.doubleValue();
+ }
+ return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
+ }
+
+ /**
+ * 提供精确的小数位四舍五入处理。
+ * @param v 需要四舍五入的数字
+ * @param scale 小数点后保留几位
+ * @return 四舍五入后的结果
+ */
+ public static double round(double v, int scale) {
+ if (scale < 0) {
+ throw new IllegalArgumentException(
+ "The scale must be a positive integer or zero");
+ }
+ BigDecimal b = new BigDecimal(Double.toString(v));
+ BigDecimal one = new BigDecimal("1");
+ return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
+ }
+}