关于系统监控有很多开源的东西可以用,很多成熟的软件可以拿来使,这里就不多说了(我也就了解一点,没太用过),大家有兴趣可以去找着看看。我要说的只是最近搞的一个系统监控,基于java的实现,其实也是很简单的就一点cpu使用率、内存、文件系统的监控,用SSH链接到linux或者unix 直接执行vmstat命令就可以看到这些参数,不过要想知道使用率,其实也就处理一下此命令执行的结果就搞定。程序如下:
private List execCmd(String cmd) {
List lines = new ArrayList();
try {
LineNumberReader lineReader = new LineNumberReader(new InputStreamReader(
new BufferedInputStream(Runtime.getRuntime().exec(cmd) .getInputStream())));
String line = null;
while ((line = lineReader.readLine()) != null) {
if (line.trim().length() > 0) {
lines.add(line);
}
}
lineReader.close();
} catch (Exception e) {
e.printStackTrace();
log.error("monitorsystem error", e);
}
return lines;
}
上面的程序直接就拿到了执行命令的结果了,处理数据就不多说了,不过这个貌似只是监控本机的系统状况,若要在A主机监控B主机或者其他的主机该怎么办呢?
首先需要下载一个jar包 ganymed-ssh2-build210.jar 这个jar里提供了通过SSh对远程主机的一些操作,然后程序代码如下就可以拿到命令结果:
mport java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
public class Monitor {
private Connection connection;
/*create connection*/
public Connection getConnection(String server , String username , String password){
try {
connection = new Connection(server);
connection.connect();
boolean isAuthenticated = connection.authenticateWithPassword(username,password);
if(isAuthenticated == false){
throw new IOException("Authentication failed...");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return connection;
}
/*colse connection*/
public void closeConnection () {
try {
if(connection.connect() != null ){
connection.close();
}
} catch (IOException e) {
}finally{
connection.close();
}
}
/*have list for commend*/
public List exeCommondForList(String server,String username, String password ,String cmd){
List lines = new ArrayList();
try {
Session session = this.getConnection(server, username, password).openSession();
session.execCommand(cmd);
System.out.println("Here is some information about the remote host:");
InputStream stdout = new StreamGobbler(session.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
while (true) {
String line = br.readLine();
if (line == null){
break;
}
lines.add(line.trim());
// System.out.println(line);
}
for (int i = 0; i < lines.size(); i++) {
System.out.println(lines.get(i));
}
this.closeConnection();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return lines;
}
Ok 搞定,下面的事情就是处理程序结果了
顺带说一下vmstat 命令:
vmstat [-a] [-n] [-S unit] [delay [ count]]
vmstat [-s] [-n] [-S unit]
vmstat [-m] [-n] [delay [ count]]
vmstat [-d] [-n] [delay [ count]]
vmstat [-p disk partition] [-n] [delay [ count]]
vmstat [-f]
vmstat [-V]
-a:显示活跃和非活跃内存
-f:显示从系统启动至今的fork数量 。引申閱讀: http://www.cnblogs.com/leoo2sk/archive/2009/12/11/talk-about-fork-in-linux.html
-m:显示slabinfo
-n:只在开始时显示一次各字段名称。
-s:显示内存相关统计信息及多种系统活动数量。
delay:刷新时间间隔。如果不指定,只显示一条结果。
count:刷新次数。如果不指定刷新次数,但指定了刷新时间间隔,这时刷新次数为无穷。
-d:显示磁盘相关统计信息。
-p:显示指定磁盘分区统计信息
-S:使用指定单位显示。参数有 k 、K 、m 、M ,分别代表1000、1024、1000000、1048576字节(byte)。默认单位为K(1024 bytes)
-V:显示vmstat版本信息。
[portal@kf-web2 ~]$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
5 0 0 10867088 3106976 10382180 0 0 0 5 0 1 3 0 97 0 0
1 0 0 10865352 3106976 10382180 0 0 0 128 1058 2634 6 0 94 0 0
1 0 0 10865472 3106976 10382180 0 0 0 28 1054 2642 6 0 94 0 0
1 0 0 10867208 3106976 10382180 0 0 0 12 1025 2435 6 0 94 0 0
1 0 0 10865592 3106984 10382180 0 0 0 40 1056 2739 6 0 94 0 0
上面命令执行的结果:
Procs(进程):
r: 运行队列中进程数量
b: 等待IO的进程数量
Memory(内存):
swpd: 使用虚拟内存大小
free: 可用内存大小
buff: 用作缓冲的内存大小
cache: 用作缓存的内存大小
Swap:
si: 每秒从交换区写到内存的大小
so: 每秒写入交换区的内存大小
IO:(现在的Linux版本块的大小为1024bytes)
bi: 每秒读取的块数
bo: 每秒写入的块数
系统:
in: 每秒中断数,包括时钟中断。
cs: 每秒上下文切换数。
CPU(以百分比表示):
us: 用户进程执行时间(user time)
sy: 系统进程执行时间(system time)
id: 空闲时间(包括IO等待时间)
wa: 等待IO时间
对了,在linux和unix下执行该命令得到的结果不一样,处理的方式也应该做相应的调整
应该加String osName = System.getProperty("os.name");这么一句话 然后if(){}else{}一下就可以了吧。
16:38:01