最近在做一个主机资源监控的需求,首先是获取一些最简单的基本参,像一些主机名称、系统类型、ip、cpu、内存和磁盘等等这些数据,看起来虽然很简单,Java的基本库就能完成,但是真的去使用的时候,还是有一些坑的。记录一下,已备后用。
目录
Java获取主机信息
1. 获取基本信息
1.1 获取主机名称和系统
1.2 获取用户信息
1.3 获取主机IP等信息
2. 获取CPU信息
2.1 获取CPU核数
2.2 获取CPU使用率
3. 获取内存信息
3.1 获取主机内存
3.2 获取JVM内存
4. 获取磁盘信息
5. 获取Java环境信息
Java获取主机信息 1. 获取基本信息 1.1 获取主机名称和系统主机名称可以通过网络类InetAddress来获取,主机系统和用户可以通过System类进行获取。
public static void getLocalHost(){ try{ InetAddress ip = InetAddress.getLocalHost(); String localName = ip.getHostName(); String osName = System.getProperty("os.name"); String userName = System.getProperty("user.name"); String osVersion = System.getProperty("os.version"); String osArch = System.getProperty("os.arch"); System.out.println("当前用户:" + userName); System.out.println("用户的主目录:"+props.getProperty("user.home")); System.out.println("用户的当前工作目录:"+props.getProperty("user.dir")); System.out.println("主机名称:" + localName); System.out.println("主机系统:" + osName); System.out.println("系统版本:" + osVersion); System.out.println("系统架构:" + osArch); } catch (Exception e) { e.printStackTrace(); }} 1.2 获取用户信息用户信息都是使用System类进行获取。
public static void getUserInfo(){ try{ String userName = System.getProperty("user.name"); String userHome = System.getProperty("user.home"); String userDir = System.getProperty("user.dir"); System.out.println("当前用户:" + userName); System.out.println("用户主目录:"+ userHome); System.out.println("当前工作目录:"+ userDir); } catch (Exception e) { e.printStackTrace(); } } 1.3 获取主机IP等信息主机的ip可以通过网络类InetAddress进行获取,但是这个方法很玄学,机器上多网卡还有虚拟机时,获取到就不准确了。目前做的获取的方法是痛殴便利网卡来获取ip。因为遍历网卡来获取ip要过滤一些不重要的网卡,过滤的方法是来自“经验”的笨方法,可以借鉴,但不保证日后网卡条件复杂的情况下获取不准确。测试的是Linux、Mac和Windows系统可用。因为过滤条件不一样,所以分为Windows获取和非Windows获取。
Windows系统获取IP:
public static void getWindowsIpAndMac(){ try { Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces(); // 遍历网卡接口 while (allNetInterfaces.hasMoreElements()) { NetworkInterface netInterface = allNetInterfaces.nextElement(); // 去除回环接口,子接口,未运行和接口 if (netInterface.isLoopback() || netInterface.isVirtual() || !netInterface.isUp()) { continue; } // 重点来了:“经验”之谈 // 为了过滤掉虚拟机的网卡,可以通过网卡名来进行基础过滤。windows主机ip对应的网卡名会包含下面三个:Intel 无线、Realtek 网线、Ethernet 兼容xp系统 if (!netInterface.getDisplayName().contains("Intel") && !netInterface.getDisplayName().contains("Realtek") && !netInterface.getDisplayName().contains("Ethernet")) { continue; } String ip = ""; String mac = ""; String niName = ""; Enumeration addresses = netInterface.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress ia = addresses.nextElement(); // 去除本地回环地址,子接口,未运行和地址 if (ia != null && !ia.isLoopbackAddress() && ia.isSiteLocalAddress() && !ia.isAnyLocalAddress()) { // 判断是否是ip v4地址 if (ia instanceof Inet4Address) { ip = ia.getHostAddress(); // 获取MAC地址 mac = getMac(ia); niName = netInterface.getName(); if (StringUtils.isNotBlank(ip) && StringUtils.isNotBlank(mac) && StringUtils.isNotBlank(niName)){ System.out.println("当前网卡:"+niName); System.out.println("当前主机ip:"+ip); System.out.println("当前主机MAC:"+mac); return; } } } } } } catch (SocketException e) { e.printStackTrace(); } }非Windows系统获取IP:
其实和windows获取的差不多,也是遍历网卡然后进行过滤,不过这个没有“经验”,不知道要过滤那些,所以用InetAddress进行获取,经测试这个在非windows上获取的还是准确的(可能我linux网卡单一)。不过为了获取当前的网卡用了一个更笨的方法,既然当前获取的ip是准确的,那就根据ip去获取网卡。不过目前没有找到这个方法,所以可以在遍历网卡时取出符合当前ip的网卡。(此方法在我这个需求里是可以的,不保证拿走就能用)。
public static void getLinuxIpAndMac(AgentMonitor agentMonitor){ try { // 先获取ip InetAddress iad = InetAddress.getLocalHost(); String localIp = iad.getHostAddress(); // 遍历网卡 Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces(); while (allNetInterfaces.hasMoreElements()) { NetworkInterface netInterface = allNetInterfaces.nextElement(); // 去除回环接口,子接口,未运行和接口 if (netInterface.isLoopback() || netInterface.isVirtual() || !netInterface.isUp()) { continue; } String ip = ""; String mac = ""; String niName = ""; Enumeration addresses = netInterface.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress ia = addresses.nextElement(); if (ia != null && !ia.isLoopbackAddress() && ia.isSiteLocalAddress() && !ia.isAnyLocalAddress()) { // 判断是否是ip v4地址且是否和已获取的ip一致 if (ia instanceof Inet4Address && ia.getHostAddress().equals(localIp)) { ip = ia.getHostAddress(); // 获取MAC地址 mac = getMac(ia); niName = netInterface.getName(); if (StringUtils.isNotBlank(ip) && StringUtils.isNotBlank(mac) && StringUtils.isNotBlank(niName)){ System.out.println("当前网卡:"+niName); System.out.println("当前主机ip:"+ip); System.out.println("当前主机MAC:"+mac); return; } } } } } } catch (Exception e) { e.printStackTrace(); } }获取MAC地址
public static String getMac(InetAddress ia){ try { //获取网卡,获取地址 byte[] mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress(); StringBuffer sb = new StringBuffer(); if (mac != null && mac.length>0){ for(int i=0; i