Springboot集成oshi遠(yuǎn)程監(jiān)控主機(jī)

我們有時(shí)候需要去監(jiān)控服務(wù)器的信息,在服務(wù)器達(dá)到某個(gè)閾值的時(shí)候需要報(bào)警,今天我們使用Springboot結(jié)合oshi來獲取系統(tǒng)信息

1.排除springboot(這里使用springboot 2.1.14.RELEASE)自帶的jna和jna-platform

    compile('org.springframework.boot:spring-boot-starter-web') {
        exclude group: 'net.java.dev.jna', module: 'jna'
        exclude group: 'net.java.dev.jna', module: 'jna-platform'
    }

2.引入oshi和高版本jna

    compile 'com.github.oshi:oshi-core:5.3.6'
    compile 'net.java.dev.jna:jna:5.6.0'
    compile 'net.java.dev.jna:jna-platform:5.6.0'

3.編寫通用信息實(shí)體

import lombok.Data;

/**
 * @author lieber
 */
@Data
public class BaseInfo {

    /**
     * 總大小
     */
    private String total;

    /**
     * 空閑
     */
    private String available;

    /**
     * 已使用
     */
    private String used;

    /**
     * 使用率
     */
    private String usageRate;

}

CPU信息實(shí)體

import lombok.Data;

/**
 * @author lieber
 */
@Data
public class CpuInfo {

    /**
     * CPU名稱
     */
    private String name;

    /**
     * 物理CPU
     */
    private int number;

    /**
     * 邏輯CPU
     */
    private int logic;

    /**
     * 物理核心數(shù)
     */
    private int core;

    /**
     * 空閑
     */
    private String idle;

    /**
     * 使用
     */
    private String used;

}

內(nèi)存信息實(shí)體

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

/**
 * @author lieber
 */
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Data
public class MemoryInfo extends BaseInfo {
}

交換區(qū)信息實(shí)體

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

/**
 * @author lieber
 */
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Data
public class SwapInfo extends BaseInfo {
}

磁盤信息實(shí)體

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

/**
 * @author lieber
 */
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Data
public class DiskInfo extends BaseInfo {
}

系統(tǒng)信息實(shí)體

import lombok.Data;

/**
 * @author lieber
 */
@Data
public class OsInfo {

    private String name;

    private String ip;
  /**
 * @author lieber
 */
    private long runtime;

}

輸出信息實(shí)體

import lombok.Builder;
import lombok.Data;

/**
 * @author lieber
 */
@Data
@Builder
public class SysInfo {

    private OsInfo os;

    private CpuInfo cpu;

    private MemoryInfo memory;

    private SwapInfo swap;

    private DiskInfo disk;

    private Long time;

}

4.編寫操作工具類

import com.xcqinzi.api.common.util.sys.model.*;
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.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author lieber
 */
public class SysUtil {

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

    private static SysUtil util;

    public static SysUtil getInstance() {
        if (util == null) {
            util = new SysUtil();
        }
        return util;
    }

    public SysInfo get() {
        SystemInfo si = new SystemInfo();
        OperatingSystem os = si.getOperatingSystem();
        HardwareAbstractionLayer hal = si.getHardware();
        CpuInfo cpuInfo = this.getCpuInfo(hal.getProcessor());
        MemoryInfo memoryInfo = this.getMemoryInfo(hal.getMemory());
        SwapInfo swapInfo = this.getSwapInfo(hal.getMemory());
        DiskInfo diskInfo = this.getDiskInfo(os);
        OsInfo osInfo = this.getOsInfo(os);
        return SysInfo.builder().cpu(cpuInfo).memory(memoryInfo).swap(swapInfo).disk(diskInfo).os(osInfo).time(System.currentTimeMillis()).build();
    }

    private CpuInfo getCpuInfo(CentralProcessor processor) {
        CpuInfo cpuInfo = new CpuInfo();
        // 基本信息
        cpuInfo.setName(processor.getProcessorIdentifier().getName());
        cpuInfo.setNumber(processor.getPhysicalPackageCount());
        cpuInfo.setCore(processor.getPhysicalProcessorCount());
        cpuInfo.setLogic(processor.getLogicalProcessorCount());
        // 占用信息
        long[] startTicks = processor.getSystemCpuLoadTicks();
        Util.sleep(1000);
        long[] endTicks = processor.getSystemCpuLoadTicks();
        long user = endTicks[CentralProcessor.TickType.USER.getIndex()] - startTicks[CentralProcessor.TickType.USER.getIndex()];
        long nice = endTicks[CentralProcessor.TickType.NICE.getIndex()] - startTicks[CentralProcessor.TickType.NICE.getIndex()];
        long sys = endTicks[CentralProcessor.TickType.SYSTEM.getIndex()] - startTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
        long idle = endTicks[CentralProcessor.TickType.IDLE.getIndex()] - startTicks[CentralProcessor.TickType.IDLE.getIndex()];
        long ioWait = endTicks[CentralProcessor.TickType.IOWAIT.getIndex()] - startTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
        long irq = endTicks[CentralProcessor.TickType.IRQ.getIndex()] - startTicks[CentralProcessor.TickType.IRQ.getIndex()];
        long softIrq = endTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - startTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
        long steal = endTicks[CentralProcessor.TickType.STEAL.getIndex()] - startTicks[CentralProcessor.TickType.STEAL.getIndex()];
        long totalCpu = user + nice + sys + idle + ioWait + irq + softIrq + steal;
        if (totalCpu <= 0) {
            cpuInfo.setUsed("0");
            cpuInfo.setIdle("0");
        } else {
            cpuInfo.setUsed(df.format(100d * user / totalCpu + 100d * sys / totalCpu));
            cpuInfo.setIdle(df.format(100d * idle / totalCpu));
        }
        return cpuInfo;
    }

    private MemoryInfo getMemoryInfo(GlobalMemory memory) {
        MemoryInfo memoryInfo = new MemoryInfo();
        long total = memory.getTotal();
        long available = memory.getAvailable();
        long used = total - available;

        memoryInfo.setTotal(FormatUtil.formatBytes(total));
        memoryInfo.setAvailable(FormatUtil.formatBytes(available));
        memoryInfo.setUsed(FormatUtil.formatBytes(used));
        String usageRate = "0";
        if (total > 0 && used > 0) {
            usageRate = df.format(used * 100d / total);
        }
        memoryInfo.setUsageRate(usageRate);
        return memoryInfo;
    }

    private SwapInfo getSwapInfo(GlobalMemory memory) {
        SwapInfo swapInfo = new SwapInfo();
        VirtualMemory virtualMemory = memory.getVirtualMemory();
        long total = virtualMemory.getSwapTotal();
        long used = virtualMemory.getSwapUsed();
        long available = total - used;

        swapInfo.setTotal(FormatUtil.formatBytes(total));
        swapInfo.setAvailable(FormatUtil.formatBytes(available));
        swapInfo.setUsed(FormatUtil.formatBytes(used));
        String usageRate = "0";
        if (total > 0 && used > 0) {
            usageRate = df.format(used * 100d / total);
        }
        swapInfo.setUsageRate(usageRate);
        return swapInfo;
    }

    private DiskInfo getDiskInfo(OperatingSystem os) {
        DiskInfo diskInfo = new DiskInfo();
        FileSystem fileSystem = os.getFileSystem();
        List<OSFileStore> fsArray = fileSystem.getFileStores();
        String osName = System.getProperty("os.name");
        long available = 0, total = 0;
        if (osName.toLowerCase().startsWith("win")) {
            for (OSFileStore fs : fsArray) {
                available += fs.getUsableSpace();
                total += fs.getTotalSpace();
            }
        } else {
            Set<String> names = new HashSet<>(fsArray.size());
            for (OSFileStore fs : fsArray) {
                if (names.add(fs.getName())) {
                    available = fs.getUsableSpace();
                    total = fs.getTotalSpace();
                }
            }
        }
        long used = total - available;

        diskInfo.setTotal(FormatUtil.formatBytes(total));
        diskInfo.setAvailable(FormatUtil.formatBytes(available));
        diskInfo.setUsed(FormatUtil.formatBytes(used));
        String usageRate = "0";
        if (total > 0 && used > 0) {
            usageRate = df.format(used * 100d / total);
        }
        diskInfo.setUsageRate(usageRate);

        return diskInfo;
    }

    private OsInfo getOsInfo(OperatingSystem os) {
        OsInfo osInfo = new OsInfo();
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        osInfo.setName(os.toString());
        osInfo.setIp(this.getIp());
        osInfo.setRuntime(System.currentTimeMillis() - time);
        return osInfo;
    }

    private String getIp() {
        try {
            InetAddress candidateAddress = null;
            // 查找網(wǎng)絡(luò)接口
            for (Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements(); ) {
                NetworkInterface anInterface = interfaces.nextElement();
                // 遍歷所有IP
                for (Enumeration<InetAddress> inetAddresses = anInterface.getInetAddresses(); inetAddresses.hasMoreElements(); ) {
                    InetAddress inetAddr = inetAddresses.nextElement();
                    // 排除loopback類型地址
                    if (!inetAddr.isLoopbackAddress()) {
                        if (inetAddr.isSiteLocalAddress()) {
                            return inetAddr.getHostAddress();
                        } else if (candidateAddress == null) {
                            candidateAddress = inetAddr;
                        }
                    }
                }
            }
            if (candidateAddress != null) {
                return candidateAddress.getHostAddress();
            }
            InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
            if (jdkSuppliedAddress == null) {
                return "";
            }
            return jdkSuppliedAddress.getHostAddress();
        } catch (Exception e) {
            return "";
        }
    }
}

5.測(cè)試

    @Test
    public void sys() {
        for (int i = 0; i <100 ; i++) {
            System.out.println(SysUtil.getInstance().get());
            Util.sleep(1000);
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖非洲,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蜕径,居然都是意外死亡两踏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門丧荐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缆瓣,“玉大人,你說我怎么就攤上這事虹统」耄” “怎么了隧甚?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長渡冻。 經(jīng)常有香客問我戚扳,道長,這世上最難降的妖魔是什么族吻? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任帽借,我火速辦了婚禮,結(jié)果婚禮上超歌,老公的妹妹穿的比我還像新娘砍艾。我一直安慰自己,他們只是感情好巍举,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布脆荷。 她就那樣靜靜地躺著,像睡著了一般懊悯。 火紅的嫁衣襯著肌膚如雪蜓谋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天炭分,我揣著相機(jī)與錄音赴肚,去河邊找鬼炸庞。 笑死带猴,一個(gè)胖子當(dāng)著我的面吹牛姑丑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播岖妄,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼型将,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼寂祥!你這毒婦竟也來了荐虐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤丸凭,失蹤者是張志新(化名)和其女友劉穎福扬,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惜犀,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡铛碑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了虽界。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汽烦。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖莉御,靈堂內(nèi)的尸體忽然破棺而出撇吞,到底是詐尸還是另有隱情俗冻,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布牍颈,位于F島的核電站迄薄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏煮岁。R本人自食惡果不足惜讥蔽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望画机。 院中可真熱鬧冶伞,春花似錦、人聲如沸步氏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽戳护。三九已至金抡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間腌且,已是汗流浹背梗肝。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铺董,地道東北人巫击。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像精续,于是被迫代替她去往敵國和親坝锰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355