性能壓測服務器監控平台


原文地址:http://blog.csdn.net/chenjiazhu/article/details/77648100

該服務器監控平台分為三部分:

 

1. 監控管理平台:配置監控任務、配置監控服務器、啟動關閉監控、結果展示

2. linux機器監控客戶端:獲取當前linux機器的監控指標,發送給監控管理平台

3. windows機器監控客戶端:獲取當前windows機器的監控指標,發送給監控管理平台

 

監控管理平台

界面如下:

監控任務

任務詳情頁

監控指標詳情頁

監控管理平台采用ssh2實現數據增刪改查(沒啥特別,不詳細介紹)

 

圖表展示采用hichart,圖表上點,最多展示100個,如果采樣點太多會影響加載速度,所以讀取數據時用存儲過程讀取最多100個點

 

CREATE DEFINER=`root`@`%` PROCEDURE `sp_getMonitorInfo_2`(IN d_itemId INT, IN d_configId INT, d_count_num INT )
begin

   
	set @count := 0;
	set @num := 0;
	
	set @count := (select count(1) FROM better.MonitorInfo where itemId=d_itemId and configId=d_configId);

	IF @count<d_count_num*2
		THEN
	    SELECT id,cpu,cpu1,cpu2,cpu3,diskRead,diskWrite,memory,networkReceive,networkSend,time,configId,itemId FROM MonitorInfo where itemId=d_itemId and configId=d_configId;
	ELSE
	
	SET @num := round(@count/d_count_num,0);

	set @i := 0;
	
	select * from (
	select @i :=@i + 1 as tmp_id,id,cpu,cpu1,cpu2,cpu3,diskRead,diskWrite,memory,networkReceive,networkSend,time,configId,itemId from MonitorInfo 
	where itemId=d_itemId and configId=d_configId) aa
	where aa.tmp_id%@num=0;
		
	END IF;

end


Linux監控客戶端

 

Linux監控客戶端實現采用讀取/proc這個偽文件系統獲取對應指標,並計算出監控的數值,返回給監控管理平台

 

CPU占用率
/proc/stat

這些數字指明了CPU執行不同的任務所消耗的時間(從系統啟動開始累計到當前時刻)。時間單位是USER_HZ或jiffies(通常是百分之一秒)。

這些數據列的含義如下,我們從左至右逐一認識:
•user:正常的進程在用戶態下執行時間累積
•nice: NICED的進程在用戶態下執行時間列
•system:進程在內核態的執行時間累積
•idle:空閑時間累積
•iowait :等待I / O完成時間累積
•irq :硬中斷時間
•softirq:軟中斷時間

 

“intr”這行給出自系統啟動以來的所有中斷信息。第一個數字記錄所有的中斷的次數;然后每個數對應一個特定的中斷自系統啟動以來所發生的次數。

“ctxt”給出了自系統啟動以來CPU發生的上下文交換的次數。

“btime”給出了從系統啟動到現在為止的時間,單位為秒。

“processes (total_forks) 自系統啟動以來所創建的任務的個數目。

“procs_running”:當前運行隊列的任務的數目。

“procs_blocked”:當前被阻塞的任務的數目,等待I/O完成次數。

 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;

public class CpuUsage {
	private static Logger log = LoggerFactory.getLogger(CpuUsage.class);
	private static CpuUsage INSTANCE = new CpuUsage();

	private static long idleCpuTimeTemp = 0;
	private static long userCpuTimeTemp = 0;
	private static long systemCpuTimeTemp = 0;
	private static long softirqCpuTimeTemp = 0;
	private static long totalCpuTimeTemp = 0;

	private CpuUsage() {

	}

	public static CpuUsage getInstance() {
		return INSTANCE;
	}

	/**
	 * Purpose:采集CPU使用率
	 * 
	 * @param args
	 * @return float,CPU使用率,小於1
	 */
	public int[] get() {
		// log.info("開始收集cpu使用率");
		int result[] = new int[8];

		int idleCpuUsage = 0, userCpuUsage = 0, systemCpuUsage = 0, softirqCpuUsage = 0;

		 String fileName = "/proc/stat";
	        File file = new File(fileName );
	        BufferedReader reader = null;
	        
		try {
			  //System.out.println("以行為單位讀取文件內容,一次讀一整行:");
            reader = new BufferedReader(new FileReader(file));
            String line = null;
            int count = 0;
            
			long idleCpuTime1 = 0, userCpuTime1 = 0, systemCpuTime1 = 0, softirqCpuTime1 = 0, totalCpuTime1 = 0; // 分別為系統啟動后空閑的CPU時間和總的CPU時間
			while ((line = reader.readLine()) != null) {

			//	log.info("line:" + line);
				if (line.startsWith("cpu ")) {
					line = line.trim();

					String[] temp = line.split("\\s+");
					idleCpuTime1 = Long.parseLong(temp[4]);
					userCpuTime1 = Long.parseLong(temp[1]);
					systemCpuTime1 = Long.parseLong(temp[3]);
					softirqCpuTime1 = Long.parseLong(temp[7]);

					for (String s : temp) {
						if (!s.equals("cpu")) {
							totalCpuTime1 += Long.parseLong(s);
						}
					}

					break;
				}
			}
			reader.close();

			if((totalCpuTime1 - totalCpuTimeTemp)!=0)
			{
				if (idleCpuTimeTemp != 0) {
					idleCpuUsage = (int) (((idleCpuTime1 - idleCpuTimeTemp) * 100 / (totalCpuTime1 - totalCpuTimeTemp)) + 0.5);
				}
	
				if (userCpuTimeTemp != 0) {
					userCpuUsage = (int) (((userCpuTime1 - userCpuTimeTemp) * 100 / (totalCpuTime1 - totalCpuTimeTemp)) + 0.5);
				}
	
				if (systemCpuTimeTemp != 0) {
					systemCpuUsage = (int) (((systemCpuTime1 - systemCpuTimeTemp) * 100 / (totalCpuTime1 - totalCpuTimeTemp)) + 0.5);
				}
	
				if (softirqCpuTimeTemp != 0) {
					softirqCpuUsage = (int) (((softirqCpuTime1 - softirqCpuTimeTemp) * 100 / (totalCpuTime1 - totalCpuTimeTemp)) + 0.5);
				}
			}

			result[3] = idleCpuUsage;
			result[2] = userCpuUsage;
			result[0] = systemCpuUsage;
			result[1] = softirqCpuUsage;

			idleCpuTimeTemp = idleCpuTime1;
			userCpuTimeTemp = userCpuTime1;
			systemCpuTimeTemp = systemCpuTime1;
			softirqCpuTimeTemp = softirqCpuTime1;
			totalCpuTimeTemp = totalCpuTime1;

		} catch (IOException e) {
			log.error("CpuUsage發生Exception. " + e.getMessage());
		}

		return result;
	}
	
}
內存
/proc/meminfo
import java.io.BufferedReader;  
import java.io.File;
import java.io.FileReader;
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.io.PrintWriter;  
import java.io.StringWriter;  

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
  
/*
 * 采集內存
 */
public class MemUsage {
	private static Logger log = LoggerFactory.getLogger(MemUsage.class);   
	    private static MemUsage INSTANCE = new MemUsage();  
	      
	    private MemUsage(){  
	      
	    }  
	      
	    public static MemUsage getInstance(){  
	        return INSTANCE;  
	    }  
	      
	    /** 
	     * Purpose:采集內存使用率 
	     * @param args 
	     * @return float,內存使用率,小於1 
	     */  
	    public float get() {  
//	        log.info("開始收集memory使用率");  
	        float memUsage = 0.0f;  
	        Process pro = null;  
	        Runtime r = Runtime.getRuntime();  
	        try {  
	            String command = "cat /proc/meminfo";  
	            pro = r.exec(command);  
	            BufferedReader in = new BufferedReader(new InputStreamReader(pro.getInputStream()));  
	            String line = null;  
	            int count = 0;  
	            long totalMem = 0, freeMem = 0;  
	            while((line=in.readLine()) != null){      
	                log.info(line);   
	                String[] memInfo = line.split("\\s+");  
	                if(memInfo[0].startsWith("MemTotal")){  
	                    totalMem = Long.parseLong(memInfo[1]);  
	                }  
	                if(memInfo[0].startsWith("MemFree")){  
	                    freeMem = Long.parseLong(memInfo[1]);  
	                }  
	                memUsage = 1- (float)freeMem/(float)totalMem;  
	                log.info("本節點內存使用率為: " + memUsage);   
	                if(++count == 2){  
	                    break;  
	                }                 
	            }  
	            in.close();  
	            pro.destroy();  
	        } catch (IOException e) {  
	            StringWriter sw = new StringWriter();  
	            e.printStackTrace(new PrintWriter(sw));  
	            log.error("MemUsage發生InstantiationException. " + e.getMessage());  
	            log.error(sw.toString());  
	        }     
	        return memUsage;  
	    }  
	    
	    /** 
	     * Purpose:采集總內存 
	     * @param args 
	     * @return floatKB
	     */  
	    public float getMenTotal() {  
//	        log.info("開始收集MenTotal");  
	        float totalMem = 0;  
	        Process pro = null;  
	        Runtime r = Runtime.getRuntime();  
	        try {  
	            String command = "cat /proc/meminfo";  
	            pro = r.exec(command);  
	            BufferedReader in = new BufferedReader(new InputStreamReader(pro.getInputStream()));  
	            String line = null;  
	            int count = 0;  
	          
	            while((line=in.readLine()) != null){      
//	                log.info(line);   
	                String[] memInfo = line.split("\\s+");  
	                if(memInfo[0].startsWith("MemTotal")){  
	                    totalMem = Long.parseLong(memInfo[1]);  
	                }  
	               
//	                log.info("本節點MenTotal為: " + totalMem);   
	                if(++count == 2){  
	                    break;  
	                }                 
	            }  
	            in.close();  
	            pro.destroy();  
	        } catch (IOException e) {  
	            StringWriter sw = new StringWriter();  
	            e.printStackTrace(new PrintWriter(sw));  
	            log.error("MemUsage發生InstantiationException. " + e.getMessage());  
	            log.error(sw.toString());  
	        }     
	        return totalMem;  
	    }  
	    
	    /** 
	     * Purpose:采集內存MemFree
	     * @param args 
	     * @return float KB
	     */  
	    public float getMemFree() {  
//	        log.info("開始收集MemFree");  
	    	
	        float freeMem = 0;  
	        String fileName = "/proc/meminfo";
	        File file = new File(fileName );
	        BufferedReader reader = null;
	        
	        try {  

	            reader = new BufferedReader(new FileReader(file));
	           
	            String line = null;  
	          
	            while((line=reader.readLine()) != null){      
//	                log.info(line);   
	                String[] memInfo = line.split("\\s+");  
	               
	                if(memInfo[0].startsWith("MemFree")){  
	                    freeMem = Long.parseLong(memInfo[1]);  
	                    break;
	                }  

	            }  
	            reader.close(); 
	        } catch (IOException e) {  
	            StringWriter sw = new StringWriter();  
	            e.printStackTrace(new PrintWriter(sw));  
	            log.error("MemUsage發生InstantiationException. " + e.getMessage());  
	            log.error(sw.toString());  
	        }     
	        return freeMem;  
	    }  
	    
	      
	    /** 
	     * @param args 
	     * @throws InterruptedException  
	     */  
	    public static void main(String[] args) throws InterruptedException {  
	        while(true){  
	            System.out.println(MemUsage.getInstance().get());  
	            Thread.sleep(5000);  
	        }  
	    }  
}
磁盤IO
/proc/diskstats

/proc/diskstats文件比/sys/block/sda/stat文件多3個域,從左至右分別對應主設備號,次設備號和設備名稱。后續的11個域在這兩個文件里是相同的,它們的函義將在下面解釋。除了第9個域,所有的域都是從啟動時的累積值。

   

第1個域:讀完成次數 ----- 讀磁盤的次數,成功完成讀的總次數。

(number of issued reads. This is the total number of reads completed successfully.)

 

第2個域:合並讀完成次數, 第6個域:合並寫完成次數。為了效率可能會合並相鄰的讀和寫。從而兩次4K的讀在它最終被處理到磁盤上之前可能會變成一次8K的讀,才被計數(和排隊),因此只有一次I/O操作。這個域使你知道這樣的操作有多頻繁。

(number of reads merged)


第3個域:讀扇區的次數,成功讀過的扇區總次數。

(number of sectors read. This is the total number of sectors read successfully.)

 

第4個域:讀花費的毫秒數,這是所有讀操作所花費的毫秒數(用__make_request()到end_that_request_last()測量)。
(number of milliseconds spent reading. This is the total number of milliseconds spent by all reads (as measured from __make_request() to end_that_request_last()).)

 

第5個域:寫完成次數 ----寫完成的次數,成功寫完成的總次數。

(number of writes completed. This is the total number of writes completed successfully.)

 

第6個域:合並寫完成次數 -----合並寫次數。

(number of writes merged Reads and writes which are adjacent to each other may be merged for efficiency. Thus two 4K reads may become one 8K read before it is ultimately handed to the disk, and so it will be counted (and queued) as only one I/O. This field lets you know how often this was done.)

 

第7個域:寫扇區次數 ---- 寫扇區的次數,成功寫扇區總次數。

(number of sectors written. This is the total number of sectors written successfully.)

 

第8個域:寫操作花費的毫秒數  ---  寫花費的毫秒數,這是所有寫操作所花費的毫秒數(用__make_request()到end_that_request_last()測量)。

(number of milliseconds spent writing This is the total number of milliseconds spent by all writes (as measured from __make_request() to end_that_request_last()).)

 

第9個域:正在處理的輸入/輸出請求數 -- -I/O的當前進度,只有這個域應該是0。當請求被交給適當的request_queue_t時增加和請求完成時減小。

(number of I/Os currently in progress. The only field that should go to zero. Incremented as requests are given to appropriate request_queue_t and decremented as they finish.)


第10個域:輸入/輸出操作花費的毫秒數  ----花在I/O操作上的毫秒數,這個域會增長只要field 9不為0。

(number of milliseconds spent doing I/Os. This field is increased so long as field 9 is nonzero.)

 

第11個域:輸入/輸出操作花費的加權毫秒數 -----  加權, 花在I/O操作上的毫秒數,在每次I/O開始,I/O結束,I/O合並時這個域都會增加。這可以給I/O完成時間和存儲那些可以累積的提供一個便利的測量標准。

(number of milliseconds spent doing I/Os. This field is incremented at each I/O start, I/O completion, I/O merge, or read of these stats by the number of I/Os in progress (field 9) times the number of milliseconds spent doing I/O since the last update of this field. This can provide an easy measure of both I/O completion time and the backlog that may be accumulating.)

 

import java.io.BufferedReader;  
import java.io.File;
import java.io.FileReader;
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.io.PrintWriter;  
import java.io.StringWriter;  

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class IoUsage {
	private static Logger log = LoggerFactory.getLogger(IoUsage.class);  
    private static IoUsage INSTANCE = new IoUsage();  
    private static long ioReadTemp = 0;  
    private static long ioWriteTemp = 0; 
    private IoUsage(){  
      
    }  
      
    public static IoUsage getInstance(){  
        return INSTANCE;  
    }  
      
    public long[] getData() {  
//      log.info("開始收集磁盤IO read");  
      long ioRead = 0;  
      long ioWrite = 0;          

      long result[] = new long[2];
      
      String fileName = "/proc/diskstats";
      File file = new File(fileName );
      BufferedReader reader = null;
      try {
          //System.out.println("以行為單位讀取文件內容,一次讀一整行:");
          reader = new BufferedReader(new FileReader(file));
          String line = null;
          int count = 0;
          // 一次讀入一行,直到讀入null為文件結束
          while ((line = reader.readLine()) != null) {
              // 顯示行號
        	  
  			if(++count == 26){  
//                  log.info(line);  
                    String[] temp = line.split("\\s+");  
                    if(temp.length > 10){  
                    	long ioReadData =  (long)(Float.parseFloat(temp[6])/2+0.5);  
                    	long ioWriteData =  (long)(Float.parseFloat(temp[10])/2+0.5); 
                    	
                    	  if(ioReadTemp!=0)
                          {
                    		  ioRead=ioReadData-ioReadTemp;
                    		  ioWrite=ioWriteData-ioWriteTemp;
                          }
                    	  ioReadTemp=ioReadData;
                    	  ioWriteTemp=ioWriteData;
                    }
                    break;
                }  
          }
          reader.close();
      } catch (IOException e) {
          e.printStackTrace();
      } finally {
          if (reader != null) {
              try {
                  reader.close();
              } catch (IOException e1) {
              }
          }
      }
      
      result[0]=ioRead;
      result[1]=ioWrite;
//      result[2]=ioReadTemp;
//      result[3]=ioWriteTemp;
      
      return result;  
  }  
    
    /** 
     * @param args 
     * @throws InterruptedException  
     */  
    public static void main(String[] args) throws InterruptedException {  
        while(true){  
            System.out.println(IoUsage.getInstance().get());  
            Thread.sleep(5000);  
        }  
    }  
}

 

網絡IO

/proc/net/dev

 

import java.io.BufferedReader;  
import java.io.File;
import java.io.FileReader;
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.io.PrintWriter;  
import java.io.StringWriter; 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NetUsage {
	private static Logger log = LoggerFactory.getLogger(NetUsage.class);  
    private static NetUsage INSTANCE = new NetUsage();  
    private final static float TotalBandwidth = 1000;   //網口帶寬,Mbps  
    private static long inSizeTemp=0;
    private static long outSizeTemp=0;
    
    private NetUsage(){  
      
    }  
      
    public static NetUsage getInstance(){  
        return INSTANCE;  
    }  
   
    /** 
     * @Purpose:采集網絡帶寬使用率 
     * @param args 
     * @return float,網絡帶寬使用率,小於1 
     */   
    public long[] getData() {  
//        log.info("開始收集網絡帶寬使用率");  
        float netUsage = 0.0f;  
        long inSize1 = 0; 
        long outSize1 = 0; 
        
        long result[] = new long[2];
        
        String fileName = "/proc/net/dev";
        File file = new File(fileName );
        BufferedReader reader = null;
        
        try {  
        	  //System.out.println("以行為單位讀取文件內容,一次讀一整行:");
            reader = new BufferedReader(new FileReader(file));
            String line = null;
            int count = 0;
             
            while((line=reader.readLine()) != null){     
                line = line.trim();  
                if(line.startsWith("eth")){  
                	
//                    log.info("line:"+line);

                    String[] temp = line.split("\\s+");  
                    long inKbyte;
                    long outKbyte;
                    
//                    for(int i=0;i<temp.length;i++)
//                    {
//                    	log.info("["+i+"]"+temp[i]);
//                    }

                    if(temp.length==16)
                    {
                    	inKbyte = Long.parseLong(temp[0].substring(5))/1024; //Receive bytes,單位為Byte,轉化為KB
                    	outKbyte = Long.parseLong(temp[8])/1024;             //Transmit bytes,單位為Byte ,轉化為KB 
                    }
                    else {
                    	inKbyte = Long.parseLong(temp[1])/1024; //Receive bytes,單位為Byte,轉化為KB
                    	outKbyte = Long.parseLong(temp[9])/1024;             //Transmit bytes,單位為Byte ,轉化為KB 
					}
                    
                    if (inSizeTemp!=0) {
		
                        inSize1= inKbyte-inSizeTemp;
                        outSize1= outKbyte-outSizeTemp;
					}
                    
                    inSizeTemp=inKbyte;
                    outSizeTemp=outKbyte;
                    
                    break;  
                }                 
            }     
            reader.close(); 
           
        } catch (IOException e) {  
            StringWriter sw = new StringWriter();  
            e.printStackTrace(new PrintWriter(sw));  
            log.error("NetUsage發生InstantiationException. " + e.getMessage());  
            log.error(sw.toString());  
        }     
        
        result[0]=inSize1;
        result[1]=outSize1;
//        result[2]=inSizeTemp;
//        result[3]=outSizeTemp;
       
        return result;  
    }   
  
    /** 
     * @param args 
     * @throws InterruptedException  
     */  
    public static void main(String[] args) throws InterruptedException {  
        while(true){  
            System.out.println(NetUsage.getInstance().get());  
            Thread.sleep(5000);  
        }  
    } 
}


獲取數據采用兩種方式作對比,舉網絡的例子
方式一:通過cat /proc/net/dev來取數據,代碼如下:

 

 

 public long[] getData1() {  
//      log.info("開始收集網絡帶寬使用率");  
      float netUsage = 0.0f;  
      long inSize1 = 0; 
      long outSize1 = 0; 
      
      long result[] = new long[4];
      
      Process pro1;  
      Runtime r = Runtime.getRuntime();  
      try {  
          String command = "cat /proc/net/dev";  
          //第一次采集流量數據  
          long startTime = System.currentTimeMillis();  
          pro1 = r.exec(command);  
          BufferedReader in1 = new BufferedReader(new InputStreamReader(pro1.getInputStream()));  
          String line = null;  
           
          while((line=in1.readLine()) != null){     
              line = line.trim();  
              if(line.startsWith("eth")){  
                  String[] temp = line.split("\\s+");   
                  long inKbyte = Long.parseLong(temp[0].substring(5))/1024; //Receive bytes,單位為Byte,轉化為KB
                  long outKbyte = Long.parseLong(temp[8])/1024;             //Transmit bytes,單位為Byte ,轉化為KB 
                  
                  if (inSizeTemp!=0) {
		
                      inSize1= inKbyte-inSizeTemp;
                      outSize1= outKbyte-outSizeTemp;
					}
                  
                  inSizeTemp=inKbyte;
                  outSizeTemp=outKbyte;
                  
                  break;  
              }                 
          }     
          in1.close();  
          pro1.destroy();  
         
      } catch (IOException e) {  
          StringWriter sw = new StringWriter();  
          e.printStackTrace(new PrintWriter(sw));  
          log.error("NetUsage發生InstantiationException. " + e.getMessage());  
          log.error(sw.toString());  
      }     
      
      result[0]=inSize1;
      result[1]=outSize1;
      result[2]=inSizeTemp;
      result[3]=outSizeTemp;
      
      return result;  
  }  


方式二:采用文件讀,代碼如下:

/** 
     * @Purpose:采集網絡帶寬使用率 
     * @param args 
     * @return float,網絡帶寬使用率,小於1 
     */   
    public long[] getData() {  
//        log.info("開始收集網絡帶寬使用率");  
        float netUsage = 0.0f;  
        long inSize1 = 0; 
        long outSize1 = 0; 
        
        long result[] = new long[2];
        
        String fileName = "/proc/net/dev";
        File file = new File(fileName );
        BufferedReader reader = null;
        
        try {  
        	  //System.out.println("以行為單位讀取文件內容,一次讀一整行:");
            reader = new BufferedReader(new FileReader(file));
            String line = null;
            int count = 0;
             
            while((line=reader.readLine()) != null){     
                line = line.trim();  
                if(line.startsWith("eth")){  
                	
//                    log.info("line:"+line);

                    String[] temp = line.split("\\s+");  
                    long inKbyte;
                    long outKbyte;
                    
//                    for(int i=0;i<temp.length;i++)
//                    {
//                    	log.info("["+i+"]"+temp[i]);
//                    }

                    if(temp.length==16)
                    {
                    	inKbyte = Long.parseLong(temp[0].substring(5))/1024; //Receive bytes,單位為Byte,轉化為KB
                    	outKbyte = Long.parseLong(temp[8])/1024;             //Transmit bytes,單位為Byte ,轉化為KB 
                    }
                    else {
                    	inKbyte = Long.parseLong(temp[1])/1024; //Receive bytes,單位為Byte,轉化為KB
                    	outKbyte = Long.parseLong(temp[9])/1024;             //Transmit bytes,單位為Byte ,轉化為KB 
					}
                    
                    if (inSizeTemp!=0) {
		
                        inSize1= inKbyte-inSizeTemp;
                        outSize1= outKbyte-outSizeTemp;
					}
                    
                    inSizeTemp=inKbyte;
                    outSizeTemp=outKbyte;
                    
                    break;  
                }                 
            }     
            reader.close(); 
           
        } catch (IOException e) {  
            StringWriter sw = new StringWriter();  
            e.printStackTrace(new PrintWriter(sw));  
            log.error("NetUsage發生InstantiationException. " + e.getMessage());  
            log.error(sw.toString());  
        }     
        
        result[0]=inSize1;
        result[1]=outSize1;
//        result[2]=inSizeTemp;
//        result[3]=outSizeTemp;
       
        return result;  
    }  


壓測下來,方式二性能更好,所以采用方式二實現所有指標采集。

監控服務實現

監控客戶端采用Springboot+SpringMvc實現,客戶端提供了啟動監控服務與關閉監控服務兩個接口給監控管理平台調用

啟動監控服務

@RequestMapping(value = { "/StartMonitorMachine" }, method = { RequestMethod.GET }, produces = "application/json;charset=UTF-8")
	@ResponseBody
	public String StartMonitorMachine(MachineMonitorConfigPack config) {

		try {
			logger.info("請求StartMonitorMachine:configId="
					+ config.getConfigId() + "&itemId=" + config.getItemId()
					+ "&startTime=" + config.getStartTime() + "&lastTime="
					+ config.getLastTime() + "&ReCallUrl="
					+ config.getReCallUrl() + "&ip=" + config.getIp());
			
			MonitorService.setConfigId(config.getConfigId());
			MonitorService.setItemId(config.getItemId());
			MonitorService.setRecallUrl(config.getReCallUrl());

			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			
			Date startDate=new Date();
//			Date startDate = sdf.parse(config.getStartTime());

			Date deadDate = new Date(startDate.getTime() + config.getLastTime()
					* 60 * 1000);

			MonitorService.setStartTime(startDate);
			MonitorService.setDeadTime(deadDate);
			MonitorService.setIp(config.getIp());

			MonitorService.getInstance().StartMonitor();

			logger.info("請求啟動監控信息成功");

			ret.put("StateCode", "0");
			ret.put("Message", "成功");
			ret.put("Data", "0");

		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.info("請求StartMonitorMachine Exception:"+e);

			ret.put("StateCode", "1");
			ret.put("Message", e.toString());
			ret.put("date", "1");
		}
		return config.getJsoncallback()+"("+ret.toString()+")";
	}

請求model

public class MachineMonitorConfigPack {
	private String jsoncallback;
	private int configId;
	private int itemId;
	private String startTime;
	private int lastTime;
	private String ReCallUrl;
	private String ip;

	
	public String getJsoncallback() {
		return jsoncallback;
	}

	public void setJsoncallback(String jsoncallback) {
		this.jsoncallback = jsoncallback;
	}

	public int getConfigId() {
		return configId;
	}

	public void setConfigId(int configId) {
		this.configId = configId;
	}

	public int getItemId() {
		return itemId;
	}

	public void setItemId(int itemId) {
		this.itemId = itemId;
	}

	public String getStartTime() {
		return startTime;
	}

	public void setStartTime(String startTime) {
		this.startTime = startTime;
	}

	public int getLastTime() {
		return lastTime;
	}

	public void setLastTime(int lastTime) {
		this.lastTime = lastTime;
	}

	public String getReCallUrl() {
		return ReCallUrl;
	}

	public void setReCallUrl(String reCallUrl) {
		ReCallUrl = reCallUrl;
	}

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}
	
}

關閉監控服務

@RequestMapping(value = { "/StopMonitorMachine" }, method = { RequestMethod.GET }, produces = "application/json;charset=UTF-8")
	@ResponseBody
	public String StopMonitorMachine(String jsoncallback) {

		APIResponse<String> rsp;

		try {

			logger.info("請求StopMonitorMachine");

			MonitorService.getInstance().StopMonitor();

			ret.put("StateCode", "0");
			ret.put("Message", "成功");
			ret.put("Data", "0");

			logger.info("請求StopMonitorMachine成功");

		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.info("請求StopMonitorMachine Exception:"+e.toString());

			ret.put("StateCode", "1");
			ret.put("Message", e.toString());
			ret.put("Data", "1");
		}

		return jsoncallback+"("+ret.toString()+")";
	}

 

 

 

jsoncallback是用來實現跨域訪問

監控服務

啟動監控接口會調用監控服務,監控服務會啟動監控線程,為了保證只有一個監控進程活着,監控服務采用單例實現(其實這邊可以采用@Component 托管給Spring,默認就是單例)

 

 

import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

public class MonitorService {
	
	 private static Boolean _isRunning = false;
	 private static Date deadTime;
     private static Date startTime;
     private static String recallUrl;
     private static int configId;
     private static int itemId;
     //private static int machineId;
     private static String ip;
     private static final Logger logger = LoggerFactory.getLogger(MonitorService.class);  

	private MonitorService(){}
	
	private static final MonitorService monitorService=new MonitorService();
	
	private static MonitorThread monitorThread = new MonitorThread();
	private static Thread thread; // 將myRunnable作為Thread target創建新的線程

	public static MonitorService getInstance(){
		return monitorService;
	}
	
	public static void StartMonitor()
	{
		try {
		
		 if (_isRunning)
         {
			 logger.info("監控已啟動");
			 
			 monitorThread.setDeadTime(deadTime);
			 monitorThread.setConfigId(configId);
			 monitorThread.setItemId(itemId);
			 monitorThread.setRecallUrl(recallUrl);
			 
			 logger.info("DeadTime:"+monitorThread.getDeadTime());
			 logger.info("configId:"+monitorThread.getConfigId());
			 logger.info("itemId:"+monitorThread.getItemId());
			 
             return;
         }
		 
		 Date time = new Date();
		 
//		 if(time.before(deadTime) && time.after(startTime))
		if(time.before(deadTime))
		 {
//			 monitorThread.setIp(ip);
//			 monitorThread.setUserName("root");
//			 monitorThread.setPassword("ymt@123");
			 monitorThread.setDeadTime(deadTime);
			 monitorThread.setConfigId(configId);
			 monitorThread.setItemId(itemId);
			 monitorThread.setRecallUrl(recallUrl);
			 
			 logger.info("當前時間在監控時間內,啟動監控進程");
			 thread = new Thread(monitorThread);
			 thread.start();
			 logger.info("監控進程start");
			 _isRunning=true;
		 }
		 else {
			 logger.info("當前時間不在監控時間內,未啟動監控進程");
		}
		} catch (Exception e) {
			 logger.info("StartMonitor() Exception:"+e);
		}
	}
	
	 @SuppressWarnings("deprecation")
	public static void StopMonitor()
     {
		 thread.stop();
		 _isRunning=false;
		 logger.info("關閉監控進程");
     }
	 
	 public static void setRunning(boolean flag){
		 _isRunning=flag;
	 }
	 
	 public static synchronized  boolean getRunning(){
		 return _isRunning;
	 }    

	public static Date getDeadTime() {
		return deadTime;
	}

	public static void setDeadTime(Date deadTime) {
		MonitorService.deadTime = deadTime;
	}

	public static Date getStartTime() {
		return startTime;
	}

	public static void setStartTime(Date startTime) {
		MonitorService.startTime = startTime;
	}

	public static String getRecallUrl() {
		return recallUrl;
	}

	public static void setRecallUrl(String recallUrl) {
		MonitorService.recallUrl = recallUrl;
	}

	public static int getConfigId() {
		return configId;
	}

	public static void setConfigId(int configId) {
		MonitorService.configId = configId;
	}

	public static int getItemId() {
		return itemId;
	}

	public static void setItemId(int itemId) {
		MonitorService.itemId = itemId;
	}

	public static MonitorService getMonitorservice() {
		return monitorService;
	}

	public static String getIp() {
		return ip;
	}

	public static void setIp(String ip) {
		MonitorService.ip = ip;
	}	
	
}

監控線程

import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ymt.envagency.util.HttpRequest;
import com.ymt.envagency.util.monitor.CpuUsage;
import com.ymt.envagency.util.monitor.IoUsage;
import com.ymt.envagency.util.monitor.MemUsage;
import com.ymt.envagency.util.monitor.NetUsage;

public class MonitorThread implements Runnable {

	private String ip;
	private String userName;
	private String password;
	private Date deadTime;
	private int configId;
	private int itemId;
	private String recallUrl;
	
	private static final Logger logger = LoggerFactory.getLogger(MonitorThread.class); 

	public synchronized String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public synchronized String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public synchronized Date getDeadTime() {
		return deadTime;
	}

	public void setDeadTime(Date deadTime) {
		this.deadTime = deadTime;
	}
	
	public synchronized int getConfigId() {
		return configId;
	}

	public void setConfigId(int configId) {
		this.configId = configId;
	}

	public synchronized int getItemId() {
		return itemId;
	}

	public void setItemId(int itemId) {
		this.itemId = itemId;
	}
	
	public synchronized String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
	
	public synchronized String getRecallUrl() {
		return recallUrl;
	}

	public void setRecallUrl(String recallUrl) {
		this.recallUrl = recallUrl;
	}
	
	public void run() {
		logger.info("進入run()");
		try {
			float Memtotal = MemUsage.getInstance().getMenTotal()/1024;

			Date nowDate = new Date();
			
			//這邊獲取是為了拋棄第一的無意義的取值
			CpuUsage.getInstance().get();
			IoUsage.getInstance().getData();
			NetUsage.getInstance().getData();
			
			logger.info("當前時間:"+nowDate);
			
			while (nowDate.before(getDeadTime())) {

				Calendar calendar = Calendar.getInstance();
				calendar.add(Calendar.SECOND, 1);
				String addInfoTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
						.format(calendar.getTime());
				
				int cpus[]=CpuUsage.getInstance().get();
				
				long ios[]=IoUsage.getInstance().getData();
				long nets[]=NetUsage.getInstance().getData();
				
//				logger.info("cpuData:" + (int)cpus[3]+","+(int)cpus[0]+","+(int)cpus[1]+","+(int)cpus[2]);
//				logger.info("cpuData:" + (int)cpus[3]+","+(int)cpus[0]+","+(int)cpus[1]+","+(int)cpus[2]);
//				logger.info("cpuData:" + (int)cpus[3]+","+(int)cpus[0]+","+(int)cpus[1]+","+(int)cpus[2]);

				String url = recallUrl+"/createStressMonitorInfo.action";
				String param = "configId=" + configId + "&itemId=" + itemId
						+ "&cpuData=" + (int)cpus[0]+ "&cpu1Data=" + (int)cpus[1] + "&cpu2Data=" + (int)cpus[2] 
								+ "&cpu3Data=" + (int)cpus[3] + "&coreNumber=" + 8
						+ "&memoryData=" + (int)(MemUsage.getInstance().getMemFree()/1024)+ "&memoryTotalData="
						+ (int)Memtotal + "&diskReadData=" + (int)(ios[0]) + "&diskWriteData="
						+ (int)(ios[1]) + "&networkReceiveData=" + (int)(nets[0])
						+ "&networkSendData=" + (int)(nets[1]) + "&addInfoTime="
						+ URLEncoder.encode(addInfoTime);
//				logger.info("url:" + url);
//				logger.info("param:" + param);

				 String s = HttpRequest.sendGet(url, param);
				 logger.info("發送:"+url+"?"+param+"  返回:"+s);
				 
				 Thread.sleep(1000);
				 nowDate = new Date();
			}
			MonitorService.setRunning(false);
			logger.info("監控時間到,監控停止。");
		} catch (Exception e) {
			logger.info("MonitorThread中run異常"+e.toString());
		}

	}

}

Windows段監控客戶端

windows端監控客戶端采用net mvc實現,主要用到perfmon監控(原理參考http://4453154.blog.51cto.com/4443154/1701525)
每個指標單獨啟動一個進程采樣

啟動接口

 public string StartMonitorMachine(MachineMonitorConfigPack info)
        {
            var resp = new APIResponse<string>()
            {
                StateCode = StateCode.Success,
                Message = "啟動監控成功"
            };

            try
            {
               // String name = ConfigurationManager.AppSettings["name"];
               // String pwd = ConfigurationManager.AppSettings["password"];
               // String domain = ".";

                //Logger.Info("domain:" + domain + "name:" + name + ",password:" + pwd);

                ImpersonateUser user = new ImpersonateUser();
                ImpersonateUserExt.ImpersonateAdminUser(user);

                //DateTime startTime = DateTime.Parse(info.startTime);
                DateTime startTime = DateTime.Now;
                DateTime endTime = startTime.AddMinutes(info.lastTime);

                MachineMonitor.SetStartTime(startTime);
                MachineMonitor.SetDeadTime(endTime);
                MachineMonitor.SetRecalUrl(info.ReCallUrl);
                MachineMonitor.SetConfigId(info.configId);
                MachineMonitor.SetItemId(info.itemId);
                MachineMonitor.StartMonitor();

                Logger.Info("Post Start Monitor Machine success.");
                Logger.Info("startTime:"+ startTime);
                Logger.Info("endTime:"+ endTime);
                Logger.Info("RecalUrl:"+ info.ReCallUrl);
                Logger.Info("ConfigId:"+ info.configId);
                Logger.Info("ItemId:" + info.itemId);

                resp.Data = "0";
                
            }
            catch (Exception ex)
            {
                resp.StateCode = StateCode.Fail;
                resp.Message += ex.ToString();
                resp.Data = "1";
                Logger.Info("Start Monitor Machine Exception:" + ex);
            }

            Logger.Info("請求StateCode:"+resp.StateCode+ ",Message:"+resp.Message);

           String result = info.jsoncallback + "(" + new JavaScriptSerializer().Serialize(resp) + ")";
            return result;
        }

請求model

using Core.Bases;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Core.Models
{
    public class MachineMonitorConfigPack : PostPackBase
    {
        public string jsoncallback { get; set; }        
        public int configId { get; set; }
        public int itemId { get; set; }
        public string startTime { get; set; }
        public int lastTime { get; set; }
        public string ReCallUrl { set; get; }

    }

    public class AppPoolMonitorConfigPack : PostPackBase
    {
        public int appPoolInfoId { get; set; }
        public string poolName { get; set; }
        public DateTime startTime { get; set; }
        public int lastTime { get; set; }
    }
}

停止接口

 

 public string StopMonitorMachine(string jsoncallback)
        {
            var resp = new APIResponse<string>()
            {
                StateCode = StateCode.Success,
                Message = "停止監控成功"
            };

            try
            {
                MachineMonitor.SetDeadTime(DateTime.Now);
                MachineMonitor.StopMonitor();

                Logger.Info("Start Monitor Machine.");
                resp.Data = "0";
            }
            catch (Exception ex)
            {
                resp.StateCode = StateCode.Fail;
                resp.Message += ex.ToString();
                resp.Data = "1";

                Logger.Info("Stop Monitor Machine Exception:" + ex);
            }
            return jsoncallback + "(" + new JavaScriptSerializer().Serialize(resp) + ")";
        }

監控服務

 

 

using Core.Monitor;
using Core.MonitorUtils;
using Core.ServerUtils;
using Core.Text;
using NLog;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using System.Web;

namespace EnvAgency.Services
{
    public class MachineMonitor
    {
        private static bool _isRunning = false;
        private static DateTime deadTime;
        private static DateTime startTime;
        private static String recallUrl;
        private static int configId;
        private static int itemId;
        //private static int machineId;
        private static Thread thread;

        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

        private MachineMonitor()
        {
            startTime = DateTime.Now.ToLocalTime();
            deadTime = DateTime.Now.ToLocalTime();
        }
        public static void SetStartTime(DateTime t)
        {
            startTime = t;
        }

        public static void SetDeadTime(DateTime t)
        {
            deadTime = t;
        }

        public static void SetRecalUrl(string t)
        {
            recallUrl = t;
        }

        public static void SetConfigId(int t)
        {
            configId = t;
        }

        public static void SetItemId(int t)
        {
            itemId = t;
        }

        public static void StartMonitor()
        {
            if (_isRunning)
            {
                Logger.Info("監控已啟動");
                return;
            }

            DateTime time = DateTime.Now.ToLocalTime();
            string ip = ServerInfo.GetLocalIP();
            //MachineInfo machineInfo = db.MachineInfo.Where(o => o.IP == ip).First();

            //if (time < deadTime && time > startTime)
            Logger.Info("time:" + time);
            if(time < deadTime)
            {
                thread = new Thread(GetInfo);
                thread.Start();
                Logger.Info("監控開啟");
                _isRunning = true;
            }
            else
            {
                Logger.Info("監控未開始或者已經結束");
            }

        }

        public static void StopMonitor()
        {
            thread.Abort();
            _isRunning = false;

            Logger.Info("監控關閉");

        }

        public static void GetInfo()
        {
            Logger.Info("Start GetInfo Process");
            DateTime dt = DateTime.Now;

            //int totalMemory = (int)((MemoryMonitor.getMemoryInfo().totalPhys / (1024 * 1024)));
            //int coreNum = ProcessorCountMonitor.getValue();
            MachineMonitorInfo info;
            Logger.Info("Now:" + dt);

            while (dt<deadTime)
            {
                info = MonitorUtil.GetMachineMonitorInfo();

                var client = new RestClient(recallUrl);
                string param = @"/createStressMonitorInfo.action?"
                    + "configId=" + configId
                    + "&itemId=" + itemId
                    + "&cpuData=" + info.cpuData
                    + "&coreNumber=" + info.coreNumber
                    + "&memoryData=" + info.memoryData
                    + "&memoryTotalData=" + info.memoryTotalData
                    + "&diskReadData=" + info.diskReadData
                    + "&diskWriteData=" + info.diskWriteData
                    + "&networkReceiveData=" + info.networkReceiveData
                    + "&networkSendData=" + info.networkSendData
                    + "&addInfoTime=" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");

                Logger.Info("recallUrl : " + recallUrl);
                Logger.Info("request : " + param);

                var request = new RestRequest(param, Method.GET);
                var response = client.Execute(request);

                Logger.Info("response :" + response.StatusCode);
                
                System.Threading.Thread.Sleep(1000);
                dt = DateTime.Now;
                Logger.Info("Now:" + dt);

            }

            _isRunning = false;

        }
    }
}

 

工具類

using Core.Monitor;
using Core.Security;
using EnvAgency.Extensions;
using NLog;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Core.MonitorUtils
{
    public class MonitorUtil
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

        // 獲取CPU,內存占用率,c盤,d盤使用情況
        public static MachineMonitorInfoExt GetMachineMonitorInfoExt()
        {
            MachineMonitorInfoExt info = new MachineMonitorInfoExt();

            ArrayList listThread = new ArrayList();
            
            // 獲取C盤可用空間
            Thread thread5 = new Thread(delegate () { GetCAvaliable(ref info); });
            thread5.Start();
            listThread.Add(thread5);

            // 獲取C盤總空間
            Thread thread6 = new Thread(delegate () { GetCTotal(ref info); });
            thread6.Start();
            listThread.Add(thread6);

            // 獲取D盤可用空間
            Thread thread7 = new Thread(delegate () { GetDAvaliable(ref info); });
            thread7.Start();
            listThread.Add(thread7);

            // 獲取D盤總空間
            Thread thread8 = new Thread(delegate () { GetDTotal(ref info); });
            thread8.Start();
            listThread.Add(thread8);

            foreach (Thread thread in listThread)
            {
                thread.Join();
            }

            return info;
        }

        // 獲取cpu,內存,Disk(I/O),Network(I/O)
        public static MachineMonitorInfo GetMachineMonitorInfo()
        {
            MachineMonitorInfo info = new MachineMonitorInfo();
            // info.CpuUsage = CPUMonitor.getValue();

            /*由於采用新建線程存在內存一直上升的情況,所以換成線程池來才解決這個問題*/
            ArrayList listThread = new ArrayList();

            // 獲取CPU占用比
            Thread thread1 = new Thread(delegate () { GetCpu(ref info); });
            thread1.Start();
            listThread.Add(thread1);

            // 獲取CPU核數
            Thread thread2 = new Thread(delegate () { GetCpuCount(ref info); });
            thread2.Start();
            listThread.Add(thread2);

            // 獲取可用內存
            Thread thread3 = new Thread(delegate () { GetMenoryAvaliable(ref info); });
            thread3.Start();
            listThread.Add(thread3);

            // 獲取總內存
            Thread thread4 = new Thread(delegate () { GetMenoryTotal(ref info); });
            thread4.Start();
            listThread.Add(thread4);

            // 獲取Disk Read
            Thread thread5 = new Thread(delegate () { GetDiskRead(ref info); });
            thread5.Start();
            listThread.Add(thread5);

            // 獲取Disk Write
            Thread thread6 = new Thread(delegate () { GetDiskWrite(ref info); });
            thread6.Start();
            listThread.Add(thread6);

            // 獲取Network Receive
            Thread thread7 = new Thread(delegate () { GetNetworkReceive(ref info); });
            thread7.Start();
            listThread.Add(thread7);

            // 獲取Network Send
            Thread thread8 = new Thread(delegate () { GetNetworkSend(ref info); });
            thread8.Start();
            listThread.Add(thread8);

            foreach (Thread thread in listThread)
            {
                thread.Join();
            }

            foreach (Thread thread in listThread)
            {
                thread.Abort();
            }

            return info;
        }

        public static void GetCpu(ref MachineMonitorInfo info)
        {
            ImpersonateUser user = new ImpersonateUser();
            ImpersonateUserExt.ImpersonateAdminUser(user);

            lock (info)
            {
                info.cpuData = (int)(CPUMonitor.getValue());
            }
        }

        public static void GetCpuCount(ref MachineMonitorInfo info)
        {
            ImpersonateUser user = new ImpersonateUser();
            ImpersonateUserExt.ImpersonateAdminUser(user);

            lock (info)
            {
                info.coreNumber = ProcessorCountMonitor.getValue();
            }
        }

        public static void GetMenoryAvaliable(ref MachineMonitorInfo info)
        {
            ImpersonateUser user = new ImpersonateUser();
            ImpersonateUserExt.ImpersonateAdminUser(user);

            lock (info)
            {
                info.memoryData = (int)((MemoryMonitor.getMemoryInfo().availPhys / (1024 * 1024)));
            }
        }

        public static void GetMenoryTotal(ref MachineMonitorInfo info)
        {
            ImpersonateUser user = new ImpersonateUser();
            ImpersonateUserExt.ImpersonateAdminUser(user);

            lock (info)
            {
                info.memoryTotalData = (int)((MemoryMonitor.getMemoryInfo().totalPhys / (1024 * 1024)));
            }
        }

        public static void GetCAvaliable(ref MachineMonitorInfoExt info)
        {
            ImpersonateUser user = new ImpersonateUser();
            ImpersonateUserExt.ImpersonateAdminUser(user);

            lock (info)
            {
                info.CHardDiskFreeSpace = (MemoryMonitor.GetHardDiskFreeSpace("C") / (1024 * 1024));
            }
        }

        public static void GetCTotal(ref MachineMonitorInfoExt info)
        {
            ImpersonateUser user = new ImpersonateUser();
            ImpersonateUserExt.ImpersonateAdminUser(user);

            lock (info)
            {
                info.CHardDiskSpace = (MemoryMonitor.GetHardDiskSpace("C") / (1024 * 1024));
            }
        }

        public static void GetDAvaliable(ref MachineMonitorInfoExt info)
        {
            ImpersonateUser user = new ImpersonateUser();
            ImpersonateUserExt.ImpersonateAdminUser(user);

            lock (info)
            {
                info.DHardDiskFreeSpace = (MemoryMonitor.GetHardDiskFreeSpace("D") / (1024 * 1024));
            }
        }

        public static void GetDTotal(ref MachineMonitorInfoExt info)
        {
            ImpersonateUser user = new ImpersonateUser();
            ImpersonateUserExt.ImpersonateAdminUser(user);

            lock (info)
            {
                info.DHardDiskSpace = (MemoryMonitor.GetHardDiskSpace("D") / (1024 * 1024));
            }
        }

        // 單kb
        public static void GetDiskRead(ref MachineMonitorInfo info)
        {
            ImpersonateUser user = new ImpersonateUser();
            ImpersonateUserExt.ImpersonateAdminUser(user);

            lock (info)
            {
                info.diskReadData = (int)((DiskReadMonitor.getValue()) / 1024);
            }
        }

        // 單位Kb
        public static void GetDiskWrite(ref MachineMonitorInfo info)
        {
            ImpersonateUser user = new ImpersonateUser();
            ImpersonateUserExt.ImpersonateAdminUser(user);

            lock (info)
            {
                info.diskWriteData = (int)((DiskWriteMonitor.getValue()) / 1024);
            }
        }

        // 單位Kb
        public static void GetNetworkReceive(ref MachineMonitorInfo info)
        {
            ImpersonateUser user = new ImpersonateUser();
            ImpersonateUserExt.ImpersonateAdminUser(user);

            lock (info)
            {
                info.networkReceiveData = (int)((NetworkReceiveMonitor.getValue()) / 1024);
            }
        }

        // 單位Kb
        public static void GetNetworkSend(ref MachineMonitorInfo info)
        {
            ImpersonateUser user = new ImpersonateUser();
            ImpersonateUserExt.ImpersonateAdminUser(user);

            lock (info)
            {
                info.networkSendData = (int)((NetworkSendMonitor.getValue()) / 1024);
            }
        }
    }

    [Serializable]
    public class MachineMonitorInfo
    {
        public int configId { get; set; }
        public int itemId { get; set; }
        public int cpuData { get; set; }
        public int coreNumber { get; set; }
        public int memoryData { get; set; }
        public int memoryTotalData { get; set; }
        public int diskReadData { get; set; }
        public int diskWriteData { get; set; }
        public int networkReceiveData { get; set; }
        public int networkSendData { get; set; }
    }

    [Serializable]
    public class MachineMonitorInfoExt : MachineMonitorInfo
    {
        public float CHardDiskFreeSpace { get; set; }
        public float DHardDiskFreeSpace { get; set; }
        public float CHardDiskSpace { get; set; }
        public float DHardDiskSpace { get; set; }
    }
}

CPU

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Core.Monitor
{
    public sealed class CPUMonitor
    {
        private static readonly CPUMonitor instance = new CPUMonitor();
        private PerformanceCounter pcCpuLoad;

        private CPUMonitor()
        {
            //初始化CPU計數器
            pcCpuLoad = new PerformanceCounter("Processor", "% Processor Time", "_Total");
            pcCpuLoad.MachineName = ".";
            pcCpuLoad.NextValue();
            System.Threading.Thread.Sleep(1000);
        }

        public static CPUMonitor getMonitor()
        {
            return instance;
        }

        public static float getValue()
        {
            return instance.pcCpuLoad.NextValue();
        }
    }
}

CPU核數

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Core.Monitor
{
    public sealed class ProcessorCountMonitor
    {
        public static readonly ProcessorCountMonitor instance = new ProcessorCountMonitor();
        private int m_ProcessorCount = 0;   //CPU個數

        private ProcessorCountMonitor()
        {
            //CPU個數
            m_ProcessorCount = Environment.ProcessorCount;
        }

        public static ProcessorCountMonitor getMonitor()
        {
            return instance;
        }

        public static int getValue()
        {
            return getMonitor().m_ProcessorCount;
        }
    }
}

內存信息

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Core.Monitor
{
    [StructLayout(LayoutKind.Sequential)]
    public struct MEMORY_INFO
    {
        public uint dwLength;
        public uint dwMemoryLoad;//內存占用比
        public UInt64 dwTotalPhys; //總的物理內存大小
        public UInt64 dwAvailPhys; //可用的物理內存大小 
        public UInt64 dwTotalPageFile;
        public UInt64 dwAvailPageFile; //可用的頁面文件大小
        public UInt64 dwTotalVirtual; //返回調用進程的用戶模式部分的全部可用虛擬地址空間
        public UInt64 dwAvailVirtual; // 返回調用進程的用戶模式部分的實際自由可用的虛擬地址空間
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MEMORYSTATUSEX
    {
        public uint dwLength;
        public uint dwMemoryLoad;
        public ulong ullTotalPhys;
        public ulong ullAvailPhys;
        public ulong ullTotalPageFile;
        public ulong ullAvailPageFile;
        public ulong ullTotalVirtual;
        public ulong ullAvailVirtual;
        public ulong ullAvailExtendedVirtual;
    }

    /// <summary>
    /// 存放內存信息
    /// </summary>
    public class MemoryInfo
    {
        public uint memoryLoad { get; set; }//返回00形式
        public ulong totalPhys { get; set; } //以Bite為單位
        public ulong availPhys { get; set; }//以Bite為單位
    }

    public class MemoryMonitor
    {
        /// <summary>
        /// 獲取內存信息
        /// </summary>
        /// <param name="meminfo"></param>
        [DllImport("kernel32")]
        public static extern void GlobalMemoryStatus(ref MEMORY_INFO meminfo);

        [DllImport("kernel32")]
        public static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX stat);

        /// <summary>
        /// 獲取內存信息
        /// </summary>
        /// <returns></returns>
        public static MemoryInfo getMemoryInfo()
        {
            MEMORYSTATUSEX memEx = new MEMORYSTATUSEX();
            memEx.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));

            GlobalMemoryStatusEx(ref memEx);

            MemoryInfo memoryInfo = new MemoryInfo();
            memoryInfo.memoryLoad = memEx.dwMemoryLoad;
            memoryInfo.availPhys = memEx.ullAvailPhys;
            memoryInfo.totalPhys = memEx.ullTotalPhys;

            return memoryInfo;
        }

        ///  <summary> 
        /// 獲取指定驅動器的空間總大小(單位為B) 
        ///  </summary> 
        ///  <param name="str_HardDiskName">只需輸入代表驅動器的字母即可 (大寫)</param> 
        ///  <returns> </returns> 
        public static long GetHardDiskSpace(string str_HardDiskName)
        {
            long totalSize = new long();
            str_HardDiskName = str_HardDiskName + ":\\";
            System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives();
            foreach (System.IO.DriveInfo drive in drives)
            {
                if (drive.Name == str_HardDiskName)
                {
                    totalSize = drive.TotalSize;
                }
            }
            return totalSize;
        }

        ///  <summary> 
        /// 獲取指定驅動器的剩余空間總大小(單位為B) 
        ///  </summary> 
        ///  <param name="str_HardDiskName">只需輸入代表驅動器的字母即可 </param> 
        ///  <returns> </returns> 
        public static long GetHardDiskFreeSpace(string str_HardDiskName)
        {
            long freeSpace = new long();
            str_HardDiskName = str_HardDiskName + ":\\";
            System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives();
            foreach (System.IO.DriveInfo drive in drives)
            {
                if (drive.Name == str_HardDiskName)
                {
                    freeSpace = drive.TotalFreeSpace;
                }
            }
            return freeSpace;
        }
    }
}

磁盤讀

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Core.Monitor
{
    public sealed class DiskReadMonitor
    {
        private static readonly DiskReadMonitor instance = new DiskReadMonitor();
        private PerformanceCounter counter;

        private DiskReadMonitor()
        {
            counter = new PerformanceCounter("PhysicalDisk", "Disk Read Bytes/sec", "_Total");
            counter.NextValue();
            System.Threading.Thread.Sleep(1000);
        }

        public static DiskReadMonitor getMonitor()
        {
            return instance;
        }

        public static float getValue()
        {
            return instance.counter.NextValue();
        }
    }
}

磁盤寫

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Core.Monitor
{
    public sealed class DiskWriteMonitor
    {
        private static readonly DiskWriteMonitor instance = new DiskWriteMonitor();
        private PerformanceCounter counter;

        private DiskWriteMonitor()
        {
            counter = new PerformanceCounter("PhysicalDisk", "Disk Write Bytes/sec", "_Total");
            counter.NextValue();
            System.Threading.Thread.Sleep(1000);
        }

        public static DiskWriteMonitor getMonitor()
        {
            return instance;
        }

        public static float getValue()
        {
            return instance.counter.NextValue();
        }
    }
}

網絡收

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Core.Monitor
{
    public sealed class NetworkReceiveMonitor
    {
        private static readonly NetworkReceiveMonitor instance = new NetworkReceiveMonitor();
        private List<PerformanceCounter> counters = new List<PerformanceCounter>();

        private NetworkReceiveMonitor()
        {
            //初始化CPU計數器
            //counter = new PerformanceCounter("Network Interface", "Bytes Received/sec", "*");

            PerformanceCounterCategory performanceCounterCategory = new PerformanceCounterCategory("Network Interface");
            string[] instances = performanceCounterCategory.GetInstanceNames(); // 多網卡的要確定當前用的是哪個
            //發送
            foreach (string instance in instances)
            {
                PerformanceCounter counter = new PerformanceCounter("Network Interface", "Bytes Received/sec", instance);
                counters.Add(counter);
                counter.NextValue();
            }
            System.Threading.Thread.Sleep(1000);
        }

        public static NetworkReceiveMonitor getMonitor()
        {
            return instance;
        }

        public static float getValue()
        {
            float value = 0;
            //return instance.counter.NextValue();
            foreach (PerformanceCounter counter in instance.counters)
            {
                value += counter.NextValue();
            }
            return value;
        }
    }
}

網絡發

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Core.Monitor
{
    public sealed class NetworkSendMonitor
    {
        private static readonly NetworkSendMonitor instance = new NetworkSendMonitor();
        private List<PerformanceCounter> counters = new List<PerformanceCounter>();

        private NetworkSendMonitor()
        {
            //初始化CPU計數器
            //counter = new PerformanceCounter("Network Interface", "Bytes Received/sec", "*");

            PerformanceCounterCategory performanceCounterCategory = new PerformanceCounterCategory("Network Interface");
            string[] instances = performanceCounterCategory.GetInstanceNames(); // 多網卡的要確定當前用的是哪個
            //發送
            foreach (string instance in instances)
            {
                PerformanceCounter counter = new PerformanceCounter("Network Interface", "Bytes Sent/sec", instance);
                counters.Add(counter);
                counter.NextValue();
            }

            System.Threading.Thread.Sleep(1000);
        }

        public static NetworkSendMonitor getMonitor()
        {
            return instance;
        }

        public static float getValue()
        {
            float value = 0;
            //return instance.counter.NextValue();
            foreach (PerformanceCounter counter in instance.counters)
            {
                value += counter.NextValue();
            }
            return value;
        }
    }
}

用戶登錄

using Core.Security;
using Core.Text;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using NLog;

namespace EnvAgency.Extensions
{
    public static class ImpersonateUserExt
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        public static bool ImpersonateAdminUser(this ImpersonateUser user)
        {
            String name = ConfigurationManager.AppSettings["name"];
            String pwd = ConfigurationManager.AppSettings["password"];
            String domain = ".";
            Logger.Info("name:" + name + ",password:" + pwd);
            return user.ImpersonateValidUser(name, domain, pwd);
        }

        public static bool ImpersonateIISResetUser(this ImpersonateUser user)
        {
            string name, pwd, domain;

            name = "test";
            pwd = "ymtcs2015";
            domain = ".";
            return user.ImpersonateValidUser(name, domain, pwd);
        }

    }
}

由於新建的線程都需要認證,所以新的采樣線程都必須以管理員身份登錄下
ImpersonateUser user = new ImpersonateUser();
ImpersonateUserExt.ImpersonateAdminUser(user);
具體配置配與Web.config
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM