新增系统监控

This commit is contained in:
阿沐 2022-11-23 13:05:17 +08:00
parent f309dfc42c
commit 77066ce076
9 changed files with 622 additions and 0 deletions

View File

@ -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<Server> getServerInfo() {
Server server = new Server();
return Result.ok(server);
}
/**
* CPU相关信息
*/
@GetMapping("cpu")
@PreAuthorize("hasAuthority('monitor:server:all')")
public Result<Cpu> getCpuInfo() {
Cpu cpu = new Cpu();
return Result.ok(cpu);
}
/**
* 内存相关信息
*/
@GetMapping("mem")
@PreAuthorize("hasAuthority('monitor:server:all')")
public Result<Mem> getMemInfo() {
Mem mem = new Mem();
return Result.ok(mem);
}
/**
* JVM相关信息
*/
@GetMapping("jvm")
@PreAuthorize("hasAuthority('monitor:server:all')")
public Result<Jvm> getJvmInfo() {
Jvm jvm = new Jvm();
return Result.ok(jvm);
}
/**
* 系统相关信息
*/
@GetMapping("sys")
@PreAuthorize("hasAuthority('monitor:server:all')")
public Result<Sys> getSysInfo() {
Sys sys = new Sys();
return Result.ok(sys);
}
/**
* 系统文件相关信息
*/
@GetMapping("disk")
@PreAuthorize("hasAuthority('monitor:server:all')")
public Result<List<Disk>> getSysFileInfo() {
Server server = new Server(new Disk());
return Result.ok(server.getDisks());
}
}

View File

@ -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());
}
}

View File

@ -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;
}

View File

@ -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<String> 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());
}
}

View File

@ -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));
}
}

View File

@ -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());
}
}

View File

@ -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();
}
}

View File

@ -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<Disk> 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<OSFileStore> 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);
}
}
}

View File

@ -12,6 +12,7 @@
<module>maku-module-quartz</module> <module>maku-module-quartz</module>
<module>maku-module-message</module> <module>maku-module-message</module>
<module>maku-module-generator</module> <module>maku-module-generator</module>
<module>maku-module-monitor</module>
</modules> </modules>
</project> </project>