在Spring boot中使用OSHI

在Spring boot中使用OSHI

OSHI是什么
OSHI.是一个基于JNA的免费的本地操作系统和Java的硬件信息库。它不需要安装任何额外的本机库,旨在提供跨平台的实现来检索系统信息,如操作系统版本、进程、内存和CPU使用情况、磁盘和分区、设备、传感器等。(OSHI is a free JNA-based (native) Operating System and Hardware Information library for Java. It does not require the installation of any additional native libraries and aims to provide a cross-platform implementation to retrieve system information, such as OS version, processes, memory & CPU usage, disks & partitions, devices, sensors, etc.)

springboot添加依赖
1、oshi依赖

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

2、测试代码

package com.only3c.cpms;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import oshi.SystemInfo;
import oshi.hardware.*;
import oshi.hardware.CentralProcessor.TickType;
import oshi.software.os.*;
import oshi.software.os.OperatingSystem.ProcessSort;
import oshi.util.FormatUtil;
import oshi.util.Util;

import java.util.Arrays;
import java.util.List;

/**
 * The Class SystemInfoTest.
 *
 * @author dblock[at]dblock[dot]org
 */
public class SystemInfoTest {

	/**
	 * The main method.
	 *
	 * @param args the arguments
	 */
	public static void main(String[] args) {
		// Options: ERROR > WARN > INFO > DEBUG > TRACE
		Logger LOG = LoggerFactory.getLogger(SystemInfoTest.class);

		LOG.info("Initializing System...");
		SystemInfo si = new SystemInfo();

		HardwareAbstractionLayer hal = si.getHardware();
		OperatingSystem os = si.getOperatingSystem();

		System.out.println(os);

		LOG.info("Checking computer system...");
		printComputerSystem(hal.getComputerSystem());

		LOG.info("Checking Processor...");
		printProcessor(hal.getProcessor());

		LOG.info("Checking Memory...");
		printMemory(hal.getMemory());

		LOG.info("Checking CPU...");
		printCpu(hal.getProcessor());

		LOG.info("Checking Processes...");
		printProcesses(os, hal.getMemory());

		LOG.info("Checking Sensors...");
		printSensors(hal.getSensors());

		LOG.info("Checking Power sources...");
		printPowerSources(hal.getPowerSources());

		LOG.info("Checking Disks...");
		printDisks(hal.getDiskStores());

		LOG.info("Checking File System...");
		printFileSystem(os.getFileSystem());

		LOG.info("Checking Network interfaces...");
		printNetworkInterfaces(hal.getNetworkIFs());

		LOG.info("Checking Network parameterss...");
		printNetworkParameters(os.getNetworkParams());

		// hardware: displays
		LOG.info("Checking Displays...");
		printDisplays(hal.getDisplays());

		// hardware: USB devices
		LOG.info("Checking USB Devices...");
		printUsbDevices(hal.getUsbDevices(true));
	}

	private static void printComputerSystem(final ComputerSystem computerSystem) {

		System.out.println("manufacturer: " + computerSystem.getManufacturer());
		System.out.println("model: " + computerSystem.getModel());
		System.out.println("serialnumber: " + computerSystem.getSerialNumber());
		final Firmware firmware = computerSystem.getFirmware();
		System.out.println("firmware:");
		System.out.println("  manufacturer: " + firmware.getManufacturer());
		System.out.println("  name: " + firmware.getName());
		System.out.println("  description: " + firmware.getDescription());
		System.out.println("  version: " + firmware.getVersion());
//		System.out.println("  release date: " + (firmware.getReleaseDate() == null ? "unknown": firmware.getReleaseDate() == null ? "unknown" : FormatUtil.formatDate(firmware.getReleaseDate())));
		final Baseboard baseboard = computerSystem.getBaseboard();
		System.out.println("baseboard:");
		System.out.println("  manufacturer: " + baseboard.getManufacturer());
		System.out.println("  model: " + baseboard.getModel());
		System.out.println("  version: " + baseboard.getVersion());
		System.out.println("  serialnumber: " + baseboard.getSerialNumber());
	}

	private static void printProcessor(CentralProcessor processor) {
		System.out.println(processor);
		System.out.println(" " + processor.getPhysicalPackageCount() + " physical CPU package(s)");
		System.out.println(" " + processor.getPhysicalProcessorCount() + " physical CPU core(s)");
		System.out.println(" " + processor.getLogicalProcessorCount() + " logical CPU(s)");

		System.out.println("Identifier: " + processor.getIdentifier());
		System.out.println("ProcessorID: " + processor.getProcessorID());
	}

	private static void printMemory(GlobalMemory memory) {
		System.out.println("Memory: " + FormatUtil.formatBytes(memory.getAvailable()) + "/"
				+ FormatUtil.formatBytes(memory.getTotal()));
		System.out.println("Swap used: " + FormatUtil.formatBytes(memory.getSwapUsed()) + "/"
				+ FormatUtil.formatBytes(memory.getSwapTotal()));
	}

	private static void printCpu(CentralProcessor processor) {
		System.out.println("Uptime: " + FormatUtil.formatElapsedSecs(processor.getSystemUptime()));
		System.out.println(
				"Context Switches/Interrupts: " + processor.getContextSwitches() + " / " + processor.getInterrupts());

		long[] prevTicks = processor.getSystemCpuLoadTicks();
		System.out.println("CPU, IOWait, and IRQ ticks @ 0 sec:" + Arrays.toString(prevTicks));
		// Wait a second...
		Util.sleep(1000);
		long[] ticks = processor.getSystemCpuLoadTicks();
		System.out.println("CPU, IOWait, and IRQ ticks @ 1 sec:" + Arrays.toString(ticks));
		long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
		long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
		long sys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
		long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
		long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.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 totalCpu = user + nice + sys + idle + iowait + irq + softirq + steal;

		System.out.format(
				"User: %.1f%% Nice: %.1f%% System: %.1f%% Idle: %.1f%% IOwait: %.1f%% IRQ: %.1f%% SoftIRQ: %.1f%% Steal: %.1f%%%n",
				100d * user / totalCpu, 100d * nice / totalCpu, 100d * sys / totalCpu, 100d * idle / totalCpu,
				100d * iowait / totalCpu, 100d * irq / totalCpu, 100d * softirq / totalCpu, 100d * steal / totalCpu);
		System.out.format("CPU load: %.1f%% (counting ticks)%n", processor.getSystemCpuLoadBetweenTicks() * 100);
		System.out.format("CPU load: %.1f%% (OS MXBean)%n", processor.getSystemCpuLoad() * 100);
		double[] loadAverage = processor.getSystemLoadAverage(3);
		System.out.println("CPU load averages:" + (loadAverage[0] < 0 ? " N/A" : String.format(" %.2f", loadAverage[0]))
				+ (loadAverage[1] < 0 ? " N/A" : String.format(" %.2f", loadAverage[1]))
				+ (loadAverage[2] < 0 ? " N/A" : String.format(" %.2f", loadAverage[2])));
		// per core CPU
		StringBuilder procCpu = new StringBuilder("CPU load per processor:");
		double[] load = processor.getProcessorCpuLoadBetweenTicks();
		for (double avg : load) {
			procCpu.append(String.format(" %.1f%%", avg * 100));
		}
		System.out.println(procCpu.toString());
	}

	private static void printProcesses(OperatingSystem os, GlobalMemory memory) {
		System.out.println("Processes: " + os.getProcessCount() + ", Threads: " + os.getThreadCount());
		// Sort by highest CPU
		List<OSProcess> procs = Arrays.asList(os.getProcesses(5, ProcessSort.CPU));

		System.out.println("   PID  %CPU %MEM       VSZ       RSS Name");
		for (int i = 0; i < procs.size() && i < 5; i++) {
			OSProcess p = procs.get(i);
			System.out.format(" %5d %5.1f %4.1f %9s %9s %s%n", p.getProcessID(),
					100d * (p.getKernelTime() + p.getUserTime()) / p.getUpTime(),
					100d * p.getResidentSetSize() / memory.getTotal(), FormatUtil.formatBytes(p.getVirtualSize()),
					FormatUtil.formatBytes(p.getResidentSetSize()), p.getName());
		}
	}

	private static void printSensors(Sensors sensors) {
		System.out.println("Sensors:");
		System.out.format(" CPU Temperature: %.1f°C%n", sensors.getCpuTemperature());
		System.out.println(" Fan Speeds: " + Arrays.toString(sensors.getFanSpeeds()));
		System.out.format(" CPU Voltage: %.1fV%n", sensors.getCpuVoltage());
	}

	private static void printPowerSources(PowerSource[] powerSources) {
		StringBuilder sb = new StringBuilder("Power: ");
		if (powerSources.length == 0) {
			sb.append("Unknown");
		} else {
			double timeRemaining = powerSources[0].getTimeRemaining();
			if (timeRemaining < -1d) {
				sb.append("Charging");
			} else if (timeRemaining < 0d) {
				sb.append("Calculating time remaining");
			} else {
				sb.append(String.format("%d:%02d remaining", (int) (timeRemaining / 3600),
						(int) (timeRemaining / 60) % 60));
			}
		}
		for (PowerSource pSource : powerSources) {
			sb.append(String.format("%n %s @ %.1f%%", pSource.getName(), pSource.getRemainingCapacity() * 100d));
		}
		System.out.println(sb.toString());
	}

	private static void printDisks(HWDiskStore[] diskStores) {
		System.out.println("Disks:");
		for (HWDiskStore disk : diskStores) {
			boolean readwrite = disk.getReads() > 0 || disk.getWrites() > 0;
			System.out.format(" %s: (model: %s - S/N: %s) size: %s, reads: %s (%s), writes: %s (%s), xfer: %s ms%n",
					disk.getName(), disk.getModel(), disk.getSerial(),
					disk.getSize() > 0 ? FormatUtil.formatBytesDecimal(disk.getSize()) : "?",
					readwrite ? disk.getReads() : "?", readwrite ? FormatUtil.formatBytes(disk.getReadBytes()) : "?",
					readwrite ? disk.getWrites() : "?", readwrite ? FormatUtil.formatBytes(disk.getWriteBytes()) : "?",
					readwrite ? disk.getTransferTime() : "?");
			HWPartition[] partitions = disk.getPartitions();
			if (partitions == null) {
				// TODO Remove when all OS's implemented
				continue;
			}
			for (HWPartition part : partitions) {
				System.out.format(" |-- %s: %s (%s) Maj:Min=%d:%d, size: %s%s%n", part.getIdentification(),
						part.getName(), part.getType(), part.getMajor(), part.getMinor(),
						FormatUtil.formatBytesDecimal(part.getSize()),
						part.getMountPoint().isEmpty() ? "" : " @ " + part.getMountPoint());
			}
		}
	}

	private static void printFileSystem(FileSystem fileSystem) {
		System.out.println("File System:");

		System.out.format(" File Descriptors: %d/%d%n", fileSystem.getOpenFileDescriptors(),
				fileSystem.getMaxFileDescriptors());

		OSFileStore[] fsArray = fileSystem.getFileStores();
		for (OSFileStore fs : fsArray) {
			long usable = fs.getUsableSpace();
			long total = fs.getTotalSpace();
			System.out.format(
					" %s (%s) [%s] %s of %s free (%.1f%%) is %s "
							+ (fs.getLogicalVolume() != null && fs.getLogicalVolume().length() > 0 ? "[%s]" : "%s")
							+ " and is mounted at %s%n",
					fs.getName(), fs.getDescription().isEmpty() ? "file system" : fs.getDescription(), fs.getType(),
					FormatUtil.formatBytes(usable), FormatUtil.formatBytes(fs.getTotalSpace()), 100d * usable / total,
					fs.getVolume(), fs.getLogicalVolume(), fs.getMount());
		}
	}

	private static void printNetworkInterfaces(NetworkIF[] networkIFs) {
		System.out.println("Network interfaces:");
		for (NetworkIF net : networkIFs) {
			System.out.format(" Name: %s (%s)%n", net.getName(), net.getDisplayName());
			System.out.format("   MAC Address: %s %n", net.getMacaddr());
			System.out.format("   MTU: %s, Speed: %s %n", net.getMTU(), FormatUtil.formatValue(net.getSpeed(), "bps"));
			System.out.format("   IPv4: %s %n", Arrays.toString(net.getIPv4addr()));
			System.out.format("   IPv6: %s %n", Arrays.toString(net.getIPv6addr()));
			boolean hasData = net.getBytesRecv() > 0 || net.getBytesSent() > 0 || net.getPacketsRecv() > 0
					|| net.getPacketsSent() > 0;
			System.out.format("   Traffic: received %s/%s%s; transmitted %s/%s%s %n",
					hasData ? net.getPacketsRecv() + " packets" : "?",
					hasData ? FormatUtil.formatBytes(net.getBytesRecv()) : "?",
					hasData ? " (" + net.getInErrors() + " err)" : "",
					hasData ? net.getPacketsSent() + " packets" : "?",
					hasData ? FormatUtil.formatBytes(net.getBytesSent()) : "?",
					hasData ? " (" + net.getOutErrors() + " err)" : "");
		}
	}

	private static void printNetworkParameters(NetworkParams networkParams) {
		System.out.println("Network parameters:");
		System.out.format(" Host name: %s%n", networkParams.getHostName());
		System.out.format(" Domain name: %s%n", networkParams.getDomainName());
		System.out.format(" DNS servers: %s%n", Arrays.toString(networkParams.getDnsServers()));
		System.out.format(" IPv4 Gateway: %s%n", networkParams.getIpv4DefaultGateway());
		System.out.format(" IPv6 Gateway: %s%n", networkParams.getIpv6DefaultGateway());
	}

	private static void printDisplays(Display[] displays) {
		System.out.println("Displays:");
		int i = 0;
		for (Display display : displays) {
			System.out.println(" Display " + i + ":");
			System.out.println(display.toString());
			i++;
		}
	}

	private static void printUsbDevices(UsbDevice[] usbDevices) {
		System.out.println("USB Devices:");
		for (UsbDevice usbDevice : usbDevices) {
			System.out.println(usbDevice.toString());
		}
	}
}

代码出处:> oshi/SystemInfoTest.java at master · oshi/oshi · GitHub

遇坑

win10 家庭版系统测试运行时 SystemInfo的hardware及os都是null 导致曝出了以下错误:

Exception in thread "main" java.lang.NoSuchMethodError:
com.sun.jna.platform.win32.OleAuto.VariantClear(Lcom/sun/jna/platform/win32/Variant$VARIANT;)Lcom/sun/jna/platform/win32/WinNT$HRESULT;

根据此错误查遍各大网站 大多数答案包括两个问题:
1、需要继续增加依赖jna,jna-platform,slf4j-api 三个jar包
2、oshi和jna的版本不匹配
解决方案是:oshi3.4以上版本余姚匹配jna4.4.0版本

以上2问题可能会解决非springboot用户的问题。 因为boot本身自带了jna和slf4j 

***当部署在centos7虚拟机里的时候 再次测试时 成功的返回了所有的数据

结论1:springboot中只需添加oshi依赖(其余已经封装进去),可根据springboot版本内置jna的版本再确定oshi的版本。win10家庭版不支持oshi。

(最近给win安装docker 家庭版就不支持,所以安装在了虚拟机,
又同样配置的oshi在虚拟机中正常使用,所以一个错误的想法就此萌生,
耽误了一个程序员一上午的时间。shitfuckcao)

结论2:结论1是错的。还是版本的问题 因为centos7中正常使用 所以导致查找问题的方向有误
···在springboot1.5中默认JNA的版本是4.2.2,而我用的oshi版本是3.9.1
···解决办法是:用JNA4.5.2 替换了springboot1.5中默认的4.2.2 win10也正常使用了。


原文:springboot-OSHI_only3c的博客-CSDN博客_springboot oshi