springboot使用oshi获取系统cpu、内存、jvm信息

2023-05-16

OSHI 是基于 JNA 的(本地)操作系统和硬件信息库。它不需要安装任何其他额外的本地库,旨在提供一种跨平台的实现来检索系统信息,例如操作系统版本、进程、内存和 CPU 使用率、磁盘和分区、设备、传感器等。

系统信息实体类:


import cn.hutool.core.lang.Singleton;
import cn.novelweb.tool.util.BigDecimalUtil;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import oshi.hardware.CentralProcessor;
import oshi.hardware.CentralProcessor.TickType;
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;
@Builder
@Data
@ApiModel(value = "系统信息整合")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SystemInfo {

    /**
     * 获取CPU需要睡眠的时间
     */
    public static int OSHI_WAIT_SECOND = 500;

    @ApiModelProperty(value = "系统CPU相关信息")
    private CpuInfo cpuInfo = Singleton.get(CpuInfo.class);

    @ApiModelProperty(value = "系统内存相关信息")
    private MemoryInfo memoryInfo = Singleton.get(MemoryInfo.class);

    @ApiModelProperty(value = "Java Jvm 相关信息")
    private JvmInfo jvmInfo = Singleton.get(JvmInfo.class);

    @ApiModelProperty(value = "操作系统相关信息")
    private OsInfo osInfo = Singleton.get(OsInfo.class);

    @ApiModelProperty(value = "磁盘相关信息")
    private List<FileSystemInfo> fileSystemInfo = new LinkedList<>();

    /**
     * 实例化 SystemInfo
     */
    public SystemInfo() {
        info();
    }

    /**
     * 初始化系统相关信息
     */
    private void info() {
        oshi.SystemInfo si = new oshi.SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        setCpuInfo(hal.getProcessor());
        setMemoryInfo(hal.getMemory());
        setJvmInfo();
        setFileSystemInfo(si.getOperatingSystem());
    }

    /**
     * 设置CPU相关信息
     *
     * @param processor 中央处理器信息
     */
    private void setCpuInfo(CentralProcessor processor) {
        // CPU信息
        long[] prevTicks = processor.getSystemCpuLoadTicks();
        // 这里必须要设置延迟
        Util.sleep(OSHI_WAIT_SECOND);
        long[] ticks = processor.getSystemCpuLoadTicks();
        long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
        long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
        long softIrq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
        long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
        long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
        long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
        long ioWait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
        long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
        long totalCpu = Math.max(user + nice + cSys + idle + ioWait + irq + softIrq + steal, 0);
        DecimalFormat format = new DecimalFormat("#.00");
        cpuInfo.setCpuNum(processor.getLogicalProcessorCount());
        cpuInfo.setToTal(totalCpu);
        cpuInfo.setSys(Double.parseDouble(format.format(cSys <= 0 ? 0 : (100d * cSys / totalCpu))));
        cpuInfo.setUsed(Double.parseDouble(format.format(user <= 0 ? 0 : (100d * user / totalCpu))));
        if (totalCpu == 0) {
            cpuInfo.setWait(0);
        } else {
            cpuInfo.setWait(Double.parseDouble(format.format(100d * ioWait / totalCpu)));
        }
        cpuInfo.setFree(Double.parseDouble(format.format(idle <= 0 ? 0 : (100d * idle / totalCpu))));
        cpuInfo.setCpuModel(processor.toString());
    }

    /**
     * 设置内存信息
     */
    private void setMemoryInfo(GlobalMemory memory) {
        memoryInfo.setToTal(memory.getTotal());
        memoryInfo.setUsed(memory.getTotal() - memory.getAvailable());
        memoryInfo.setFree(memory.getAvailable());
    }



    /**
     * 设置Java虚拟机
     */
    private void setJvmInfo() {
        Properties props = System.getProperties();
        jvmInfo.setToTal(Runtime.getRuntime().totalMemory());
        jvmInfo.setMax(Runtime.getRuntime().maxMemory());
        jvmInfo.setFree(Runtime.getRuntime().freeMemory());
        jvmInfo.setVersion(props.getProperty("java.version"));
        jvmInfo.setHome(props.getProperty("java.home"));
    }

    /**
     * 设置磁盘信息
     *
     * @param os 操作系统数据
     */
    private void setFileSystemInfo(OperatingSystem os) {
        FileSystem fileSystem = os.getFileSystem();
        OSFileStore[] fsArray = fileSystem.getFileStores();
        for (OSFileStore fs : fsArray) {
            long free = fs.getUsableSpace();
            long total = fs.getTotalSpace();
            long used = total - free;
            FileSystemInfo sysFile = new FileSystemInfo();
            sysFile.setDirName(fs.getMount());
            sysFile.setSysTypeName(fs.getType());
            sysFile.setTypeName(fs.getName());
            sysFile.setToTal(convertFileSize(total));
            sysFile.setFree(convertFileSize(free));
            sysFile.setUsed(convertFileSize(used));
            sysFile.setUsage(BigDecimalUtil.mul(BigDecimalUtil.div(used, total, 4), 100));
            fileSystemInfo.add(sysFile);
        }
    }

    /**
     * 文件大小字节转换
     *
     * @param size 大小
     * @return 转换后的字符串
     */
    private 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);
        }
    }
}

cpu信息:

@Data
@ApiModel(value = "系统CPU相关信息")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CpuInfo {

    @ApiModelProperty(value = "cpu核心数", example = "0")
    private Integer cpuNum;

    @ApiModelProperty(value = "CPU总的使用率", example = "0.00")
    private double toTal;

    @ApiModelProperty(value = "CPU系统使用率", example = "0.00")
    private double sys;

    @ApiModelProperty(value = "CPU用户使用率", example = "0.00")
    private double used;

    @ApiModelProperty(value = "CPU当前等待率", example = "0.00")
    private double wait;

    @ApiModelProperty(value = "CPU当前空闲率", example = "0.00")
    private double free;

    @ApiModelProperty(value = "CPU型号信息")
    private String cpuModel;
}

系统内存信息:

@Data
@ApiModel(value = "系统内存相关信息")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MemoryInfo {

    @ApiModelProperty(value = "内存总量(GB)", example = "0.00")
    private double toTal;

    @ApiModelProperty(value = "已用内存(GB)", example = "0.00")
    private double used;

    @ApiModelProperty(value = "剩余内存(GB)", example = "0.00")
    private double free;

    @ApiModelProperty(value = "当前内存使用率(百分比)", example = "0.00")
    private double usage;

    public double getTotal() {
        return BigDecimalUtil.div(toTal, (1024 * 1024 * 1024), 2);
    }

    public double getUsed() {
        return BigDecimalUtil.div(used, (1024 * 1024 * 1024), 2);
    }

    public double getFree() {
        return BigDecimalUtil.div(free, (1024 * 1024 * 1024), 2);
    }

    public double getUsage() {
        return BigDecimalUtil.mul(BigDecimalUtil.div(used, toTal, 4), 100);
    }
}

jvm信息:

@Data
@ApiModel(value = "Java Jvm 相关信息")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class JvmInfo {

    @ApiModelProperty(value = "当前JVM占用的内存总数(M)", example = "0.00")
    private double toTal;

    @ApiModelProperty(value = "JVM最大可用内存总数(M)", example = "0.00")
    private double max;

    @ApiModelProperty(value = "JVM空闲内存(M)", example = "0.00")
    private double free;

    @ApiModelProperty(value = "JVM的启动时间")
    private String startTime;

    @ApiModelProperty(value = "JVM的运行时间")
    private String runTime;

    @ApiModelProperty(value = "当前JVM运行的PID")
    private Long currentProcessIdentifier;

    @ApiModelProperty(value = "当前JVM已经使用的部分")
    private String used;

    @ApiModelProperty(value = "当前JVM使用率(百分比)")
    private String usage;

    @ApiModelProperty(value = "JDK版本信息")
    private String version;

    @ApiModelProperty(value = "JDK安装路径")
    private String home;

    @ApiModelProperty(value = "JDK名称")
    private String name;

    public double getToTal() {
        return BigDecimalUtil.div(toTal, (1024 * 1024), 2);
    }

    public double getMax() {
        return BigDecimalUtil.div(max, (1024 * 1024), 2);
    }

    public double getFree() {
        return BigDecimalUtil.div(free, (1024 * 1024), 2);
    }

    public String getName() {
        return ManagementFactory.getRuntimeMXBean().getVmName();
    }

    public String getStartTime() {
        return DateUtil.formatDateTime(getServerStartDate());
    }

    public String getRunTime() {
        return getDatePoor(new Date(), getServerStartDate());
    }

    public Long getCurrentProcessIdentifier() {
        return Long.parseLong(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);
    }

    public double getUsed() {
        return BigDecimalUtil.div(toTal - free, (1024 * 1024), 2);
    }

    public double getUsage() {
        return BigDecimalUtil.mul(BigDecimalUtil.div(toTal - free, toTal, 4), 100);
    }

    /**
     * 获取JVM服务启动时间
     *
     * @return 返回Date形式的JVM启动时间
     */
    private static Date getServerStartDate() {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 获取两个时间的差值(用于计算JVM运行时间)
     *
     * @param endDate 大的那个时间
     * @param nowDate 小的那个时间
     * @return 返回差的时间字符
     */
    private static String getDatePoor(Date endDate, Date nowDate) {
        // 依次定义 天、时、分、秒
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 输出结果
        return DateUtil.formatBetween(diff, BetweenFormater.Level.SECOND);
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springboot使用oshi获取系统cpu、内存、jvm信息 的相关文章

随机推荐