Java 服务监控
效果
pom 添加依赖:
<!-- 获取系统信息 -->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>5.7.5</version>
</dependency>
<!-- 访问系统本地库 -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.8.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.8.0</version>
</dependency>
oshi-core API
对象 | 方法 | 描述 |
SystemInfo | getOperatingSystem() | 获取操作系统信息,OperatingSystem |
getHardware() | 获取硬件信息,HardwareAbstractionLayer | |
OperatingSystem | getFamily() | 获取操作系统名称,例如 Windows |
getManufacturer() | 获取供货商,例如 Microsoft | |
getVersion() | 获取操作系统版本信息 | |
getFileSystem() | 获取系统硬盘信息,FileSystem | |
getProcesses(int pId, OperatingSystem.ProcessSort var2) | 通过 进程id 获取进程信息,并设置排序方式,OSProcess[] | |
getProcess(int pId) | 通过 进程id 获取一个进程信息,OSProcess | |
getProcesses(Collection<Integer> pId) | 获取多个进程信息,List<OSProcess> | |
getChildProcesses(int var1, int var2, OperatingSystem.ProcessSort var3) | 获取子进程,OSProcess[] | |
getProcessId() | 获取进程id | |
getProcessCount() | 获取进程数量 | |
getThreadCount() | 获取线程数 | |
getNetworkParams() | 获取网络相关参数,NetworkParams | |
HardwareAbstractionLayer | getComputerSystem() | 获取计算机系统信息,ComputerSystem |
getProcessor() | 获取处理器信息,CentralProcessor | |
getMemory() | 获取内存信息,GlobalMemory | |
getPowerSources() | 获取电源信息,PowerSource | |
getDiskStores() | 获取硬件磁盘信息,HWDiskStore | |
getNetworkIFs() | 获取网络信息,NetworkIF | |
getDisplays() | 获取显示信息,Display | |
getSensors() | 获取传感器信息,Sensors | |
getUsbDevices(boolean var1) | 获取USB设备信息,UsbDevice | |
OperatingSystemVersion | getBuildNumber() | 获取内部编号 |
getCodeName() | 代码名称 | |
getVersion() | 获取版本 | |
FileSystem | getMaxFileDescriptors() | 获取最大文件描述符 |
getOpenFileDescriptors() | 获取打开文件描述符 | |
getFileStores() | 获取盘符相关信息 | |
OSProcess | getName() | 进程程序名称 |
getPath() | 进程程序所在位置 | |
getCommandLine() | 获取命令行 | |
getCurrentWorkingDirectory() | 获取当前工作目录 | |
getUser() | 获取用户信息 | |
getUserID() | 获取用户id | |
getGroup() | 获取组信息 | |
getGroupID() | 获取组id | |
getState() | 状态 | |
getProcessID() | 获取进程id | |
getParentProcessID() | 获取父进程id | |
getThreadCount() | 获取线程数 | |
getPriority() | 优先级 | |
getVirtualSize() | 虚拟大小 | |
getResidentSetSize() | 实际使用物理内存 | |
getKernelTime() | 内核时间 | |
getUserTime() | 用户时间 | |
getUpTime() | 正常运行时间 | |
getStartTime() | 开始时间 | |
getBytesRead() | 读取字节 | |
getBytesWritten() | 写入字节 | |
getOpenFiles() | 打开文件数量 | |
NetworkParams | getDnsServers() | 获取域名地址 |
getHostName() | 获取主机名 | |
getDomainName() | 获取域名 | |
getIpv4DefaultGateway() | 获取默认Ipv4 | |
getIpv6DefaultGateway() | 获取默认Ipv6 | |
OSFileStore | getName() | 磁盘名称 |
getVolume() | 文件集 | |
getLogicalVolume() | 合理的文件集 | |
getMount() | 盘符 | |
getDescription() | 描述 | |
getType() | 类型 | |
getUUID() | 磁盘UUID | |
getUsableSpace() | 可用空间 | |
getTotalSpace() | 总空间 | |
ComputerSystem | getManufacturer() | 获取制造商 |
getModel() | 获取型号 | |
getSerialNumber() | 获取序列号 | |
getFirmware() | 获取固件信息,Firmware | |
getBaseboard() | 获取外壳信息,Baseboard | |
Firmware | getManufacturer() | 获取制造商信息 |
getName() | 获取名称 | |
getDescription() | 获取描述信息 | |
getVersion() | 获取版本 | |
getReleaseDate() | 获取发布时间 | |
Baseboard | getManufacturer() | 获取制造商信息 |
getModel() | 获取型号 | |
getVersion() | 获取版本信息 | |
getSerialNumber() | 获取序列号 | |
CentralProcessor | getVendor() | 获取供应商 |
getName() | 获取cpu名称 | |
getVendorFreq() | 获取供应商频率 | |
getProcessorID() | 获取处理器id | |
getIdentifier() | 获取标识符 | |
isCpu64bit() | 判断cpu是否为64位的 | |
getStepping() | 获取cpu步进 | |
getModel() | 获取型号 | |
getFamily() | 获取家族 | |
getSystemCpuLoadBetweenTicks() | 获取cpu负载间隔刻度 | |
getSystemCpuLoadTicks() | 获取cpu负载刻度 | |
getSystemCpuLoad() | 获取cpu负载 | |
getSystemLoadAverage() | 获取cpu平均负载 | |
getSystemLoadAverage(int var1) | 获取cpu平均负载 | |
getProcessorCpuLoadBetweenTicks() | 获取处理器cpu负载间隔刻度 | |
getProcessorCpuLoadTicks() | 获取处理器cpu负载刻度 | |
getSystemUptime() | 获取正常运行时间 | |
getLogicalProcessorCount() | 获取逻辑处理器数量 | |
getPhysicalProcessorCount() | 获取物理处理器数量 | |
getPhysicalPackageCount() | 获取物理包装数量 | |
getContextSwitches() | 获取上下文切换数量 | |
getInterrupts() | 获取中断 | |
GlobalMemory | getTotal() | 获取总内存 |
getAvailable() | 获取可用系统运行内存 | |
getSwapTotal() | 获取可用虚拟总内存 | |
getSwapUsed() | 获取已用虚拟总内存 | |
PowerSource | getName() | 获取名称 |
getRemainingCapacity() | 获取剩余容量 | |
getTimeRemaining() | 获取剩余时间 | |
HWDiskStore | getName() | 获取名称 |
getModel() | 获取型号 | |
getSerial() | 获取序列号 | |
getSize() | 获取大小 | |
getReads() | (读长)是高通量测序中一个反应获得的测序序列 | |
getReadBytes() | 读取字节 | |
getWrites() | 写长 | |
getWriteBytes() | 写入字节 | |
getTransferTime() | 获取转移时间 | |
getPartitions() | 获取分区,HWPartition | |
getTimeStamp() | 获取时间戳 | |
NetworkIF | getName() | 获取名称 |
getDisplayName() | 获取显示名称 | |
getMTU() | 获取最大传输单元 | |
getMacaddr() | 获取MAC地址 | |
getIPv4addr() | 获取IPv4 | |
getIPv6addr() | 获取IPv6 | |
getBytesRecv() | 获取接收字节数 | |
getBytesSent() | 获取发送字节数 | |
getPacketsRecv() | 获取接收数据包 | |
getPacketsSent() | 获取发送数据包 | |
getInErrors() | 是否可达,正常 0 | |
getOutErrors() | 响应错误,无错误 0 | |
getSpeed() | 获取速率 | |
getTimeStamp() | 获取时间错 | |
Display | getEdid() | 中文名称扩展显示器识别数据 |
Sensors | getCpuTemperature() | 获取CPU温度 |
getFanSpeeds() | 获取风扇速度 | |
getCpuVoltage() | 获取CPU电压 | |
UsbDevice | getName() | 获取名称 |
getVendor() | 获取供应商 | |
getVendorId() | 获取供应商id | |
getProductId() | 获取商品id | |
getSerialNumber() | 获取序列号 | |
getConnectedDevices() | 获取连接设备 |
CPU 相关
package com.example.demo.module.domain.entity;
import com.example.demo.common.utils.Arith;
/**
* CPU相关信息
*/
public class Cpu
{
/**
* 核心数
*/
private int cpuNum;
/**
* CPU总的使用率
*/
private double total;
/**
* CPU系统使用率
*/
private double sys;
/**
* CPU用户使用率
*/
private double used;
/**
* CPU当前等待率
*/
private double wait;
/**
* CPU当前空闲率
*/
private double free;
public int getCpuNum()
{
return cpuNum;
}
public void setCpuNum(int cpuNum)
{
this.cpuNum = cpuNum;
}
public double getTotal()
{
return Arith.round(Arith.mul(total, 100), 2);
}
public void setTotal(double total)
{
this.total = total;
}
public double getSys()
{
return Arith.round(Arith.mul(sys / total, 100), 2);
}
public void setSys(double sys)
{
this.sys = sys;
}
public double getUsed()
{
return Arith.round(Arith.mul(used / total, 100), 2);
}
public void setUsed(double used)
{
this.used = used;
}
public double getWait()
{
return Arith.round(Arith.mul(wait / total, 100), 2);
}
public void setWait(double wait)
{
this.wait = wait;
}
public double getFree()
{
return Arith.round(Arith.mul(free / total, 100), 2);
}
public void setFree(double free)
{
this.free = free;
}
}
JVM 相关
package com.example.demo.module.domain.entity;
import com.example.demo.common.utils.Arith;
import com.example.demo.common.utils.DateUtils;
import java.lang.management.ManagementFactory;
/**
* JVM相关信息
*/
public class Jvm
{
/**
* 当前JVM占用的内存总数(M)
*/
private double total;
/**
* JVM最大可用内存总数(M)
*/
private double max;
/**
* JVM空闲内存(M)
*/
private double free;
/**
* JDK版本
*/
private String version;
/**
* JDK路径
*/
private String home;
public double getTotal()
{
return Arith.div(total, (1024 * 1024), 2);
}
public void setTotal(double total)
{
this.total = total;
}
public double getMax()
{
return Arith.div(max, (1024 * 1024), 2);
}
public void setMax(double max)
{
this.max = max;
}
public double getFree()
{
return Arith.div(free, (1024 * 1024), 2);
}
public void setFree(double free)
{
this.free = free;
}
public double getUsed()
{
return Arith.div(total - free, (1024 * 1024), 2);
}
public double getUsage()
{
return Arith.mul(Arith.div(total - free, total, 4), 100);
}
/**
* 获取JDK名称
*/
public String getName()
{
return ManagementFactory.getRuntimeMXBean().getVmName();
}
public String getVersion()
{
return version;
}
public void setVersion(String version)
{
this.version = version;
}
public String getHome()
{
return home;
}
public void setHome(String home)
{
this.home = home;
}
/**
* JDK启动时间
*/
public String getStartTime()
{
return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate());
}
/**
* JDK运行时间
*/
public String getRunTime()
{
return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate());
}
}
内存相关 MEN
package com.example.demo.module.domain.entity;
import com.example.demo.common.utils.Arith;
/**
* 內存相关信息
*/
public class Mem
{
/**
* 内存总量
*/
private double total;
/**
* 已用内存
*/
private double used;
/**
* 剩余内存
*/
private double free;
public double getTotal()
{
return Arith.div(total, (1024 * 1024 * 1024), 2);
}
public void setTotal(long total)
{
this.total = total;
}
public double getUsed()
{
return Arith.div(used, (1024 * 1024 * 1024), 2);
}
public void setUsed(long used)
{
this.used = used;
}
public double getFree()
{
return Arith.div(free, (1024 * 1024 * 1024), 2);
}
public void setFree(long free)
{
this.free = free;
}
public double getUsage()
{
return Arith.mul(Arith.div(used, total, 4), 100);
}
}
系统相关
package com.example.demo.module.domain.entity;
/**
* 系统相关信息
*/
public class Sys
{
/**
* 服务器名称
*/
private String computerName;
/**
* 服务器Ip
*/
private String computerIp;
/**
* 项目路径
*/
private String userDir;
/**
* 操作系统
*/
private String osName;
/**
* 系统架构
*/
private String osArch;
public String getComputerName()
{
return computerName;
}
public void setComputerName(String computerName)
{
this.computerName = computerName;
}
public String getComputerIp()
{
return computerIp;
}
public void setComputerIp(String computerIp)
{
this.computerIp = computerIp;
}
public String getUserDir()
{
return userDir;
}
public void setUserDir(String userDir)
{
this.userDir = userDir;
}
public String getOsName()
{
return osName;
}
public void setOsName(String osName)
{
this.osName = osName;
}
public String getOsArch()
{
return osArch;
}
public void setOsArch(String osArch)
{
this.osArch = osArch;
}
}
系统文件相关
package com.example.demo.module.domain.entity;
/**
* 系统文件相关信息
*/
public class SysFile
{
/**
* 盘符路径
*/
private String dirName;
/**
* 盘符类型
*/
private String sysTypeName;
/**
* 文件类型
*/
private String typeName;
/**
* 总大小
*/
private String total;
/**
* 剩余大小
*/
private String free;
/**
* 已经使用量
*/
private String used;
/**
* 资源的使用率
*/
private double usage;
public String getDirName()
{
return dirName;
}
public void setDirName(String dirName)
{
this.dirName = dirName;
}
public String getSysTypeName()
{
return sysTypeName;
}
public void setSysTypeName(String sysTypeName)
{
this.sysTypeName = sysTypeName;
}
public String getTypeName()
{
return typeName;
}
public void setTypeName(String typeName)
{
this.typeName = typeName;
}
public String getTotal()
{
return total;
}
public void setTotal(String total)
{
this.total = total;
}
public String getFree()
{
return free;
}
public void setFree(String free)
{
this.free = free;
}
public String getUsed()
{
return used;
}
public void setUsed(String used)
{
this.used = used;
}
public double getUsage()
{
return usage;
}
public void setUsage(double usage)
{
this.usage = usage;
}
}
服务器相关
package com.example.demo.module.domain.entity;
import com.example.demo.common.utils.Arith;
import com.example.demo.common.utils.IpUtils;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.CentralProcessor.TickType;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import oshi.util.Util;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
/**
* 服务器相关信息
*/
public class Server
{
private static final int OSHI_WAIT_SECOND = 1000;
/**
* CPU相关信息
*/
private Cpu cpu = new Cpu();
/**
* 內存相关信息
*/
private Mem mem = new Mem();
/**
* JVM相关信息
*/
private Jvm jvm = new Jvm();
/**
* 服务器相关信息
*/
private Sys sys = new Sys();
/**
* 磁盘相关信息
*/
private List<SysFile> sysFiles = new LinkedList<SysFile>();
public Cpu getCpu()
{
return cpu;
}
public void setCpu(Cpu cpu)
{
this.cpu = cpu;
}
public Mem getMem()
{
return mem;
}
public void setMem(Mem mem)
{
this.mem = mem;
}
public Jvm getJvm()
{
return jvm;
}
public void setJvm(Jvm jvm)
{
this.jvm = jvm;
}
public Sys getSys()
{
return sys;
}
public void setSys(Sys sys)
{
this.sys = sys;
}
public List<SysFile> getSysFiles()
{
return sysFiles;
}
public void setSysFiles(List<SysFile> sysFiles)
{
this.sysFiles = sysFiles;
}
public void copyTo() throws Exception
{
SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();
setCpuInfo(hal.getProcessor());
setMemInfo(hal.getMemory());
setSysInfo();
setJvmInfo();
setSysFiles(si.getOperatingSystem());
}
/**
* 设置CPU信息
*/
private void setCpuInfo(CentralProcessor processor)
{
// CPU信息
long[] prevTicks = processor.getSystemCpuLoadTicks();
Util.sleep(OSHI_WAIT_SECOND);
long[] ticks = processor.getSystemCpuLoadTicks();
long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.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 cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
cpu.setCpuNum(processor.getLogicalProcessorCount());
cpu.setTotal(totalCpu);
cpu.setSys(cSys);
cpu.setUsed(user);
cpu.setWait(iowait);
cpu.setFree(idle);
}
/**
* 设置内存信息
*/
private void setMemInfo(GlobalMemory memory)
{
mem.setTotal(memory.getTotal());
mem.setUsed(memory.getTotal() - memory.getAvailable());
mem.setFree(memory.getAvailable());
}
/**
* 设置服务器信息
*/
private void setSysInfo()
{
Properties props = System.getProperties();
sys.setComputerName(IpUtils.getHostName());
sys.setComputerIp(IpUtils.getHostIp());
sys.setOsName(props.getProperty("os.name"));
sys.setOsArch(props.getProperty("os.arch"));
sys.setUserDir(props.getProperty("user.dir"));
}
/**
* 设置Java虚拟机
*/
private void setJvmInfo() throws UnknownHostException
{
Properties props = System.getProperties();
jvm.setTotal(Runtime.getRuntime().totalMemory());
jvm.setMax(Runtime.getRuntime().maxMemory());
jvm.setFree(Runtime.getRuntime().freeMemory());
jvm.setVersion(props.getProperty("java.version"));
jvm.setHome(props.getProperty("java.home"));
}
/**
* 设置磁盘信息
*/
private void setSysFiles(OperatingSystem os)
{
FileSystem fileSystem = os.getFileSystem();
List<OSFileStore> fsArray = fileSystem.getFileStores();
for (OSFileStore fs : fsArray)
{
long free = fs.getUsableSpace();
long total = fs.getTotalSpace();
long used = total - free;
SysFile sysFile = new SysFile();
sysFile.setDirName(fs.getMount());
sysFile.setSysTypeName(fs.getType());
sysFile.setTypeName(fs.getName());
sysFile.setTotal(convertFileSize(total));
sysFile.setFree(convertFileSize(free));
sysFile.setUsed(convertFileSize(used));
sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100));
sysFiles.add(sysFile);
}
}
/**
* 字节转换
*
* @param size 字节大小
* @return 转换后值
*/
public String convertFileSize(long size)
{
long kb = 1024;
long mb = kb * 1024;
long gb = mb * 1024;
if (size >= gb)
{
return String.format("%.1f GB", (float) size / gb);
}
else if (size >= mb)
{
float f = (float) size / mb;
return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
}
else if (size >= kb)
{
float f = (float) size / kb;
return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
}
else
{
return String.format("%d B", size);
}
}
}
浮点数运算工具类
package com.example.demo.common.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* 精确的浮点数运算
*/
public class Arith
{
/** 默认除法运算精度 */
private static final int DEF_DIV_SCALE = 10;
/** 这个类不能实例化 */
private Arith()
{
}
/**
* 提供精确的加法运算。
* @param v1 被加数
* @param v2 加数
* @return 两个参数的和
*/
public static double add(double v1, double v2)
{
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
/**
* 提供精确的减法运算。
* @param v1 被减数
* @param v2 减数
* @return 两个参数的差
*/
public static double sub(double v1, double v2)
{
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精确的乘法运算。
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static double mul(double v1, double v2)
{
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
* 小数点以后10位,以后的数字四舍五入。
* @param v1 被除数
* @param v2 除数
* @return 两个参数的商
*/
public static double div(double v1, double v2)
{
return div(v1, v2, DEF_DIV_SCALE);
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
* 定精度,以后的数字四舍五入。
* @param v1 被除数
* @param v2 除数
* @param scale 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static double div(double v1, double v2, int scale)
{
if (scale < 0)
{
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
if (b1.compareTo(BigDecimal.ZERO) == 0)
{
return BigDecimal.ZERO.doubleValue();
}
return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
}
/**
* 提供精确的小数位四舍五入处理。
* @param v 需要四舍五入的数字
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public static double round(double v, int scale)
{
if (scale < 0)
{
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = BigDecimal.ONE;
return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
}
}
controller
package com.example.demo.module.domain.controller;
import com.example.demo.module.domain.entity.Server;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping(value = "/domain")
public class DomainController {
@GetMapping(value = "data")
public ModelAndView server() throws Exception {
ModelAndView mv = new ModelAndView("server");
Server server = new Server();
server.copyTo();
mv.addObject("server",server);
return mv;
}
}
html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>server</title>
<link th:href="@{/static/layui/css/layui.css}" rel="stylesheet"/>
</head>
<body style="padding: 20px 20px 20px 20px">
<p>cpu</p>
<table class="layui-table">
<thead>
<tr>
<th>属性</th>
<th>值</th>
</tr>
</thead>
<tbody>
<tr>
<td>核心数</td>
<td th:text="${server.cpu.cpuNum}">0个</td>
</tr>
<tr>
<td>用户使用率</td>
<td th:text="${server.cpu.used + '%'}">0%</td>
</tr>
<tr>
<td>系统使用率</td>
<td th:text="${server.cpu.sys + '%'}">0%</td>
</tr>
<tr>
<td>当前空闲率</td>
<td th:text="${server.cpu.free + '%'}">0%</td>
</tr>
</tbody>
</table>
<br/>
<p>内存</p>
<table class="layui-table">
<thead>
<tr>
<th>属性</th>
<th>内存</th>
<th>JVM</th>
</tr>
</thead>
<tbody>
<tr>
<td>总内存</td>
<td th:text="${server.mem.total + 'G'}">0GB</td>
<td th:text="${server.jvm.total + 'M'}">0MB</td>
</tr>
<tr>
<td>已用内存</td>
<td th:text="${server.mem.used + 'G'}">0GB</td>
<td th:text="${server.jvm.used + 'M'}">0MB</td>
</tr>
<tr>
<td>剩余内存</td>
<td th:text="${server.mem.free + 'G'}">0GB</td>
<td th:text="${server.jvm.free + 'M'}">0MB</td>
</tr>
<tr>
<td>使用率</td>
<td th:class="${server.mem.usage gt 80} ? 'text-danger'">[[${server.mem.usage}]]%</td>
<td th:class="${server.jvm.usage gt 80} ? 'text-danger'">[[${server.jvm.usage}]]%</td>
</tr>
</tbody>
</table>
<br/>
<p>服务器信息</p>
<table class="layui-table">
<tbody>
<tr>
<td>服务器名称</td>
<td th:text="${server.sys.computerName}">xxx</td>
<td>操作系统</td>
<td th:text="${server.sys.osName}">Linux</td>
</tr>
<tr>
<td>服务器IP</td>
<td th:text="${server.sys.computerIp}">127.0.0.1</td>
<td>系统架构</td>
<td th:text="${server.sys.osArch}">amd64</td>
</tr>
</tbody>
</table>
<br/>
<p>Java虚拟机信息</p>
<table class="layui-table">
<tbody>
<tr>
<td>Java名称</td>
<td th:text="${server.jvm.name}">Java</td>
<td>Java版本</td>
<td th:text="${server.jvm.version}">1.8.0</td>
</tr>
<tr>
<td>启动时间</td>
<td th:text="${server.jvm.startTime}">2018-12-31 00:00:00</td>
<td>运行时长</td>
<td th:text="${server.jvm.runTime}">0天0时0分0秒</td>
</tr>
<tr>
<td colspan="1">安装路径</td>
<td colspan="3" th:text="${server.jvm.home}"></td>
</tr>
<tr>
<td colspan="1">项目路径</td>
<td colspan="3" th:text="${server.sys.userDir}"></td>
</tr>
</tbody>
</table>
<br/>
<p>磁盘状态</p>
<table class="layui-table">
<thead>
<tr>
<th>盘符路径</th>
<th>文件系统</th>
<th>盘符类型</th>
<th>总大小</th>
<th>可用大小</th>
<th>已用大小</th>
<th>已用百分比</th>
</tr>
</thead>
<tbody>
<tr th:each="sysFile : ${server.sysFiles}">
<td th:text="${sysFile.dirName}">C:\</td>
<td th:text="${sysFile.sysTypeName}">NTFS</td>
<td th:text="${sysFile.typeName}">local</td>
<td th:text="${sysFile.total}">0GB</td>
<td th:text="${sysFile.free}">0GB</td>
<td th:text="${sysFile.used}">0GB</td>
<td th:class="${sysFile.usage gt 80} ? 'text-danger'">[[${sysFile.usage}]]%</td>
</tr>
</tbody>
</table>
</body>
</html>