1. 程式人生 > >linux各發行版本的系統資源獲取方式調研

linux各發行版本的系統資源獲取方式調研

package com.yoyosys.crawler.system_info;
import java.io.BufferedReader;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;  
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;  
import com.alibaba.fastjson.JSON;
import com.yoyosys.crawler.DataObject;
  
/** 
 * 取得linux系統下的cpu、記憶體資訊 
 */
public final class LinuxSystemTool {
	
    private static Logger log = Logger.getLogger(LinuxSystemTool.class); 
   // private final static float TotalBandwidth = 1000;   //網口頻寬,Mbps
    
    private static LinuxSystemTool linuxSystemTool = new LinuxSystemTool();
    
    public  static LinuxSystemTool getInstance(){
    	return linuxSystemTool;
    	
    }
 
    /**
     * 單位是 Byte
     * @param list
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    public static long[] getMemInfo(List<DataObject> list) throws IOException, InterruptedException {  
    	
    	File file = new File("/proc/meminfo");
        BufferedReader br = new BufferedReader(new InputStreamReader(  
                new FileInputStream(file)));  
        long[] result = new long[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:")){
            	String memtotal=token.nextToken();
                result[0] = Long.parseLong(memtotal);  
                DataObject memTotalData= new DataObject();
                memTotalData.setClock(System.currentTimeMillis());
                memTotalData.setKey("vm.memory.size[total]");
                memTotalData.setValue(result[0] * 1024 + "");
                list.add(memTotalData);
            } else if (str.equalsIgnoreCase("MemFree:"))  {
            	String memFree=token.nextToken();
                result[1] = Long.parseLong(memFree);  
                DataObject memFreeData= new DataObject();
                memFreeData.setClock(System.currentTimeMillis());
                memFreeData.setKey("vm.memory.size[free]");
                memFreeData.setValue(result[1] * 1024 + "");
                list.add(memFreeData);
            } else if (str.equalsIgnoreCase("SwapTotal:"))  {
            	String swapTotal=token.nextToken();
                result[2] = Long.parseLong(swapTotal);  
                DataObject swapTotalData= new DataObject();
                swapTotalData.setClock(System.currentTimeMillis());
                swapTotalData.setKey("system.swap.size[,total]");
                swapTotalData.setValue(result[2] * 1024 +"");
                list.add(swapTotalData);
            } else if (str.equalsIgnoreCase("SwapFree:"))  {
            	String swapFree=token.nextToken();
                result[3] = Long.parseLong(swapFree);  
                DataObject swapFreeData= new DataObject();
                swapFreeData.setClock(System.currentTimeMillis());
                swapFreeData.setKey("system.swap.size[,free]");
                swapFreeData.setValue(result[3]*1024 +"");
                list.add(swapFreeData);
            }
           
            
        }  
        // float  memUsage = 1- (float)freeMem/(float)totalMem; 
        float  mem_pused = 1- (float)result[1]/(float)result[0];
        DataObject memUsageData= new DataObject();
        memUsageData.setClock(System.currentTimeMillis());
        memUsageData.setKey("vm.memory.size[pused]");
        memUsageData.setValue(mem_pused+"" );
        list.add(memUsageData);
        
        float swap_pfree=(float)result[3]/(float)result[2];
        DataObject swapUsageData= new DataObject();
        swapUsageData.setClock(System.currentTimeMillis());
        swapUsageData.setKey("system.swap.size[,pfree]");
        swapUsageData.setValue(swap_pfree+"");
        list.add(swapUsageData);
        
        long swap_used=result[2]-result[3];
        DataObject swapUsedData= new DataObject();
        swapUsedData.setClock(System.currentTimeMillis());
        swapUsedData.setKey("system.swap.size[,used]");
        swapUsedData.setValue(swap_used*1024 +"");
        list.add(swapUsedData);
           
        long mem_used=result[0]-result[1];
        DataObject memUsedData= new DataObject();
        memUsedData.setClock(System.currentTimeMillis());
        memUsedData.setKey("vm.memory.size[used]");
        memUsedData.setValue(mem_used*1024 +"");
        list.add(memUsedData);
        
        return result;  
        
    }  
    
    /** 
     * 獲取cpu資訊   百分率
     *  
     * @return float efficiency 
     * @throws IOException 
     * @throws InterruptedException 
     */  
    public static float getCpuInfo(List<DataObject> list) 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();  
        
        long user1 = Long.parseLong(token.nextToken());  
        long nice1 = Long.parseLong(token.nextToken());  
        long sys1 = Long.parseLong(token.nextToken());  
        long idle1 = Long.parseLong(token.nextToken());
        long iowait1 = Long.parseLong(token.nextToken());
        long irq1 = Long.parseLong(token.nextToken());
        long softirq1 = Long.parseLong(token.nextToken());
        
        Thread.sleep(1000);
  
        br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
        
        token = new StringTokenizer(br.readLine());  
        token.nextToken();
      
        long user2 = Long.parseLong(token.nextToken());  
        long nice2 = Long.parseLong(token.nextToken());  
        long sys2 = Long.parseLong(token.nextToken());  
        long idle2 = Long.parseLong(token.nextToken());
        long iowait2 = Long.parseLong(token.nextToken());
        long irq2 = Long.parseLong(token.nextToken());
        long softirq2 = Long.parseLong(token.nextToken());
        
        float totalCpu=(user2 + nice2 + sys2 + idle2 + iowait2 +irq2 +softirq2) - (user1 + nice1  
                + sys1 + idle1 + iowait1 +irq1 +softirq1);
        
        float usageCpu=(float) ((user2 + sys2 + nice2) - (user1 + sys1 + nice1))  
                / totalCpu ;
        
        usageCpu=(totalCpu-(idle2-idle1))/totalCpu;
        
        DataObject userData = new DataObject();
        userData.setClock(System.currentTimeMillis());
        userData.setKey("system.cpu.util[,user]");
        userData.setValue((user2-user1)/totalCpu*100 +"");
        list.add(userData);
        
        DataObject niceData = new DataObject();
        niceData.setClock(System.currentTimeMillis());
        niceData.setKey("system.cpu.util[,nice]");
        niceData.setValue((nice2-nice1)/totalCpu*100 +"");
        list.add(niceData);
        
        DataObject sysData = new DataObject();
        sysData.setClock(System.currentTimeMillis());
        sysData.setKey("system.cpu.util[,system]");
        sysData.setValue( (sys2-sys1)/totalCpu*100 +"");
        list.add(sysData);
        
        DataObject idleData = new DataObject();
        idleData.setClock(System.currentTimeMillis());
        idleData.setKey("system.cpu.util[,idle]");
        idleData.setValue( (idle2-idle1)/totalCpu*100 +"");
        list.add(idleData);
         
        DataObject iowaitData = new DataObject();
        iowaitData.setClock(System.currentTimeMillis());
        iowaitData.setKey("system.cpu.util[,iowait]");
        iowaitData.setValue( (iowait2-iowait1)/totalCpu*100 +"");
        list.add(iowaitData);
        
        DataObject irqData = new DataObject();
        irqData.setClock(System.currentTimeMillis());
        irqData.setKey("system.cpu.util[,interrupt]");
        irqData.setValue( (irq2-irq1)/totalCpu*100 +"");
        list.add(irqData);
        
        DataObject softirqData = new DataObject();
        softirqData.setClock(System.currentTimeMillis());
        softirqData.setKey("system.cpu.util[,softirq]");
        softirqData.setValue( (softirq2-softirq1)/totalCpu*100 +"");
        list.add(softirqData);        
        
        return 0.0f;
        
      }  
    
    /**
     * cpu 平均負載 百分率
     * 
     * @param list
     */
    public static void getCpuLoadAvg(List<DataObject> list){
    	  File file = new File("/proc/loadavg");
          BufferedReader br;
		try {
			
			br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
		    StringTokenizer token = new StringTokenizer(br.readLine());  
           
            DataObject oneMinuteLoad=new DataObject();
            oneMinuteLoad.setClock(System.currentTimeMillis());
            oneMinuteLoad.setKey("system.cpu.load[,avg1]");
            oneMinuteLoad.setValue(token.nextToken());
            list.add(oneMinuteLoad);
            
            DataObject fiveMinuteLoad=new DataObject();
            fiveMinuteLoad.setClock(System.currentTimeMillis());
            fiveMinuteLoad.setKey("system.cpu.load[,avg5]");
            fiveMinuteLoad.setValue(token.nextToken());
            list.add(fiveMinuteLoad);
            
            DataObject fifteenMinuteLoad=new DataObject();
            fifteenMinuteLoad.setClock(System.currentTimeMillis());
            fifteenMinuteLoad.setKey("system.cpu.load[,avg15]");
            fifteenMinuteLoad.setValue(token.nextToken());
            list.add(fifteenMinuteLoad);
       
		} catch (Exception e) {
			
			log.error("get cpu loadavg error:"+e.getMessage());
			log.error("get cpu loadavg error:"+e.getLocalizedMessage());
		}  
    }
    
    //單位是  byte
    /**
     * 網路流量 IO  Byte
     * @param list
     * @return
     */
    public  static float getNetInfo(List<DataObject> list) {  
      
        float netUsage = 0.0f;  
        Map<String,Object>  mapNet=new HashMap<String,Object>();
        BufferedReader in1 = null;
        BufferedReader in2 = null; 
        try {
        	
        	File file = new File("/proc/net/dev");
            in1 = new BufferedReader(new InputStreamReader(  
                      new FileInputStream(file)));  
//            //第一次採集流量資料  
            long startTime = System.currentTimeMillis();  
            String line = null;  
            long inSize1 = 0, outSize1 = 0;
            in1.readLine();
            in1.readLine();
            //[face, |bytes, packets, errs, drop, fifo, frame, compressed, multicast|bytes, packets, errs, drop, fifo, colls, carrier, compressed]
         
            while((line=in1.readLine()) != null){
            	
                line = line.trim();
                
                String[] temp = line.split("\\s+");
                String eth_name=temp[0].substring(0,temp[0].lastIndexOf(":"));
                
                if(eth_name.equals("lo"))
                	continue;
                int _index=temp[0].lastIndexOf(":");
            
                if(temp[0].length() > _index+1){
                	inSize1 = Long.parseLong(temp[0].substring(temp[0].lastIndexOf(":")+1)); //Receive bytes,單位為Byte  
                    outSize1 = Long.parseLong(temp[8]);//Transmit bytes,單位為Byte  
                }else{
                	inSize1 = Long.parseLong(temp[1]);
                    outSize1 = Long.parseLong(temp[9]);//Transmit bytes,單位為Byte  
                }
                long[] size={inSize1,outSize1};
                mapNet.put(eth_name, size);
             }     
            in1.close();
          
            try {  
                Thread.sleep(1000); 
            } catch (InterruptedException e) {  
                StringWriter sw = new StringWriter();
                e.printStackTrace(new PrintWriter(sw));  
            }  
            //第二次採集流量資料  
            long endTime = System.currentTimeMillis();
            in2 = new BufferedReader(new InputStreamReader(  
                    new FileInputStream(file)));  
            long inSize2 = 0 ,outSize2 = 0;  
            in2.readLine();
            in2.readLine();
            while((line=in2.readLine()) != null){
                line = line.trim();
                String[] temp = line.split("\\s+");
                String eth_name=temp[0].substring(0,temp[0].lastIndexOf(":"));
                if(eth_name.equals("lo"))
                	continue;
                
                int _index=temp[0].lastIndexOf(":");
            	
                if(temp[0].length() > _index+1){
                
                	inSize2 = Long.parseLong(temp[0].substring(temp[0].lastIndexOf(":")+1));  
                	outSize2 = Long.parseLong(temp[8]);
                }else{
                	inSize2 = Long.parseLong(temp[1]);
                    outSize2 = Long.parseLong(temp[9]);//Transmit bytes,單位為Byte  
                	
                }
                long [] d =(long[]) mapNet.get(eth_name);
                long inNet=d[0];
                long outNet=d[1];
                
                DataObject  inNetData = new   DataObject();
                inNetData.setClock(System.currentTimeMillis());
                inNetData.setKey("net.if.in["+eth_name+"]");
                inNetData.setValue( (inSize2-inNet) +"");
                list.add(inNetData);
                
                DataObject  outNetData = new   DataObject();
                outNetData.setClock(System.currentTimeMillis());
                outNetData.setKey("net.if.out["+eth_name+"]");
                outNetData.setValue( (outSize2-outNet) + "");
                list.add(outNetData);
                
//              System.out.println(inSize2 + " - " + inNet + "=" + (inSize2-inNet)/128.0);   //除以128   單位KB    (換算成 bps    Kbps)
//              outNetData.setValue( (outSize2-outNet)*8 +"");  //乘以8   單位B
            }
            
            in2.close();
        } catch (IOException e) {
            StringWriter sw = new StringWriter();  
            e.printStackTrace(new PrintWriter(sw));  
            log.error("NetUsage發生InstantiationException. " + e.getMessage());  
            log.error(sw.toString());
        } finally{
        	try {
				if ( in1 != null ) in1.close();
				if (  in2 != null ) in2.close();
			} catch (IOException e) {
				log.info("IOException :" + e.getMessage());
			}
        }
        return netUsage;
    }
    
    /**
     * 獲取主機狀態資訊   1 是正常  
     * 
     * @param list
     */
    public static void getHostStatus(List<DataObject> list){
    	
    	DataObject data = new DataObject();
    	data.setClock(System.currentTimeMillis());
    	data.setKey("agent.ping");
    	data.setValue("1");
    	list.add(data);
    	
    }
    
    public static List<DataObject>  get()  {
    	List<DataObject> list= new ArrayList<DataObject>();
    	//記憶體  cpu  網路IO 磁碟IO
    	try{
    		
	    	LinuxSystemTool.getMemInfo(list);
	        LinuxSystemTool.getCpuInfo(list);
	        LinuxSystemTool.getCpuLoadAvg(list);
	        LinuxSystemTool.getNetInfo(list);
	        LinuxSystemTool.getDiskSpace(list);
	        LinuxSystemTool.getIOstats(list);
	        LinuxSystemTool.getHostStatus(list);
	        
    	}catch(Exception e){
    		log.error("exception:"+e.getMessage());
    	}
    	log.info(JSON.toJSONString(list, true));
    	
        return list;
    }  
    
//http://www.360doc.com/content/14/0603/14/14935022_383255906.shtml  推導公式
/* 
    8       0 sda 84369 44065 3313744 31078 72767 195050 2144912 56178 0 54484 87178
    8       1 sda1 804 823 6430 90 11 7 72 2 0 90 91
    8       2 sda2 82544 41372 3284186 30663 71229 162201 1869888 47523 0 48303 78111
    8       3 sda3 863 1870 21864 290 1527 32842 274952 8653 0 6547 8941
*/
    /**
     * 磁碟IO  單位Byte
     * 
     * @param list
     */
    public static void getIOstats(List <DataObject> list){
    	
    	File file = new File("/proc/diskstats");
        BufferedReader in1=null;
        BufferedReader in2=null;
        String line = null; 
    	try {
    		in1 = new BufferedReader(new InputStreamReader(  
			          new FileInputStream(file)));
			try {
				long tmp[]={0,0};
				while((line=in1.readLine()) != null){
					line = line.trim();
					String [] ss = line.split("\\s+");
					Pattern p = Pattern.compile("sd[a-z][0-9]\\d{0,}$|hd[a-z][0-9]\\d{0,}$");
					Matcher matcher = p.matcher(ss[2]);
					boolean flag=matcher.matches();
					if(ss[2].contains("loop") || ss[2].contains("ram") || flag)
						continue;

					tmp[0]+=Long.parseLong(ss[5]);
					tmp[1]+=Long.parseLong(ss[9]);
					
				}
				
				Thread.sleep(1000);
				
				in2 = new BufferedReader(new InputStreamReader(  
				          new FileInputStream(file)));
				
				long[] tmp2={0,0};
				
				while((line=in2.readLine()) != null){
					line = line.trim();
					String [] ss = line.split("\\s+");
					
					Pattern p = Pattern.compile("sd[a-z][0-9]\\d{0,}$|hd[a-z][0-9]\\d{0,}$");
					Matcher matcher = p.matcher(ss[2]);
					boolean flag=matcher.matches();
					
					if( ss[2].contains("loop") || ss[2].contains("ram") || flag)
						continue;
					
					long rd_sectors2 = Long.parseLong(ss[5]);
					long wr_sectors2 = Long.parseLong(ss[9]);
					
					tmp2[0]+=rd_sectors2;
					tmp2[1]+=wr_sectors2;
					
				}
				
				long rd_sector = tmp2[0]-tmp[0];
				long wr_sector = tmp2[1]-tmp[1];
				
				DataObject readData = new DataObject();
				readData.setClock(System.currentTimeMillis());
				readData.setKey("vfs.dev.read[,,avg1]");
				readData.setValue(rd_sector *512 +"");
				list.add(readData);
				
				DataObject writeData = new DataObject();
				writeData.setClock(System.currentTimeMillis());
				writeData.setKey("vfs.dev.write[,,avg1]");
				writeData.setValue(wr_sector *512 +"");
				list.add(writeData);
				
				log.info(JSON.toJSONString(list,true));
				//一個扇區是 512 Byte;re_sector wr_sector是扇區數,換算成KB,要除以2;1KB=2*512Bytess
				//System.out.println(JSON.toJSONString(list,true));
				
			} catch (Exception e) {
				log.error("diskstats error:"+e.getMessage());
			}finally{
				
				try {
					if ( in1 != null ) in1.close();
					if (  in2 != null ) in2.close();
				} catch (IOException e) {
					log.info("IOException :" + e.getMessage());
				}
			}
		} catch (FileNotFoundException e) {
			
			log.error("diskstats exception:"+e.getMessage());
			
		}
    }
    
    /**
     * 磁碟總量 單位 Byte
     * 
     * @param list
     */
    public static  void getDiskSpace( List <DataObject> list) {
    	File file = new File("/etc/mtab");
        BufferedReader in1 = null;
        String line = null;

      /*
       * /dev/sda2 / ext4 rw 0 0
		proc /proc proc rw 0 0
		sysfs /sys sysfs rw 0 0
		devpts /dev/pts devpts rw,gid=5,mode=620 0 0
		tmpfs /dev/shm tmpfs rw 0 0
		/dev/sda1 /boot ext4 rw 0 0
		/dev/sdb5 /data/logic ext3 rw 0 0
		/dev/sdb1 /data/primary ext4 rw 0 0
		none /proc/sys/fs/binfmt_misc binfmt_misc rw 0 0
		sunrpc /var/lib/nfs/rpc_pipefs rpc_pipefs rw 0 0
		gvfs-fuse-daemon /root/.gvfs fuse.gvfs-fuse-daemon rw,nosuid,nodev 0 0
		/dev/sr0 /media/VMware\040Tools iso9660 r
	   *   一個目錄可以掛載多個分割槽,(一個分割槽掛在到多個目錄中沒有意義)
         * */
        try {
        	in1 = new BufferedReader(new InputStreamReader(  
			          new FileInputStream(file)));
		
			while((line=in1.readLine()) != null){
				line = line.trim();
				String [] ss = line.split("\\s+");
				File ff=new File(ss[1]);
				
				if(ss[2].equals("xfs") || ss[2].contains("ext") || ss[2].equals("btrfs")){
					//long usdSpace=(long) (ff.getUsableSpace());
					long freeSpace=(long)ff.getFreeSpace();
					long totalSpace=(long) (ff.getTotalSpace());
					
					DataObject totalSpaceData = new DataObject();
					totalSpaceData.setClock(System.currentTimeMillis());
					totalSpaceData.setKey("vfs.fs.size["+ss[1]+",total]");
					totalSpaceData.setValue(totalSpace +"");
					list.add(totalSpaceData);
					
					DataObject usedSpaceData = new DataObject();
					usedSpaceData.setClock(System.currentTimeMillis());
					usedSpaceData.setKey("vfs.fs.size["+ss[1]+",used]");
					usedSpaceData.setValue(totalSpace-freeSpace +"");
					list.add(usedSpaceData);
					
					DataObject typeFileSystemData = new DataObject();
					typeFileSystemData.setClock(System.currentTimeMillis());
					typeFileSystemData.setKey("fs_type_"+ss[1]);
					typeFileSystemData.setValue(ss[2]);
					list.add(typeFileSystemData);
					
					DataObject  pusedData = new DataObject();
					pusedData.setClock(System.currentTimeMillis());
					pusedData.setKey("vfs.fs.size["+ ss[1] +",pused]");
					pusedData.setValue( (totalSpace-freeSpace)/(float)totalSpace +"" );
					list.add(pusedData);
					
				}
				//map.put(ss[1], obj);
		}
			log.info(JSON.toJSONString(list,true)); 
			//System.out.print(JSON.toJSONString(list,true));
		} catch (Exception e1) {
			
			log.info("Exception:"+e1.getMessage());
			
		}finally{
			
			if(in1 != null){
				try {
					
					in1.close();
					
				} catch (IOException e) {
				
					log.error("IOexception :"+e.getMessage());
				}
			}
		}
    }
    
    
	public static void main(String[] args) throws Exception { 
    	String tmp="";
    	if(args.length != 0){
    		tmp=args[0];
    	}
    	 
//    	tmp="diskIO";
//    	//記憶體
    	while(true){
 
    	//記憶體(讀檔案)-》proc/meminfo
    	//cpu(讀檔案)-》/proc/stat 		
    	//網路(讀檔案)-》/proc/net/dev      
    	//磁碟-》執行命令
    	/*
        List<DataObject>  list= new ArrayList<DataObject>();
    	if(tmp.equals("mem") || "".equals(tmp)){
    		   LinuxSystemTool.getMemInfo(list);
    		
    	}
    	if(tmp.equals("cpu") || "".equals(tmp)){
    		  LinuxSystemTool.getCpuInfo(list);
    		  LinuxSystemTool.getCpuLoadAvg(list);
    	}
    	if(tmp.equals("net") || "".equals(tmp)){
    		  LinuxSystemTool.getNetInfo(list);
    		 
    	}
    	if(tmp.equals("diskIO" )|| "".equals(tmp) ){
    		 LinuxSystemTool.getIOstats(list);
    	}
    	
    	  //磁碟IO  執行命令;
    	if(tmp.equals("disk") || "".equals(tmp) ){
    		  LinuxSystemTool.getDiskSpace(list);
//    		  System.out.println(JSON.toJSONString(list,true));
//    		  break;
    	}
    	*/
    	
    	 List<DataObject>  list= new ArrayList<DataObject>();
    	 LinuxSystemTool.getDiskSpace(list);
    	
    	
    	
    	 System.out.println(JSON.toJSONString(list,true));
    	 break;
    	}
    }  
}