diff --git a/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/controller/ServerController.java b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/controller/ServerController.java new file mode 100644 index 0000000..9885454 --- /dev/null +++ b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/controller/ServerController.java @@ -0,0 +1,82 @@ +package net.maku.monitor.controller; + +import net.maku.framework.common.utils.Result; +import net.maku.monitor.model.*; +import net.maku.monitor.vo.Server; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 服务器监控 + * + * @author Pure tea + */ +@RestController +@RequestMapping("monitor/server") +public class ServerController { + + /** + * 服务器相关信息 + */ + @GetMapping("info") + @PreAuthorize("hasAuthority('monitor:server:all')") + public Result getServerInfo() { + Server server = new Server(); + return Result.ok(server); + } + + /** + * CPU相关信息 + */ + @GetMapping("cpu") + @PreAuthorize("hasAuthority('monitor:server:all')") + public Result getCpuInfo() { + Cpu cpu = new Cpu(); + return Result.ok(cpu); + } + + /** + * 内存相关信息 + */ + @GetMapping("mem") + @PreAuthorize("hasAuthority('monitor:server:all')") + public Result getMemInfo() { + Mem mem = new Mem(); + return Result.ok(mem); + } + + /** + * JVM相关信息 + */ + @GetMapping("jvm") + @PreAuthorize("hasAuthority('monitor:server:all')") + public Result getJvmInfo() { + Jvm jvm = new Jvm(); + return Result.ok(jvm); + } + + /** + * 系统相关信息 + */ + @GetMapping("sys") + @PreAuthorize("hasAuthority('monitor:server:all')") + public Result getSysInfo() { + Sys sys = new Sys(); + return Result.ok(sys); + } + + /** + * 系统文件相关信息 + */ + @GetMapping("disk") + @PreAuthorize("hasAuthority('monitor:server:all')") + public Result> getSysFileInfo() { + Server server = new Server(new Disk()); + return Result.ok(server.getDisks()); + } + +} diff --git a/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Cpu.java b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Cpu.java new file mode 100644 index 0000000..1c33467 --- /dev/null +++ b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Cpu.java @@ -0,0 +1,67 @@ +package net.maku.monitor.model; + +import cn.hutool.system.oshi.CpuInfo; +import cn.hutool.system.oshi.OshiUtil; +import lombok.Data; + +/** + * Cpu Info + * + * @author Pure tea + */ +@Data +public class Cpu { + + /** + * 设置等待时间,单位毫秒 + */ + private static final Long JOSHI_WAIT_SECOND = 360L; + + /** + * CPU型号 + */ + private String cpuModel; + + /** + * 核心数 + */ + private int cpuNum; + + /** + * CPU总的使用率 + */ + private double total; + + /** + * CPU系统使用率 + */ + private double sys; + + /** + * CPU用户使用率 + */ + private double used; + + /** + * CPU当前等待率 + */ + private double wait; + + /** + * CPU当前空闲率 + */ + private double free; + + public Cpu() { + // 获取CPU相关信息,间隔1秒 + CpuInfo cpuInfo = OshiUtil.getCpuInfo(JOSHI_WAIT_SECOND); + this.setCpuModel(cpuInfo.getCpuModel().split("\n")[0]); + this.setCpuNum(cpuInfo.getCpuNum()); + this.setTotal(cpuInfo.getToTal()); + this.setSys(cpuInfo.getSys()); + this.setUsed(cpuInfo.getUser()); + this.setWait(cpuInfo.getWait()); + this.setFree(cpuInfo.getFree()); + } + +} diff --git a/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Disk.java b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Disk.java new file mode 100644 index 0000000..508d33c --- /dev/null +++ b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Disk.java @@ -0,0 +1,48 @@ +package net.maku.monitor.model; + +import lombok.Data; + +/** + * Disk + * + * @author Pure tea + */ +@Data +public class Disk { + + /** + * 磁盘名称 + */ + private String diskName; + + /** + * 磁盘类型 + */ + private String diskType; + + /** + * 磁盘路径 + */ + private String dirName; + + /** + * 总大小 + */ + private String total; + + /** + * 剩余大小 + */ + private String free; + + /** + * 已经使用量 + */ + private String used; + + /** + * 资源的使用率 + */ + private double usage; + +} diff --git a/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Jvm.java b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Jvm.java new file mode 100644 index 0000000..937decb --- /dev/null +++ b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Jvm.java @@ -0,0 +1,101 @@ +package net.maku.monitor.model; + +import cn.hutool.core.date.BetweenFormatter; +import cn.hutool.core.date.DateUtil; +import cn.hutool.system.SystemUtil; +import lombok.Data; +import net.maku.monitor.utils.ArityUtil; + +import java.util.Date; +import java.util.List; + +/** + * Jvm Info + * + * @author Pure tea + */ +@Data +public class Jvm { + + /** + * JVM 最大可用内存总数(G) + */ + private double max; + + /** + * JVM 占用的内存总数(M) + */ + private double total; + + /** + * JVM 已用内存(M) + */ + private double used; + + /** + * JVM 空闲内存(M) + */ + private double free; + + /** + * JVM 内存使用率 + */ + private double usage; + + /** + * JVM 名称 + */ + private String name; + + /** + * Java Version + */ + private String version; + + /** + * JavaVM Vendor + */ + private String vendor; + + /** + * JDK 路径 + */ + private String home; + + /** + * JarDir + */ + private String userDir; + + /** + * JVM 启动时间 + */ + private String startTime; + + /** + * JVM 运行时间 + */ + private String runTime; + + /** + * JVM InputArguments + */ + private List inputArguments; + + public Jvm() { + this.setMax(ArityUtil.div(SystemUtil.getMaxMemory(), 1024 * 1024 * 1024, 2)); + this.setTotal(ArityUtil.div(SystemUtil.getTotalMemory(), 1024 * 1024 * 1024, 2)); + this.setFree(ArityUtil.div(SystemUtil.getFreeMemory(), 1024 * 1024 * 1024, 2)); + this.setUsed(ArityUtil.round(this.getTotal() - this.getFree(), 2)); + this.setUsage(ArityUtil.div(this.getUsed(), this.getTotal(), 4) * 100); + this.setName(SystemUtil.getRuntimeMXBean().getVmName()); + this.setVersion(SystemUtil.getJavaInfo().getVersion()); + this.setVendor(SystemUtil.getJavaInfo().getVendor()); + this.setHome(SystemUtil.getJavaRuntimeInfo().getHomeDir()); + this.setUserDir(SystemUtil.getUserInfo().getCurrentDir()); + Date startTime = new Date(SystemUtil.getRuntimeMXBean().getStartTime()); + this.setStartTime(DateUtil.formatDateTime(startTime)); + this.setRunTime(DateUtil.formatBetween(startTime, new Date(), BetweenFormatter.Level.SECOND)); + this.setInputArguments(SystemUtil.getRuntimeMXBean().getInputArguments()); + } +} diff --git a/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Mem.java b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Mem.java new file mode 100644 index 0000000..7b57b1a --- /dev/null +++ b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Mem.java @@ -0,0 +1,44 @@ +package net.maku.monitor.model; + +import cn.hutool.system.oshi.OshiUtil; +import lombok.Data; +import net.maku.monitor.utils.ArityUtil; +import oshi.hardware.GlobalMemory; + +/** + * Mem Info + * + * @author Pure tea + */ +@Data +public class Mem { + + /** + * 内存总数(G) + */ + private double total; + + /** + * 已用内存(G) + */ + private double used; + + /** + * 剩余内存(G) + */ + private double free; + + /** + * 内存使用率 + */ + private double usage; + + public Mem() { + GlobalMemory globalMemory = OshiUtil.getMemory(); + this.setTotal(ArityUtil.div(globalMemory.getTotal(), 1024 * 1024 * 1024, 2)); + this.setFree(ArityUtil.div(globalMemory.getAvailable(), 1024 * 1024 * 1024, 2)); + this.setUsed(ArityUtil.sub(this.getTotal(), this.getFree())); + this.setUsage(ArityUtil.round(ArityUtil.div(this.getUsed(), this.getTotal(), 4) * 100, 2)); + } + +} diff --git a/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Sys.java b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Sys.java new file mode 100644 index 0000000..24d4a2f --- /dev/null +++ b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/model/Sys.java @@ -0,0 +1,49 @@ +package net.maku.monitor.model; + +import cn.hutool.system.SystemUtil; +import cn.hutool.system.oshi.OshiUtil; +import lombok.Data; + +/** + * System Info + * + * @author Pure tea + */ +@Data +public class Sys { + + /** + * 操作系统 + */ + private String osName; + + /** + * 系统架构 + */ + private String osArch; + + /** + * 系统版本 + */ + private String osVersion; + + + /** + * 服务器名称 + */ + private String computerName; + + /** + * 服务器Ip + */ + private String computerIp; + + public Sys() { + this.setOsName(SystemUtil.getOsInfo().getName()); + this.setOsArch(SystemUtil.getOsInfo().getArch()); + this.setOsVersion(SystemUtil.getOsInfo().getVersion()); + this.setComputerName(OshiUtil.getOs().getNetworkParams().getHostName()); + this.setComputerIp(SystemUtil.getHostInfo().getAddress()); + } + +} diff --git a/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/utils/ArityUtil.java b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/utils/ArityUtil.java new file mode 100644 index 0000000..c08b7e3 --- /dev/null +++ b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/utils/ArityUtil.java @@ -0,0 +1,114 @@ +package net.maku.monitor.utils; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * 精确浮点数运算 + * + * @author Pure tea + */ +public class ArityUtil { + + /** + * 默认除法运算精度 + */ + private static final int DEF_DIV_SCALE = 10; + + /** + * 这个类不能实例化 + */ + private ArityUtil() { + + } + + /** + * 提供精确的加法运算。 + * + * @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 = BigDecimal.ONE; + return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue(); + } +} diff --git a/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/vo/Server.java b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/vo/Server.java new file mode 100644 index 0000000..43847a2 --- /dev/null +++ b/maku-boot-module/maku-module-monitor/src/main/java/net/maku/monitor/vo/Server.java @@ -0,0 +1,116 @@ +package net.maku.monitor.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import net.maku.monitor.model.*; +import net.maku.monitor.utils.ArityUtil; +import oshi.SystemInfo; +import oshi.software.os.FileSystem; +import oshi.software.os.OSFileStore; + +import java.util.LinkedList; +import java.util.List; + +/** + * Server Info + * + * @author Pure tea + */ +@Tag(name = "服务器信息") +@Data +@Slf4j +public class Server { + + /** + * Cpu Info + */ + @Schema(description = "CPU信息") + private Cpu cpu; + + /** + * Mem Info + */ + @Schema(description = "内存信息") + private Mem mem; + + /** + * Jvm Info + */ + @Schema(description = "JVM信息") + private Jvm jvm; + + /** + * Sys Info + */ + @Schema(description = "系统信息") + private Sys sys; + + /** + * SysFile Info + */ + @Schema(description = "系统文件信息") + private List disks = new LinkedList<>(); + + public Server() { + this.cpu = new Cpu(); + this.mem = new Mem(); + this.jvm = new Jvm(); + this.sys = new Sys(); + this.setDiskList(); + log.info("Server Info => {}", this); + } + + public Server(Disk disk) { + this.setDiskList(); + log.info("Server Info => {}", this); + } + + /** + * 设置磁盘信息 + */ + private void setDiskList() { + SystemInfo systemInfo = new SystemInfo(); + FileSystem fileSystem = systemInfo.getOperatingSystem().getFileSystem(); + List fsArray = fileSystem.getFileStores(); + for (OSFileStore fs : fsArray) { + long free = fs.getUsableSpace(); + long total = fs.getTotalSpace(); + long used = total - free; + Disk disk = new Disk(); + disk.setDiskName(fs.getName()); + disk.setDiskType(fs.getType()); + disk.setDirName(fs.getMount()); + disk.setTotal(convertFileSize(total)); + disk.setFree(convertFileSize(free)); + disk.setUsed(convertFileSize(used)); + disk.setUsage(ArityUtil.mul(ArityUtil.div(used, total, 4), 100)); + this.disks.add(disk); + } + } + + /** + * 字节转换 + * + * @param size 字节大小 + * @return 转换后值 + */ + public static 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/maku-boot-module/pom.xml b/maku-boot-module/pom.xml index c64d43d..2ad5dc6 100644 --- a/maku-boot-module/pom.xml +++ b/maku-boot-module/pom.xml @@ -12,6 +12,7 @@ maku-module-quartz maku-module-message maku-module-generator + maku-module-monitor \ No newline at end of file