实现
使用Oshi和Hutool工具包1、pom依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.github.oshi</groupId><artifactId>oshi-core</artifactId><version>6.4.0</version></dependency><dependency><groupId>io.projectreactor</groupId><artifactId>reactor-core</artifactId></dependency><!--swagger--><dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version></dependency><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-ui</artifactId><version>3.0.3</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.8</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.11</version></dependency>
代码demo
1、工具类
Arith
package com.yy.agent.util;import java.math.BigDecimal;
import java.math.RoundingMode;/*** @author code* @version 1.0* @Date 2024/6/12 10:24* @Description 精确的浮点数运算*/
public class Arith {/** 默认除法运算精度 */private static final int DEF_DIV_SCALE = 10;/** 这个类不能实例化 */private Arith(){}/*** 提供精确的加法运算。* @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();}
}
DateUtils
package com.yy.agent.util;import org.apache.commons.lang3.time.DateFormatUtils;import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.Date;/*** @author code* @version 1.0* @Date 2024/6/12 10:42* @Description ${DESCRIPTION}*/
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {public static String YYYY = "yyyy";public static String YYYY_MM = "yyyy-MM";public static String YYYY_MM_DD = "yyyy-MM-dd";public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";private static String[] parsePatterns = {"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM","yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM","yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};/*** 获取当前Date型日期** @return Date() 当前日期*/public static Date getNowDate(){return new Date();}/*** 获取当前日期, 默认格式为yyyy-MM-dd** @return String*/public static String getDate(){return dateTimeNow(YYYY_MM_DD);}public static final String getTime(){return dateTimeNow(YYYY_MM_DD_HH_MM_SS);}public static final String dateTimeNow(){return dateTimeNow(YYYYMMDDHHMMSS);}public static final String dateTimeNow(final String format){return parseDateToStr(format, new Date());}public static final String dateTime(final Date date){return parseDateToStr(YYYY_MM_DD, date);}public static final String parseDateToStr(final String format, final Date date){return new SimpleDateFormat(format).format(date);}public static final Date dateTime(final String format, final String ts){try{return new SimpleDateFormat(format).parse(ts);}catch (ParseException e){throw new RuntimeException(e);}}/*** 日期路径 即年/月/日 如2018/08/08*/public static final String datePath(){Date now = new Date();return DateFormatUtils.format(now, "yyyy/MM/dd");}/*** 日期路径 即年/月/日 如20180808*/public static final String dateTime(){Date now = new Date();return DateFormatUtils.format(now, "yyyyMMdd");}/*** 日期型字符串转化为日期 格式*/public static Date parseDate(Object str){if (str == null){return null;}try{return parseDate(str.toString(), parsePatterns);}catch (ParseException e){return null;}}/*** 获取服务器启动时间*/public static Date getServerStartDate(){long time = ManagementFactory.getRuntimeMXBean().getStartTime();return new Date(time);}/*** 计算时间差** @param endTime 最后时间* @param startTime 开始时间* @return 时间差(天/小时/分钟)*/public static String timeDistance(Date endTime, Date startTime){long nd = 1000 * 24 * 60 * 60;long nh = 1000 * 60 * 60;long nm = 1000 * 60;// long ns = 1000;// 获得两个时间的毫秒时间差异long diff = endTime.getTime() - startTime.getTime();// 计算差多少天long day = diff / nd;// 计算差多少小时long hour = diff % nd / nh;// 计算差多少分钟long min = diff % nd % nh / nm;// 计算差多少秒//输出结果// long sec = diff % nd % nh % nm / ns;return day + "天" + hour + "小时" + min + "分钟";}/*** 增加 LocalDateTime ==> Date*/public static Date toDate(LocalDateTime temporalAccessor){ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());return Date.from(zdt.toInstant());}/*** 增加 LocalDate ==> Date*/public static Date toDate(LocalDate temporalAccessor){LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());return Date.from(zdt.toInstant());}}
2、实体类
Cpu
package com.yy.agent.eneity.po;import com.yy.agent.util.Arith;/*** @author code* @version 1.0* @Date 2024/6/12 9:53* @Description ${DESCRIPTION}*/
public class Cpu {/*** 服务器ip*/private String hostName;/*** 核心数*/private int cpuNum;/*** CPU总的使用率*/private double total;/*** CPU系统使用率*/private double sys;/*** CPU用户使用率*/private double used;/*** CPU当前等待率*/private double wait;/*** CPU当前空闲率*/private double free;public int getCpuNum(){return cpuNum;}public void setCpuNum(int cpuNum){this.cpuNum = cpuNum;}public double getTotal(){return Arith.round(Arith.mul(total, 100), 2);}public void setTotal(double total){this.total = total;}public double getSys(){return Arith.round(Arith.mul(sys / total, 100), 2);}public void setSys(double sys){this.sys = sys;}public double getUsed(){return Arith.round(Arith.mul(used / total, 100), 2);}public void setUsed(double used){this.used = used;}public double getWait(){return Arith.round(Arith.mul(wait / total, 100), 2);}public void setWait(double wait){this.wait = wait;}public double getFree(){return Arith.round(Arith.mul(free / total, 100), 2);}public void setFree(double free){this.free = free;}public String getHostName() {return hostName;}public void setHostName(String hostName) {this.hostName = hostName;}@Overridepublic String toString() {return "Cpu{" +"hostName='" + hostName + '\'' +", cpuNum=" + cpuNum +", total=" + total +", sys=" + sys +", used=" + used +", wait=" + wait +", free=" + free +'}';}
}
package com.yy.agent.eneity.po;import com.yy.agent.util.Arith;/*** @author code* @version 1.0* @Date 2024/6/12 10:25* @Description ${DESCRIPTION}*/
public class Mem {/*** 服务器ip*/private String hostName;/*** 内存总量*/private double total;/*** 已用内存*/private double used;/*** 剩余内存*/private double free;public double getTotal(){return Arith.div(total, (1024 * 1024 * 1024), 2);}public void setTotal(long total){this.total = total;}public double getUsed(){return Arith.div(used, (1024 * 1024 * 1024), 2);}public void setUsed(long used){this.used = used;}public double getFree(){return Arith.div(free, (1024 * 1024 * 1024), 2);}public void setFree(long free){this.free = free;}public double getUsage(){return Arith.mul(Arith.div(used, total, 4), 100);}public String getHostName() {return hostName;}public void setHostName(String hostName) {this.hostName = hostName;}@Overridepublic String toString() {return "Mem{" +"hostName='" + hostName + '\'' +", total=" + total +", used=" + used +", free=" + free +'}';}
}
Sys
package com.yy.agent.eneity.po;/*** @author code* @version 1.0* @Date 2024/6/12 11:13* @Description ${DESCRIPTION}*/
public class Sys {/*** 服务器ip*/private String hostName;/*** 服务器名称*/private String computerName;/*** 服务器Ip*/private String computerIp;/*** 项目路径*/private String userDir;/*** 操作系统*/private String osName;/*** 系统架构*/private String osArch;/*** 系统状态*/private String state;private Integer processCount;/*** 磁盘使用率*/private Double DiskUsage;/*** cpu使用率*/private Double cpuUsage;/*** mem使用率*/private Double memUsage;private Integer cpuCoreNum;private long bootTime;private long upTime;public String getComputerName(){return computerName;}public void setComputerName(String computerName){this.computerName = computerName;}public String getComputerIp(){return computerIp;}public void setComputerIp(String computerIp){this.computerIp = computerIp;}public String getUserDir(){return userDir;}public void setUserDir(String userDir){this.userDir = userDir;}public String getOsName(){return osName;}public void setOsName(String osName){this.osName = osName;}public String getOsArch(){return osArch;}public void setOsArch(String osArch){this.osArch = osArch;}public String getState() {return state;}public void setState(String state) {this.state = state;}public String getHostName() {return hostName;}public void setHostName(String hostName) {this.hostName = hostName;}public Integer getProcessCount() {return processCount;}public void setProcessCount(Integer processCount) {this.processCount = processCount;}public Double getDiskUsage() {return DiskUsage;}public void setDiskUsage(Double diskUsage) {DiskUsage = diskUsage;}public Double getCpuUsage() {return cpuUsage;}public void setCpuUsage(Double cpuUsage) {this.cpuUsage = cpuUsage;}public Double getMemUsage() {return memUsage;}public void setMemUsage(Double memUsage) {this.memUsage = memUsage;}public Integer getCpuCoreNum() {return cpuCoreNum;}public void setCpuCoreNum(Integer cpuCoreNum) {this.cpuCoreNum = cpuCoreNum;}public long getBootTime() {return bootTime;}public void setBootTime(long bootTime) {this.bootTime = bootTime;}public long getUpTime() {return upTime;}public void setUpTime(long upTime) {this.upTime = upTime;}@Overridepublic String toString() {return "Sys{" +"hostName='" + hostName + '\'' +", computerName='" + computerName + '\'' +", computerIp='" + computerIp + '\'' +", userDir='" + userDir + '\'' +", osName='" + osName + '\'' +", osArch='" + osArch + '\'' +", state='" + state + '\'' +", processCount=" + processCount +", DiskUsage=" + DiskUsage +", cpuUsage=" + cpuUsage +", memUsage=" + memUsage +", cpuCoreNum=" + cpuCoreNum +", bootTime=" + bootTime +", upTime=" + upTime +'}';}
}
SysFile
package com.yy.agent.eneity.po;/*** @author code* @version 1.0* @Date 2024/6/12 10:27* @Description ${DESCRIPTION}*/
public class SysFile {/*** 服务器ip*/private String hostName;/*** 盘符路径*/private String dirName;/*** 盘符类型*/private String sysTypeName;/*** 文件类型*/private String typeName;/*** 总大小*/private String total;/*** 剩余大小*/private String free;/*** 已经使用量*/private String used;/*** 资源的使用率*/private double usage;public String getDirName(){return dirName;}public void setDirName(String dirName){this.dirName = dirName;}public String getSysTypeName(){return sysTypeName;}public void setSysTypeName(String sysTypeName){this.sysTypeName = sysTypeName;}public String getTypeName(){return typeName;}public void setTypeName(String typeName){this.typeName = typeName;}public String getTotal(){return total;}public void setTotal(String total){this.total = total;}public String getFree(){return free;}public void setFree(String free){this.free = free;}public String getUsed(){return used;}public void setUsed(String used){this.used = used;}public double getUsage(){return usage;}public void setUsage(double usage){this.usage = usage;}public String getHostName() {return hostName;}public void setHostName(String hostName) {this.hostName = hostName;}@Overridepublic String toString() {return "SysFile{" +"hostName='" + hostName + '\'' +", dirName='" + dirName + '\'' +", sysTypeName='" + sysTypeName + '\'' +", typeName='" + typeName + '\'' +", total='" + total + '\'' +", free='" + free + '\'' +", used='" + used + '\'' +", usage=" + usage +'}';}
}
3、接口
ServerResourceController
package com.yy.agent.controller;import com.yy.agent.eneity.po.Server;
import com.yy.agent.util.ResultUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;/*** @author code* @version 1.0* @Date 2024/6/12 13:51* @Description ${DESCRIPTION}*/
@RestController
@RequestMapping("/server")
@Slf4j
public class ServerResourceController {@GetMapping(value = "/resource")public ResultUtils getServerResource() {Server server = new Server();Map<String, Object> resMap = new HashMap<>();try {server.copyTo();log.info("server:{}", server.toString());resMap.put("server", server.getSys());resMap.put("process", server.getProcesses());resMap.put("fs", server.getFsArray());resMap.put("disk", server.getSysFiles());} catch (Exception e) {log.error("exception");}return ResultUtils.ok(resMap);}}
结果
http://192.168.59.128:18071/server/resource
源码
代码地址:https://gitee.com/yy19951002/demo/tree/master/spring-boot-parent/spring-boot-agent