`
avery_leo
  • 浏览: 382301 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

用java取得linux系统cpu、内存的实时信息

阅读更多
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;

/**
 * 取得linux系统下的cpu、内存信息
 * 
 * <p>
 * 
 * @author leo
 *         </p>
 * @date 2008
 */
public final class LinuxSystemTool implements Runnable{
	private Logger log = Logger.getLogger(LinuxSystemTool.class);
	private Config config=Config.getInstance();
	/**
	 * get memory by used info
	 * 
	 * @return int[] result
	 *         result.length==4;int[0]=MemTotal;int[1]=MemFree;int[2]=SwapTotal;int[3]=SwapFree;
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public void run() {
		// TODO Auto-generated method stub

		while (true) {
			
			try {
				exec();
				Thread.sleep(config.getThreadTime());
			} catch (Exception e) {
				// TODO Auto-generated catch block
				log.error("Performance Monitoring error:"+e.getMessage());
				e.printStackTrace();
			}
		}
	}
	public void exec() throws Exception {
//		ServerStatus ss = new ServerStatus();

		InetAddress inet = InetAddress.getLocalHost();
		System.out.println("Performance Monitoring ip:"+inet.toString());
		
		String ip=inet.toString().substring(inet.toString().indexOf("/")+1);
		log.info("Performance Monitoring ip:"+ip);
		
		int[] memInfo = LinuxSystemTool.getMemInfo();
		System.out.println("MemTotal:" + memInfo[0]);
		System.out.println("MemFree:" + memInfo[1]);
		
		SnmpUtil util=new SnmpUtil();
		util.setCPU(getCpuInfo());
//		util.setDISK(1);
		util.setMEM(memInfo[0]/memInfo[1]);
		util.setIP(ip);

	}
	public static int[] getMemInfo() throws IOException, InterruptedException {
		File file = new File("/proc/meminfo");
		BufferedReader br = new BufferedReader(new InputStreamReader(
				new FileInputStream(file)));
		int[] result = new int[4];
		String str = null;
		StringTokenizer token = null;
		while ((str = br.readLine()) != null) {
			token = new StringTokenizer(str);
			if (!token.hasMoreTokens())
				continue;

			str = token.nextToken();
			if (!token.hasMoreTokens())
				continue;

			if (str.equalsIgnoreCase("MemTotal:"))
				result[0] = Integer.parseInt(token.nextToken());
			else if (str.equalsIgnoreCase("MemFree:"))
				result[1] = Integer.parseInt(token.nextToken());
			else if (str.equalsIgnoreCase("SwapTotal:"))
				result[2] = Integer.parseInt(token.nextToken());
			else if (str.equalsIgnoreCase("SwapFree:"))
				result[3] = Integer.parseInt(token.nextToken());
		}

		return result;
	}

	/**
	 * get memory by used info
	 * 
	 * @return float efficiency
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public static float getCpuInfo() throws IOException, InterruptedException {
		File file = new File("/proc/stat");
		BufferedReader br = new BufferedReader(new InputStreamReader(
				new FileInputStream(file)));
		StringTokenizer token = new StringTokenizer(br.readLine());
		token.nextToken();
		int user1 = Integer.parseInt(token.nextToken());
		int nice1 = Integer.parseInt(token.nextToken());
		int sys1 = Integer.parseInt(token.nextToken());
		int idle1 = Integer.parseInt(token.nextToken());

		Thread.sleep(1000);

		br = new BufferedReader(
				new InputStreamReader(new FileInputStream(file)));
		token = new StringTokenizer(br.readLine());
		token.nextToken();
		int user2 = Integer.parseInt(token.nextToken());
		int nice2 = Integer.parseInt(token.nextToken());
		int sys2 = Integer.parseInt(token.nextToken());
		int idle2 = Integer.parseInt(token.nextToken());

		return (float) ((user2 + sys2 + nice2) - (user1 + sys1 + nice1))
				/ (float) ((user2 + nice2 + sys2 + idle2) - (user1 + nice1
						+ sys1 + idle1));
	}

	/**
	 * 测试类
	 * 
	 * <p>
	 * 
	 * @author
	 * </p>
	 * @date
	 */

	public static void main(String[] args) throws Exception {
		int[] memInfo = LinuxSystemTool.getMemInfo();
		System.out.println("MemTotal:" + memInfo[0]);
		System.out.println("MemFree:" + memInfo[1]);
		System.out.println("SwapTotal:" + memInfo[2]);
		System.out.println("SwapFree:" + memInfo[3]);

		System.out.println("CPU利用率:" + LinuxSystemTool.getCpuInfo());
	}
}

 CPU

 

在文件"/proc/stat"里面就包含了CPU的信息。每一个CPU的每一tick用在什么地方都在这个文件里面记着。后面的数字含义分别是: user、nice、sys、idle、iowait。有些版本的kernel没有iowait这一项。这些数值表示从开机到现在,CPU的每tick用在了哪里。例如:

cpu0 256279030 0 11832528 1637168262

就是cpu0从开机到现在有 256279030 tick用在了user消耗,11832528用在了sys消耗。所以如果想计算单位时间(例如1s)里面CPU的负载,那只需要计算1秒前后数值的差除以每一秒的tick数量就可以了。gkrellm就是这样实现的:((200 * (v2 - v1) / CPU_TICKS_PER_SECOND) + 1) /2

例如,第一次读取/proc/stat,user的值是256279030;一秒以后再读一次,值是256289030,那么CPU在这一秒的user消耗就是:((200 * (256289030 - 256279030) / CPU_TICKS_PER_SECOND) + 1) /2 = ((10000 * 200 / 1000000) + 1) / 2 = 1%了。

 

2、内存消耗

 

文件"/proc/meminfo"里面包含的就是内存的信息,还包括了swap的信息。例如:

 

 

$ cat /proc/meminfo

total:    used:    free: shared: buffers: cached:
Mem: 1057009664 851668992 205340672        0 67616768 367820800
Swap: 2146787328 164429824 1982357504
MemTotal:      1032236 kB
MemFree:        200528 kB
MemShared:           0 kB
……

不过从gkrellm的源代码看,有些版本没有前面那两行统计的信息,只能够根据下面的Key: Value这种各式的数据收集。

 

3、磁盘空间

 

从gkrellm的源代码看,这个是一个很复杂的数据。磁盘分区的数据有可能分布在:/proc/mounts、/proc/diskstats、 /proc/partitions等等。而且如果想要检查某几个特定的路径,还需要通过mount、df等命令的帮助。为了减少麻烦,这个数据我就直接用 statfs函数直接获得了。

 

int statfs(const char *path, struct statfs *buf);

这个函数只需要输入需要检查的路径名称,就可以返回这个路径所在的分区的空间使用情况:

总空间:buf.f_bsize * buf.f_blocks

空余空间:buf.f_bsize * buf.f_bavail

 

4、磁盘I/O

 

磁盘I/O的数据也同样比较复杂,有些版本看/proc/diskstats,有些版本看/proc/partitions,还有些版本至今我也不知道在那里看……不过可以看到数据的版本也像CPU那样,需要隔一段时间取值,两次取值的差就是流量。

 

5、网络流量

 

网络流量也是五花八门,不过基本上都可以在/proc/net/dev里面获得。同样也是需要两次取值取其差作为流量值。

分享到:
评论
5 楼 avery_leo 2009-05-06  
ocelight 写道

这个网站竟然回帖要求这么严格,我觉得我从你这里学习了很多而且潜水太久。 原来网管里的CPU,内存,磁盘利用率我直接是用的你的方法。 但是对于这种读文件的方式我始终觉得不是太好。(检测服务器时候还选需要检查系统差异) 我后来发现一个采集服务器状态的包,Hyperic-hq产品的基础包sigar.jar 你可以上http://www.hyperic.com看一下 还有真诚的希望和你成为朋友 下面是我的blog地址:http://blog.csdn.net/ocelight


谢谢交流,共同学习
4 楼 ocelight 2009-05-06  
这个网站竟然回帖要求这么严格,我觉得我从你这里学习了很多而且潜水太久。
原来网管里的CPU,内存,磁盘利用率我直接是用的你的方法。
但是对于这种读文件的方式我始终觉得不是太好。(检测服务器时候还选需要检查系统差异)
我后来发现一个采集服务器状态的包,Hyperic-hq产品的基础包sigar.jar
你可以上http://www.hyperic.com看一下
还有真诚的希望和你成为朋友
下面是我的blog地址:http://blog.csdn.net/ocelight
3 楼 blackboy_my 2009-02-05  
还有就是SnmpUtil在哪个包下?
2 楼 blackboy_my 2009-02-05  
这里的Config类是哪个包下的
1 楼 goddy128 2008-12-24  
收了~~~谢谢了

相关推荐

Global site tag (gtag.js) - Google Analytics