OSHI:Java跨平台系統監控的神器,一行代碼搞定!

在現代軟件開發中,系統監控是一個不可或缺的環節。無論是開發大型企業級應用還是小型工具,瞭解系統的運行狀態、資源使用情況等信息都至關重要。Java作為一門廣泛使用的編程語言,提供了多種方式來獲取系統信息,但這些方法往往存在侷限性。例如,System.getProperty()只能獲取有限的操作系統信息,而Runtime.exec()需要依賴特定操作系統的命令。那麼,有沒有一種更簡單、更通用的方法呢?答案是肯定的,那就是OSHI(操作系統和硬件信息)。

文章目錄

  • OSHI:Java跨平台系統監控的神器,一行代碼搞定!
  • 一、OSHI簡介
  • 二、為什麼使用OSHI進行系統監控?
  • 三、在Java項目中設置OSHI
  • 四、獲取基本系統信息
  • 4.1 獲取操作系統詳細信息
  • 4.2 檢查系統正常運行時間
  • 五、使用OSHI進行CPU監控
  • 5.1 獲取處理器詳細信息
  • 5.2 動態測量CPU負載
  • 六、內存監控
  • 6.1 獲取總內存和可用內存
  • 6.2 存儲和磁盤信息
  • 七、OSHI的侷限性
  • 八、OSHI的能力
  • 九、結論

一、OSHI簡介

OSHI是一個純Java庫,它無需任何原生依賴,能夠以跨平台的方式提取有關操作系統、硬件和網絡的有用信息。它與大多數主流操作系統(Windows、macOS、Linux)兼容,提供關於CPU、內存、磁盤、傳感器和網絡的深度系統分析。由於完全基於Java,OSHI無需編寫本地代碼,輕量級且易於使用,只需添加一個依賴項即可。

二、為什麼使用OSHI進行系統監控?

與其他方法相比,OSHI具有以下優勢:

  • 跨平台兼容性:支持Windows、macOS、Linux等主流操作系統。
  • 無需原生代碼:完全基於Java,無需編寫或調用本地代碼。
  • 功能豐富:提供操作系統、CPU、內存、磁盤、網絡等多方面的詳細信息。
  • 易於集成:只需添加一個依賴項,即可在項目中使用。

三、在Java項目中設置OSHI

如果使用Maven構建項目,只需在pom.xml文件中添加以下依賴項:

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

添加完成後,即可開始使用OSHI。

四、獲取基本系統信息

4.1 獲取操作系統詳細信息

通過OSHI,可以輕鬆獲取操作系統的名稱、版本、架構等信息。以下是具體的代碼示例:

@Test
void givenSystem_whenUsingOSHI_thenExtractOSDetails() {
    SystemInfo si = new SystemInfo();
    OperatingSystem os = si.getOperatingSystem();

    assertNotNull(os, "Operating System object should not be null");
    assertNotNull(os.getFamily(), "OS Family should not be null");
    assertNotNull(os.getVersionInfo(), "OS Version info should not be null");
    assertTrue(os.getBitness() == 32 || os.getBitness() == 64, "OS Bitness should be 32 or 64");
}

這段代碼創建了一個SystemInfo對象,用於訪問系統相關詳細信息。然後,它檢索OperatingSystem實例,該實例提供操作系統系列、版本和位數等信息。

4.2 檢查系統正常運行時間

系統運行時間是指系統自上次啓動以來的運行時長。以下是獲取系統運行時間的代碼:

@Test
void givenSystem_whenUsingOSHI_thenExtractSystemUptime() {
    SystemInfo si = new SystemInfo();
    OperatingSystem os = si.getOperatingSystem();

    long uptime = os.getSystemUptime();
    assertTrue(uptime >= 0, "System uptime should be non-negative");
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        fail("Test interrupted");
    }
    long newUptime = os.getSystemUptime();
    assertTrue(newUptime >= uptime, "Uptime should increase over time");
}

該代碼使用OSHI獲取系統運行時間,首先檢查系統運行時間是否為非負值,然後暫停兩秒鐘,再次獲取系統運行時間,以驗證運行時間是否隨時間增加。

五、使用OSHI進行CPU監控

5.1 獲取處理器詳細信息

CPU是系統的核心部件,監控其使用情況、負載和核心數量對於性能調優至關重要。以下是獲取處理器詳細信息的代碼:

@Test
void givenSystem_whenUsingOSHI_thenExtractCPUDetails() {
    SystemInfo si = new SystemInfo();
    CentralProcessor processor = si.getHardware().getProcessor();

    assertNotNull(processor, "Processor object should not be null");
    assertTrue(processor.getPhysicalProcessorCount() > 0, "CPU must have at least one physical core");
    assertTrue(processor.getLogicalProcessorCount() >= processor.getPhysicalProcessorCount(),
      "Logical cores should be greater than or equal to physical cores");
}

此代碼從OSHI初始化一個SystemInfo對象,並從系統硬件中檢索CentralProcessor實例。CentralProcessor提供有關CPU的詳細信息,例如核心數、處理器標識符和負載指標。

5.2 動態測量CPU負載

如果想查看CPU在某一時刻的繁忙程度,可以使用以下代碼:

@Test
void givenSystem_whenUsingOSHI_thenExtractCPULoad() throws InterruptedException {
    SystemInfo si = new SystemInfo();
    CentralProcessor processor = si.getHardware().getProcessor();

    long[] prevTicks = processor.getSystemCpuLoadTicks();
    TimeUnit.SECONDS.sleep(1);
    double cpuLoad = processor.getSystemCpuLoadBetweenTicks(prevTicks) * 100;

    assertTrue(cpuLoad >= 0 && cpuLoad <= 100, "CPU load should be between 0% and 100%");
}

該代碼捕獲系統的CPU負載滴答(prevTicks),等待一秒鐘,並使用getSystemCpuLoadBetweenTicks(prevTicks) * 100計算記錄的滴答之間的CPU負載百分比。最後,它斷言CPU負載落在0%到100%的有效範圍內。

六、內存監控

6.1 獲取總內存和可用內存

系統的RAM決定了可以同時運行多少個應用程序。以下是獲取系統的總內存和可用內存的代碼:

@Test
void givenSystem_whenUsingOSHI_thenExtractMemoryDetails() {
    SystemInfo si = new SystemInfo();
    GlobalMemory memory = si.getHardware().getMemory();

    assertTrue(memory.getTotal() > 0, "Total memory should be positive");
    assertTrue(memory.getAvailable() >= 0, "Available memory should not be negative");
    assertTrue(memory.getAvailable() <= memory.getTotal(), "Available memory should not exceed total memory");
}

該代碼初始化一個SystemInfo對象並獲取GlobalMemory實例,該實例提供內存相關信息。它斷言總內存為正數,以確保系統擁有有效的RAM。它還檢查可用內存是否為非負數且不超過總內存。

6.2 存儲和磁盤信息

硬盤和固態硬盤存儲着我們所有的數據。OSHI可以幫助監控磁盤總空間、分區和使用情況統計信息。以下是獲取磁盤存儲詳細信息的代碼:

@Test
void givenSystem_whenUsingOSHI_thenExtractDiskDetails() {
    SystemInfo si = new SystemInfo();
    List<HWDiskStore> diskStores = si.getHardware().getDiskStores();

    assertFalse(diskStores.isEmpty(), "There should be at least one disk");

    for (HWDiskStore disk : diskStores) {
        assertNotNull(disk.getModel(), "Disk model should not be null");
        assertTrue(disk.getSize() >= 0, "Disk size should be non-negative");
    }
}

該代碼使用OSHI獲取磁盤存儲詳細信息。它獲取代表系統磁盤的HWDiskStore實例列表。它確保至少存在一個磁盤,然後遍歷每個磁盤,驗證型號名稱不為空且磁盤大小為非負數。

七、OSHI的侷限性

儘管OSHI功能豐富,但它也存在一些侷限性:

  • 傳感器數據的可用性取決於硬件支持:並非所有機器都會提供温度或電壓讀數。
  • 底層控制有限:OSHI提供只讀的系統信息,不允許修改系統。
  • 對系統API的依賴性:某些信息在不同的操作系統之間可能略有不同。

八、OSHI的能力

功能類別

功能描述

系統信息

操作系統名稱、版本、架構、運行時間、家族、位數;計算機系統信息、固件信息、主板信息

CPU信息

物理CPU核心數、邏輯CPU核心數、處理器組、NUMA節點、處理器名稱、速度、標識符、系統和每個處理器的負載、使用率滴答計數器、中斷次數、系統運行時間

進程信息

進程運行時間、CPU使用率、內存使用量、用户/組信息、命令行參數、線程詳細信息

內存信息

總物理內存、可用物理內存、已使用物理內存;總虛擬內存、可用虛擬內存、已使用虛擬內存、交換空間使用情況

磁盤信息

磁盤型號、序列號、大小、讀寫次數;掛載的文件系統(類型、可用空間、總空間、選項)、分區讀寫次數

網絡信息

IP地址、帶寬使用情況(上行/下行)、網絡參數、TCP/UDP統計信息

電池信息

電池容量百分比、剩餘時間、電源使用統計信息

USB設備

連接的USB設備信息

顯示器和硬件

連接的顯示器信息(包括EDID信息)、圖形和音頻卡信息

傳感器信息

温度(CPU温度等)、風扇轉速、電壓(如果硬件支持)

配置

支持通過oshi.properties文件或Java系統屬性進行配置

九、結論

OSHI是一個功能強大且輕量級的Java庫,用於檢索系統和硬件信息。它免去了處理本地系統命令、JNI或平台特定依賴項的麻煩,因此對於需要跨平台系統監控的開發人員來説,它是一個絕佳的選擇。通過本文介紹的功能,你可以輕鬆地在Java項目中集成OSHI,實現對系統信息的全面監控。

如果你對OSHI感興趣,或者在使用過程中遇到了問題,歡迎在評論區留言交流。讓我們一起探索更多Java開發的樂趣!