Java Web 获取系统信息

该博客介绍了如何在Java Web开发中利用Oshi库来实时监控操作系统的CPU、内存、磁盘和交换区的使用情况。通过引入Oshi的依赖,博主展示了获取系统信息、CPU利用率、内存使用、磁盘空间和交换区状态的代码示例,为性能分析和问题排查提供了实用工具。
摘要由CSDN通过智能技术生成

        Java做Web开发时,有时需要实时查看操作系统资源占用情况,以便分析应用是否发生高耗或异常。

1. 引入支持库

<dependency>
   <groupId>com.github.oshi</groupId>
   <artifactId>oshi-core</artifactId>
   <version>5.3.6</version>
</dependency>

2. 编写测试代码

package org.dsg.oshi;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.BetweenFormater;
import cn.hutool.core.date.DateUtil;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.hardware.VirtualMemory;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import oshi.util.FormatUtil;
import oshi.util.Util;

import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.text.DecimalFormat;
import java.util.*;

public class OSMonitorService {

    public static void main(String[] args) {
        OSMonitorService service = new OSMonitorService();
        Map<String, Object> servers = service.getServers();
        if(CollectionUtil.isNotEmpty(servers)) {
            servers.forEach((k, v) -> System.out.println(k + ":" + v));
        }
    }

    /**
     * 定义GB的计算常量
     */
    private static final int GB = 1024 * 1024 * 1024;
    /**
     * 定义MB的计算常量
     */
    private static final int MB = 1024 * 1024;
    /**
     * 定义KB的计算常量
     */
    private static final int KB = 1024;

    private final DecimalFormat df = new DecimalFormat("0.00");

    /**
     * 获取服务器信息
     */
    private Map<String, Object> getServers(){
        Map<String, Object> resultMap = new LinkedHashMap<>(8);
        try{
            SystemInfo si = new SystemInfo();
            OperatingSystem os = si.getOperatingSystem();
            HardwareAbstractionLayer hal = si.getHardware();
            resultMap.put("sys", getSystemInfo(os));
            resultMap.put("cpu", getCpuInfo(hal.getProcessor()));
            resultMap.put("memory", getMemoryInfo(hal.getMemory()));
            resultMap.put("swap", getSwapInfo(hal.getMemory()));
            resultMap.put("disk", getDiskInfo(os));
            resultMap.put("time", DateUtil.format(new Date(), "HH:mm:ss"));
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }

        return resultMap;
    }

    /**
     * 获取磁盘信息
     */
    private Map<String, Object> getDiskInfo(OperatingSystem os){
        Map<String, Object> diskInfo = new LinkedHashMap<>();
        FileSystem fileSystem = os.getFileSystem();
        List<OSFileStore> fsArray = fileSystem.getFileStores();
        String osName = System.getProperty("os.name");
        long available = 0, total = 0;
        for(OSFileStore fs:fsArray){
            // windows 需要将所有磁盘分区累加,linux 和 mac 直接累加会出现磁盘重复的问题,待修复
            if(osName.toLowerCase().startsWith("win")){
                available += fs.getUsableSpace();
                total += fs.getTotalSpace();
            }else{
                available = fs.getUsableSpace();
                total = fs.getTotalSpace();
                break;
            }
        }

        long used = total - available;
        diskInfo.put("total", total > 0?getSize(total):"?");
        diskInfo.put("available", getSize(available));
        diskInfo.put("used", getSize(used));
        diskInfo.put("usageRate", df.format(used/(double)total*100));
        return diskInfo;
    }

    /**
     * 获取交换区信息
     */
    private Map<String, Object> getSwapInfo(GlobalMemory memory){
        Map<String, Object> swapInfo = new LinkedHashMap<>();
        VirtualMemory virtualMemory = memory.getVirtualMemory();
        long total = virtualMemory.getSwapTotal();
        long used = virtualMemory.getSwapUsed();
        swapInfo.put("total", FormatUtil.formatBytes(total));
        swapInfo.put("used", FormatUtil.formatBytes(used));
        swapInfo.put("available", FormatUtil.formatBytes(total - used));
        if(used == 0){
            swapInfo.put("usageRate", 0);
        }else{
            swapInfo.put("usageRate", df.format(used/(double)total*100));
        }
        return swapInfo;
    }

    /**
     * 获取内存信息
     */
    private Map<String, Object> getMemoryInfo(GlobalMemory memory){
        Map<String, Object> memoryInfo = new LinkedHashMap<>();
        memoryInfo.put("total", FormatUtil.formatBytes(memory.getTotal()));
        memoryInfo.put("available", FormatUtil.formatBytes(memory.getAvailable()));
        memoryInfo.put("used", FormatUtil.formatBytes(memory.getTotal() - memory.getAvailable()));
        memoryInfo.put("usageRate", df.format((memory.getTotal() - memory.getAvailable())/(double)memory.getTotal()*100));
        return memoryInfo;
    }

    /**
     * 获取CPU相关信息
     */
    private Map<String, Object> getCpuInfo(CentralProcessor processor){
        Map<String, Object> cpuInfo = new LinkedHashMap<>();
        cpuInfo.put("name", processor.getProcessorIdentifier().getName());
        cpuInfo.put("package", processor.getPhysicalPackageCount() + "个物理包数");
        cpuInfo.put("core", processor.getPhysicalProcessorCount() + "个物理核心");
        cpuInfo.put("coreNumber", processor.getPhysicalProcessorCount());
        cpuInfo.put("logic", processor.getLogicalProcessorCount() + "个逻辑CPU");
        long[] prevTicks = processor.getSystemCpuLoadTicks();
        Util.sleep(1000);
        long[] ticks = processor.getSystemCpuLoadTicks();
        long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
        long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
        long sys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
        long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];;
        long ioWait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.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 totalCPU = user + nice + sys + idle + ioWait + irq + softIrq + steal;
        cpuInfo.put("used", df.format(100d * user / totalCPU + 100d * sys / totalCPU));
        cpuInfo.put("idle", df.format(100d * idle / totalCPU));
        return cpuInfo;
    }

    /**
     * 获取系统相关信息,系统运行天数、系统IP
     */
    private Map<String, Object> getSystemInfo(OperatingSystem os){
        Map<String, Object> systemInfo = new LinkedHashMap<>();
        //JVM运行事件
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        Date date = new Date(time);
        //计算项目运行时间
        String formatBetween = DateUtil.formatBetween(date, new Date(), BetweenFormater.Level.HOUR);
        //系统信息
        systemInfo.put("os", os.toString());
        systemInfo.put("day", formatBetween);
        systemInfo.put("ip", getLocalIP());
        return systemInfo;
    }

    /**
     * 获取当前机器IP
     * 遍历所有的网络接口,在所有的接口下遍历IP,排除loopback类型地址
     * 如果没有非loopback类型地址,只能用最次选的方案
     */
    private static String getLocalIP(){
        try {
            InetAddress candidateAddress = null;
            //遍历网络接口
            for(Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements();){
                NetworkInterface networkInterface = interfaces.nextElement();
                for(Enumeration<InetAddress> iNetAddress = networkInterface.getInetAddresses(); iNetAddress.hasMoreElements();){
                    InetAddress inetAddress = iNetAddress.nextElement();
                    if(!inetAddress.isLoopbackAddress()){
                        if(inetAddress.isSiteLocalAddress()){
                            return inetAddress.getHostAddress();
                        }else if(candidateAddress == null){
                            candidateAddress = inetAddress;
                        }
                    }
                }
            }

            if(candidateAddress != null){
                return candidateAddress.getHostAddress();
            }

            InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
            if(jdkSuppliedAddress == null) {
                return "";
            }

            return jdkSuppliedAddress.getHostAddress();
        }catch(Exception e){
            return "";
        }
    }

    private String getSize(long size) {
        String resultSize;
        if (size / GB >= 1) {
            //如果当前Byte的值大于等于1GB
            resultSize = df.format(size / (float) GB) + "GB";
        } else if (size / MB >= 1) {
            //如果当前Byte的值大于等于1MB
            resultSize = df.format(size / (float) MB) + "MB";
        } else if (size / KB >= 1) {
            //如果当前Byte的值大于等于1KB
            resultSize = df.format(size / (float) KB) + "KB";
        } else {
            resultSize = size + "B   ";
        }
        return resultSize;
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐江小鱼

知识创造财富,余额还是小数

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值