程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 應用Java編寫一個簡略的Web的監控體系

應用Java編寫一個簡略的Web的監控體系

編輯:關於JAVA

應用Java編寫一個簡略的Web的監控體系。本站提示廣大學習愛好者:(應用Java編寫一個簡略的Web的監控體系)文章只能為提供參考,不一定能成為您想要的結果。以下是應用Java編寫一個簡略的Web的監控體系正文


公司的辦事器須要及時監控,並且當用戶空間曾經滿了,操作掉敗,或許湧現法式Exception的時刻就須要及時提示,便於網管和法式員調式,如許就把這個及時監控體系分為了兩部門,
 
第一部門:及時體系監控(cpu應用率,cpu溫度,總內存年夜小,已應用內存年夜小)
第二部門:及時告警
因為無刷新及時性,所以只能應用Ajax,這裡沒有效就任何ajax框架,由於挪用比擬簡略
年夜家曉得,因為java的後天缺乏,對底層體系的挪用和操作普通用jni來完成,特殊是cpu溫度,你在window下是打逝世用敕令行是得不到的, 但因為我們的辦事器體系是linux,所以可以不挪用jni完整用java的方法來獲得體系信息,這裡用到了runtime的exec()函數,經由過程解析 當地敕令挪用的成果來查詢當地信息,

* 獲得linux體系下的cpu、內存信息  
*  
* */  
public  final  class LinuxSystemTool  
{  
/**  
* 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  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));  
}  
}  

 
這裡的兩個辦法,說明一下,
辦法1文件"/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 

如許可以用截取字符串的辦法,來獲得linux內存信息.
辦法2在文件"/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數目便可以了。
ok如許還剩下cpu溫度,怎樣做呢
發明了一個文件"cat /proc/acpi/thermal_zone/THM/temperature";可以前往本機的linux溫度,
年夜概是如許的:

temperature:      68C

但不是每台linux機械都有這個THM你要肯定你的linux加載了這個THM能力應用這個文件,如許就用InputStreamReader(new FileInputStream(new File("/proc/acpi/thermal_zone/THM/temperature")), 去讀取這個文件,前面的信任年夜家必定會做了吧,就是把內容讀出來,然後朋分字符串去獲得這個68。ok,體系根本信息全體完成,然後ok如今就只要一件事就是用Ajax去挪用這個類來獲得 根本信息,然後前往到頁面上,Ajax的用法就不贅言了。
 
上面是體系監控的後果,年夜概是Ajax每幾秒去linux下去取一次體系信息,然後顯示在jsp頁面上,以下是後果。

到這裡第一部門體系監控部門曾經完成,如今開端完成及時告警部門,剖析需求
1溫度和cpu跨越額外值須要告警
2用戶操作體系掉敗,用戶存儲空間缺乏也須要告警,還有我們公司的營業操作掉敗告警,假如產生Exception也只能告警,固然要把異常的客棧的 信息保留在數據庫裡,我就如許設計假如用戶在操作中觸發了這些毛病,則保留在數據庫的告警內外,然後及時監控的再掏出來這些信息。
3告警是要及時的那末要怎樣從告警內外查到以後今後的數據呢,一開端想到用以後時光,在以後時光加上Ajax發送時光距離,select * from warnlist where date>new Date()+AjaxTime這類情勢,後來發明時光是很不准確的,收集延遲,法式處置時光,(cpu信息用了sleep函數),等等你經常會發明有些 告警信息被無情的放過,而有的時刻有反復數據,如許我想到了用id,每次進入告警體系先查詢到最年夜的告警id,然後保留在session中,然後ajax 從數據庫裡取告警信息的時刻都查這個id以後的數據(就是進入監控體系後的最新數據),然後session再保留新的最年夜id,下次ajax取照樣從這個 session中取最年夜id,如許信息便可以當ajax取的時刻都包管是最新的,並且沒有反復,very good!就如許做了
如許設計了一張告警處置表

CREATE  TABLE `warnlist` ( 
 `Id` bigint (20) NOT  NULL auto_increment, 
 `warnleave` tinyint(2) NOT  NULL  default  '0' ,//告警級別:告警的嚴重水平 
 `fromguy` varchar (20) NOT  NULL ,//屬於哪一個用戶哪一個組織的告警 
 `warncontent` varchar (100) NOT  NULL ,//告警內容,好比cpu應用率跨越80% 
 `aviliablevalue` varchar (12) default  NULL ,//許可值 好比85% 
 `warnvalue` varchar (12) default  NULL ,//告警值 80 
 `warntime` datetime NOT  NULL ,//告警時光 
 `stackinfo` varchar (255) default  NULL ,//異常的客棧信息 
 `dealwith` tinyint(2) NOT  NULL  default  '0' ,//處置成果 
 `version` int (11) default  NULL ,//version 
 `organizerID` varchar (20) default  NULL ,//組織id 
 `des` varchar (255) default  NULL , 
 PRIMARY  KEY  (`Id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

 
假定我ajax從體系守信息後,那末要寫個邏輯,if(cpuTempature>75C)or if(cpuUserd>80%)則寫入數據庫,然後再查詢年夜於上一次發送Ajax數據庫的最年夜id的告警信息(這時代假如產生的以下毛病一並查 出:用戶存儲空間缺乏,還有我們公司的營業操作掉敗告警,Exception等),輪回拔出一個xml解析類中,年夜概情勢是如許的Ajax前往這個 xml,供頁面提守信息

< response >  
< cpuUsed > 67 </ cpuUsed >  
< cpuTemp > 76 < cpuTemp >  
< Memory > 1023422 </ Memory >  
< freeMemory > 43244 </ freeMemory >  
< wannlist >  
< warnid > 2 </ warnid >  
< warncontent > 體系存儲空間缺乏 </ warncontent >  
< fromguy > kakaluyi </ fromguy >  
.............. 
</ wanrlist >  
< warnlist >  
< warnid > 3 </ warnid >  
< warncontent > cpu溫渡過高 </ warncontent >  
< fromguy > 體系 </ fromguy >  
< orgid > 體系 </ orgid >  
< warnvalue > 78 </ warnvalue >  
............. 
</ warnlist >  
........ 
 
</ response >  

 
體系信息的顯示代碼,就是聯系關系下面誰人圖片的:

var cpuUsed = req .responseXML.getElementsByTagName('cpuUsed')[0].firstChild.nodeValue; 
var totalMemory = req .responseXML.getElementsByTagName('totalMemory')[0].firstChild.nodeValue; 
var freeMemory = req .responseXML.getElementsByTagName('freeMemory')[0].firstChild.nodeValue; 
var cpuTemp = req .responseXML.getElementsByTagName('cpuTemp')[0].firstChild.nodeValue; 
$('cpuUsed').innerHTML = cpuUsed ; 
$('totalMemory').innerHTML = totalMemory ; 
$('freeMemory').innerHTML = freeMemory ; 
$('cpuTemp').innerHTML = cpuTemp ; 
 
//jsp 
< tr >  
< td  class = "label"  width = "20%" >  

辦事器CPU應用率:

</ td >  
< td  class = "text" >  
< font  color = "#FF0000"  size = "+2" > < label  id = "cpuUsed" > </ label >  
</ font >  < 告警預定閥值: 80% >  
</ td >  
</ tr >  
 ......... 

然後就是頁面展示的成績了這裡我用了dom節點的增刪,一個頁面堅持50筆記錄,假如跨越50條則刪除之前的節點,代碼為:
 

var length=req.responseXML.getElementsByTagName( 'warnlist' ).length; 
if (length>0) 
{ 
var trlength=document.getElementsByTagName( 'table' )[4].childNodes[0].childNodes.length; 
 
if (trlength+length-1>50) //假如年夜於50條,則查找告警列表的table,獲得  
告警信息的子節點,然後刪除過剩的最早的告警信息 
{ 
var tbody=document.getElementsByTagName( 'table' )[4].childNodes[0]; 
for ( var i=1;i<trlength+length-50;i++) 
{ 
var tr=tbody.childNodes[i]; 
tr.parentNode.removeChild(tr); 
 
} 

 
然後拔出新的告警信息,

for ( var i=0;i<length;i++) 
{ 
var onewarnlist=req.responseXML.getElementsByTagName( 'warnlist' )[i].childNodes; 
if (onewarnlist[0].firstChild.nodeValue==0) 
{ 
var leave= "企業級告警" ; 
} 
else { 
var leave= "運營商級告警" ; 
} 
var from=onewarnlist[1].firstChild.nodeValue; 
var warncontent=onewarnlist[2].firstChild.nodeValue; 
var aviliablevalue=onewarnlist[3].firstChild.nodeValue; 
var warnvalue=onewarnlist[4].firstChild.nodeValue; 
var warntime=onewarnlist[5].firstChild.nodeValue; 
var id=onewarnlist[8].firstChild.nodeValue; 
if (onewarnlist[6].firstChild.nodeValue==0) 
{ 
var dealwith= "未處置" ; 
} 
else { 
var dealwith= "<font color='red'>已處置</font>" ; 
} 
var table=document.getElementById( 'warntable' ); 
var tr=document.createElement( 'tr' ); 
 if (x%2==1) 
{ 
tr.style.backgroundColor="#BFD3F9"  
} 
else { 
tr.style.backgroundColor="#FBFCEB"  
} 
x++; 
table.appendChild(tr); 
var td=document.createElement( 'td' ); 
td.className ='listText' ; 
td.innerHTML =x; 
tr.appendChild(td); 
var td1=document.createElement( 'td' ); 
td1.className ='listText' ; 
td1.innerHTML = leave; 
tr.appendChild(td1); 
var td2=document.createElement( 'td' ); 
td2.className ='listText' ; 
td2.innerHTML = from; 
tr.appendChild(td2); 
var td3=document.createElement( 'td' ); 
td3.className ='listText' ; 
td3.innerHTML = warncontent; 
tr.appendChild(td3);6 
var td4=document.createElement( 'td' ); 
td4.className ='listText' ; 
td4.innerHTML = aviliablevalue; 
tr.appendChild(td4); 
var td5=document.createElement( 'td' ); 
td5.className ='listText' ; 
td5.innerHTML = '<font color="#FF0000">' +warnvalue+ '</font>' ; 
tr.appendChild(td5); 
var td6=document.createElement( 'td' ); 
td6.className ='listText' ; 
td6.innerHTML = warntime; 
tr.appendChild(td6); 
var td7=document.createElement( 'td' ); 
td7.className ='listText' ; 
td7.innerHTML = dealwith; 
tr.appendChild(td7); 
var td8=document.createElement( 'td' ); 
td8.className ='listText' ; 
td8.innerHTML = id; 
tr.appendChild(td8); 
  } 

 
ok,一切年夜功樂成,以下是終究後果

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved