- 获取linux命令运行结果
- 获取CPU使用率
- 获取内存大小和内存使用率
- 获取磁盘IO
- 获取网络IO
获取linux命令运行结果
下面的代码用于获取运行一个Linux命令之后的结果,函数返回一个字符串,即命令的运行结果
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
public class Runcommand {
public static String runCommand(String CMD) {
String info = "";
try {
Process pos = Runtime.getRuntime().exec(CMD);
pos.waitFor();
InputStreamReader isr = new InputStreamReader(pos.getInputStream());
LineNumberReader lnr = new LineNumberReader(isr);
String line = "";
while ((line = lnr.readLine()) != null) {
info = info + line + "\n";
}
} catch (IOException e) {
info = e.toString();
} catch (Exception e) {
info = e.toString();
}
return info;
}
}
以下我所获取的数据都简单地用json封装了一下
获取CPU使用率
通过运行Linux命令cat /proc/stat获取
第一行的数值表示的是CPU总的使用情况,所以我们只需用第一行的数字计算。
这里显示的数据单位是jiffies,jiffies是内核中的一个全局变量,用来记录自系统启动以来产生的节拍数,在linux中,一个节拍大致可理解为操作系统进程调度的最小时间片,不同linux内核可能值有不同,通常在1ms到10ms之间。
每个数据代表不同的时间,具体每个数据的含义可在Linux中通过/proc/stat等文件计算Cpu使用率中了解
总的cpu时间totalCpuTime = user + nice + system + idle + iowait + irq + softirq + stealstolen +guest
idle是CPU的空闲时间,即没有使用的时间
所以CPU利用率为:1-idle/totalCpuTime
使用一秒内CPU的使用率充当实时的CPU的实时使用率,即CPU实时使用率为:1-(idle2-idle1)/(totalCpuTime2-totalCpuTime1)
代码如下
import net.sf.json.JSONObject;
public class AcquireCPU {
private static String CMD = "cat /proc/stat";
public static double getCPUUsageRate() {
String info1 = null;
String info2 = null;
try {
info1 = Runcommand.runCommand(CMD);
Thread.sleep(1000);//隔一秒再运行一次
info2 = Runcommand.runCommand(CMD);
} catch (Exception e) {
}
double total1 = 0.0;// 第一次获取的CPU使用总时间
double total2 = 0.0;// 第二次获取的CPU使用总时间
double CPUUsageRate = 0.0;// CPU使用率
String[] data1 = info1.split("\n");
String[] data2 = info2.split("\n");
String[] strdata1 = data1[0].split(" +");
String[] strdata2 = data2[0].split(" +");
int[] numdata1 = new int[strdata1.length - 1];
int[] numdata2 = new int[strdata2.length - 1];
for (int i = 1; i < strdata1.length; i++) {
numdata1[i - 1] = Integer.parseInt(strdata1[i]);
total1 += numdata1[i - 1];
numdata2[i - 1] = Integer.parseInt(strdata2[i]);
total2 += numdata2[i - 1];
}
double idle1 = numdata1[3];// CPU未使用的时间
double idle2 = numdata2[3];// CPU未使用的时间
System.out.println(info1);
System.out.println(info2);
return CPUUsageRate = 1.0 - (idle2 - idle1) / (total2 - total1);//CPU使用率
}
public static JSONObject toJson(double CPUUsageRate) {//封装成json数据
JSONObject json = new JSONObject();
json.put("CPUUsageRate", CPUUsageRate);
return json;
}
public static void main(String[] args) {
// System.out.println("CPU使用率:"+getCPUUsageRate());
double m = getCPUUsageRate();
System.out.println("CPU使用率:" + m);
System.out.println(toJson(m));
}
}
获取内存大小和内存使用率
在Linux下查看内存我们一般用free命令:
下面是对这些数值的解释(单位kb):
Mem:
total:总计物理内存的大小。
used:已使用多大。
free:可用有多少。
shared:多个进程共享的内存总额。
buff/cache:磁盘缓存的大小。
available:可以使用的内存总量。
Swap(交换区的信息):
total:交换的总量。
used:使用量。
free:空闲的交换区。
对于应用程序来说,buff/cache 是等于可用的,因为buff/cache是为了提高文件读取的性能,当应用程序需在用到内存的时候,buff/cache会很快地被回收。
所以从应用程序的角度来说,可用内存=free+buff/cache=total-used
如上例:111552+243544=2028536-1673440=355096
内存使用率计算为:used/total
代码如下:
import net.sf.json.JSONObject;
public class AcquireMemory {
private static int memorySize;//内存大小
private static double memoryUsageRate;//内存使用率
private static String CMD = "free";
public static JSONObject getMemorySize(String info){
JSONObject json = new JSONObject();
String[] data=info.split(" +");
memorySize=Integer.parseInt(data[7]);
json.put("memorySize", memorySize);
return json;
}
public static JSONObject geteMemoryUsageRate(String info){
JSONObject json = new JSONObject();
String[] data=info.split(" +");
double total=Double.parseDouble(data[7]);//内存总大小
double used=Double.parseDouble(data[8]);//已使用内存大小
memoryUsageRate = used/total;
json.put("memoryUsageRate", memoryUsageRate);
return json;
}
public static void main(String[] args) {
String info = Runcommand.runCommand(CMD);
System.out.println(info);
System.out.println(getMemorySize(info));
System.out.println(geteMemoryUsageRate(info));
}
}
获取磁盘IO
通过运行iostat -d -x 1 2命令获取磁盘的IO,后面的1代表间隔一秒,2代表获取两次,因为主要想要获取实时的磁盘IO,而仅仅执行iostat -d -x 的话,获取的数据是从系统启动以来的平均数据,这里第二次输出的数据是从上次输出之后统计的,即一秒前,所以也是以1秒的数据来近似代表实时的磁盘IO
下面介绍一下每项数据的意义:
rrqm/s:每秒进行merge的读操作数目。即delta(rmerge)/s
wrqm/s:每秒进行merge的写操作数目。即delta(wmerge)/s
r/s:每秒完成的读I/O设备次数。即delta(rio)/s
w/s:每秒完成的写I/0设备次数。即delta(wio)/s
rKB/s:每秒读K字节数。
wKB/s:每秒写K字节数。
avgrq-sz:平均每次设备I/O操作的数据大小(扇区)。即delta(rsect+wsect)/delta(rio+wio)
avgqu-sz:平均I/O队列长度。即delta(aveq)/s/1000(因为aveq的单位为毫秒)
await:平均每次设备I/O操作的等待时间(毫秒)。即delta(ruse+wuse)/delta(rio+wio)
svctm:平均每次设备I/O操作的服务时间(毫秒)。即delta(use)/delta(rio+wio)
%util:一秒中有百分之多少的时间用于I/O操作,或者说一秒中有多少时间I/O队列是非空的。即delta(usr)/s/1000(因为use的单位为毫秒)
所以直接获取结果的rKB/s和wKB/s即可
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class AcquireDiskIO {
public static String CMD = "iostat -d -x 1 2";
public static JSONArray getDiskIORate(String info) {
String diskName = null;
double rkb = 0.0;
double wkb = 0.0;
JSONObject json = new JSONObject();
JSONArray jsonArray = new JSONArray();
String[] data = info.split("\n");
for (int i = 7; i < data.length; i++) {
String[] numdata = data[i].split(" +");
diskName = numdata[0];//磁盘名称
rkb = Double.parseDouble(numdata[5]);//磁盘读数据速率
wkb = Double.parseDouble(numdata[6]);//磁盘写数据速率
json.put("diskName", diskName);
json.put("rkb", rkb);
json.put("wkb", wkb);
jsonArray.add(json);
}
return jsonArray;//返回json数组
}
public static void main(String[] args) {
String info = Runcommand.runCommand(CMD);
System.out.println(info);
System.out.println(getDiskIORate(info));
}
}
获取网络IO
通过运行 cat /proc/net/dev命令来获取网络IO
最左边Inter表示接口的名字,Receive表示收包,Transmit表示发送包;
bytes表示收发的字节数;
packets表示收发正确的包量;
errs表示收发错误的包量;
drop表示收发丢弃的包量;
这些数据也是自从系统启动以来的数据,所以用一秒内收发字节数来近似代表实时的网络IO
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class AcquireNetIO {
private static String CMD = "cat /proc/net/dev";
public static JSONArray getNetIO() {
String info1 = null;
String info2 = null;
JSONObject json = new JSONObject();
JSONArray jsonArray = new JSONArray();
try {
info1 = Runcommand.runCommand(CMD);
Thread.sleep(1000);//隔一秒再执行一次
info2 = Runcommand.runCommand(CMD);
System.out.println(info1);
System.out.println(info2);
} catch (Exception e) {
// TODO: handle exception
}
String[] data1 = info1.split("\n");
String[] data2 = info2.split("\n");
int receiveBytes1 = 0;
int transmitBytes1 = 0;
int receiveBytes2 = 0;
int transmitBytes2 = 0;
for (int i = 2; i < data1.length; i++) {
String[] numdata1 = data1[i].trim().split(" +");
String[] numdata2 = data2[i].trim().split(" +");
receiveBytes1 = Integer.parseInt(numdata1[1]);
transmitBytes1 = Integer.parseInt(numdata1[9]);
receiveBytes2 = Integer.parseInt(numdata2[1]);
transmitBytes2 = Integer.parseInt(numdata2[9]);
int receiveBytes = receiveBytes2 - receiveBytes1;
int transmitBytes = transmitBytes2 - transmitBytes1;
json.put("Interface", numdata1[0]);//端口名称
json.put("receiveBytes", receiveBytes);//端口一秒内接收的字节数
json.put("transmitBytes", transmitBytes);//端口一秒内发送的字节数
jsonArray.add(json);
// System.out.println(numdata1[0]+" receiveBytes:" + receiveBytes +
// " bytes transmitBytes:" + transmitBytes + " bytes");
}
return jsonArray;//返回json数组
}
public static void main(String[] args) {
System.out.println(getNetIO());
}
}