最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Java編寫一個簡單的Web的監(jiān)控系統(tǒng)

 更新時間:2015年11月17日 15:54:45   作者:snoopy7713  
這篇文章主要介紹了使用Java編寫一個簡單的Web的監(jiān)控系統(tǒng)的例子,并且將重要信息轉(zhuǎn)為XML通過網(wǎng)頁前端顯示,非常之實(shí)用,需要的朋友可以參考下

公司的服務(wù)器需要實(shí)時監(jiān)控,而且當(dāng)用戶空間已經(jīng)滿了,操作失敗,或者出現(xiàn)程序Exception的時候就需要實(shí)時提醒,便于網(wǎng)管和程序員調(diào)式,這樣就把這個實(shí)時監(jiān)控系統(tǒng)分為了兩部分,
 
第一部分:實(shí)時系統(tǒng)監(jiān)控(cpu利用率,cpu溫度,總內(nèi)存大小,已使用內(nèi)存大?。?br /> 第二部分:實(shí)時告警
由于無刷新實(shí)時性,所以只能使用Ajax,這里沒有用到任何ajax框架,因為調(diào)用比較簡單
大家知道,由于java的先天不足,對底層系統(tǒng)的調(diào)用和操作一般用jni來完成,特別是cpu溫度,你在window下是打死用命令行是得不到的, 但由于我們的服務(wù)器系統(tǒng)是linux,所以可以不調(diào)用jni完全用java的方式來得到系統(tǒng)信息,這里用到了runtime的exec()函數(shù),通過解析 本地命令調(diào)用的結(jié)果來查詢本地信息,

* 取得linux系統(tǒng)下的cpu、內(nèi)存信息  
*  
* */  
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"里面包含的就是內(nèi)存的信息,還包括了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內(nèi)存信息.
方法2在文件"/proc/stat"里面就包含了CPU的信息。每一個CPU的每一tick用在什么地方都在這個文件里面記著。后面的數(shù)字含義分 別是: user、nice、sys、idle、iowait。有些版本的kernel沒有iowait這一項。這些數(shù)值表示從開機(jī)到現(xiàn)在,CPU的每tick用 在了哪里。例如:

cpu0 256279030 0 11832528 1637168262 

就是cpu0從開機(jī)到現(xiàn)在有 256279030 tick用在了user消耗,11832528用在了sys消耗。所以如果想計算單位時間(例如1s)里面CPU的負(fù)載,那只需要計算1秒前后數(shù)值的差除以每一秒的tick數(shù)量就可以了。
ok這樣還剩下cpu溫度,怎么做呢
發(fā)現(xiàn)了一個文件"cat /proc/acpi/thermal_zone/THM/temperature";可以返回本機(jī)的linux溫度,
大概是這樣的:

temperature:      68C

但不是每臺linux機(jī)器都有這個THM你要確定你的linux加載了這個THM才能使用這個文件,這樣就用InputStreamReader(new FileInputStream(new File("/proc/acpi/thermal_zone/THM/temperature")), 去讀取這個文件,后面的相信大家一定會做了吧,就是把內(nèi)容讀出來,然后分割字符串去得到這個68。ok,系統(tǒng)基本信息全部完成,然后ok現(xiàn)在就只有一件事就是用Ajax去調(diào)用這個類來得到 基本信息,然后返回到頁面上,Ajax的用法就不贅言了。
 
下面是系統(tǒng)監(jiān)控的效果,大概是Ajax每幾秒去linux下去取一次系統(tǒng)信息,然后顯示在jsp頁面上,以下是效果。

20151117154830520.png (450×204)

到這里第一部分系統(tǒng)監(jiān)控部分已經(jīng)完成,現(xiàn)在開始完成實(shí)時告警部分,分析需求
1溫度和cpu超過額定值需要告警
2用戶操作系統(tǒng)失敗,用戶存儲空間不足也需要告警,還有我們公司的業(yè)務(wù)操作失敗告警,如果發(fā)生Exception也只能告警,當(dāng)然要把異常的堆棧的 信息保存在數(shù)據(jù)庫里,我就這樣設(shè)計如果用戶在操作中觸發(fā)了這些錯誤,則保存在數(shù)據(jù)庫的告警表里,然后實(shí)時監(jiān)控的再取出來這些信息。
3告警是要實(shí)時的那么要怎么從告警表里查到當(dāng)前以后的數(shù)據(jù)呢,一開始想到用當(dāng)前時間,在當(dāng)前時間加上Ajax發(fā)送時間間隔,select * from warnlist where date>new Date()+AjaxTime這種形式,后來發(fā)現(xiàn)時間是很不正確的,網(wǎng)絡(luò)延遲,程序處理時間,(cpu信息用了sleep函數(shù)),等等你常常會發(fā)現(xiàn)有些 告警信息被無情的放過,而有的時候有重復(fù)數(shù)據(jù),這樣我想到了用id,每次進(jìn)入告警系統(tǒng)先查詢到最大的告警id,然后保存在session中,然后ajax 從數(shù)據(jù)庫里取告警信息的時候都查這個id之后的數(shù)據(jù)(就是進(jìn)入監(jiān)控系統(tǒng)后的最新數(shù)據(jù)),然后session再保存新的最大id,下次ajax取還是從這個 session中取最大id,這樣信息就可以當(dāng)ajax取的時候都保證是最新的,而且沒有重復(fù),very good!就這樣做了
這樣設(shè)計了一張告警處理表

CREATE  TABLE `warnlist` ( 
 `Id` bigint (20) NOT  NULL auto_increment, 
 `warnleave` tinyint(2) NOT  NULL  default  '0' ,//告警級別:告警的嚴(yán)重程度 
 `fromguy` varchar (20) NOT  NULL ,//屬于哪個用戶哪個組織的告警 
 `warncontent` varchar (100) NOT  NULL ,//告警內(nèi)容,比如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' ,//處理結(jié)果 
 `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; 

 
假設(shè)我ajax從系統(tǒng)取信息后,那么要寫個邏輯,if(cpuTempature>75C)or if(cpuUserd>80%)則寫入數(shù)據(jù)庫,然后再查詢大于上一次發(fā)送Ajax數(shù)據(jù)庫的最大id的告警信息(這期間如果發(fā)生的以下錯誤一并查 出:用戶存儲空間不足,還有我們公司的業(yè)務(wù)操作失敗告警,Exception等),循環(huán)插入一個xml解析類中,大概形式是這樣的Ajax返回這個 xml,供頁面提取信息

< response >  
< cpuUsed > 67 </ cpuUsed >  
< cpuTemp > 76 < cpuTemp >  
< Memory > 1023422 </ Memory >  
< freeMemory > 43244 </ freeMemory >  
< wannlist >  
< warnid > 2 </ warnid >  
< warncontent > 系統(tǒng)存儲空間不足 </ warncontent >  
< fromguy > kakaluyi </ fromguy >  
.............. 
</ wanrlist >  
< warnlist >  
< warnid > 3 </ warnid >  
< warncontent > cpu溫度過高 </ warncontent >  
< fromguy > 系統(tǒng) </ fromguy >  
< orgid > 系統(tǒng) </ orgid >  
< warnvalue > 78 </ warnvalue >  
............. 
</ warnlist >  
........ 
 
</ response >  

 
系統(tǒng)信息的顯示代碼,就是關(guān)聯(lián)上面那個圖片的:

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%" >  

服務(wù)器CPU使用率:

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

然后就是頁面展現(xiàn)的問題了這里我用了dom節(jié)點(diǎn)的增刪,一個頁面保持50條記錄,如果超過50條則刪除以前的節(jié)點(diǎn),代碼為:
 

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,得到  
告警信息的子節(jié)點(diǎn),然后刪除多余的最早的告警信息 
{ 
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= "企業(yè)級告警" ; 
} 
else { 
var leave= "運(yùn)營商級告警" ; 
} 
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,一切大功告成,以下是最終效果

20151117155058639.png (762×343)

相關(guān)文章

  • 解決創(chuàng)建springboot后啟動報錯:Failed?to?bind?properties?under‘spring.datasource‘

    解決創(chuàng)建springboot后啟動報錯:Failed?to?bind?properties?under‘spri

    在Spring?Boot項目中,application.properties和application.yml是用于配置參數(shù)的兩種文件格式,properties格式簡潔但不支持層次結(jié)構(gòu),而yml格式支持層次性,可讀性更好,在yml文件中,要注意細(xì)節(jié),比如冒號后面需要空格
    2024-10-10
  • Java全面分析面向?qū)ο笾庋b

    Java全面分析面向?qū)ο笾庋b

    或許大家都聽說過java是純面向?qū)ο笳Z言,面向?qū)ο笏枷胍簿褪俏覀兂Uf的OOP,我們聽說最多的思想就是繼承,封裝,多態(tài),今天我們來講一講封裝
    2022-04-04
  • Java創(chuàng)建數(shù)組的3種方式代碼舉例

    Java創(chuàng)建數(shù)組的3種方式代碼舉例

    數(shù)組是相同類型數(shù)據(jù)的有序集合,數(shù)組描述的是若干個相同類型的數(shù)據(jù)按照一定的先后次序排列組合而成,其中每一個數(shù)據(jù)稱為數(shù)組的元素,可以通過下標(biāo)進(jìn)行訪問,這篇文章主要給大家介紹了關(guān)于Java創(chuàng)建數(shù)組的3種方式,需要的朋友可以參考下
    2024-01-01
  • spring項目對某條單據(jù)進(jìn)行加鎖處理的方法

    spring項目對某條單據(jù)進(jìn)行加鎖處理的方法

    這篇文章主要給大家介紹了關(guān)于spring項目對某條單據(jù)進(jìn)行加鎖處理的相關(guān)資料,用于對工單單據(jù)進(jìn)行加鎖和解鎖處理,以防止多用戶同時編輯同一單據(jù),前端傳遞參數(shù)包括單據(jù)ID、類型、鎖超時時間等,后端通過Redis實(shí)現(xiàn)鎖機(jī)制,需要的朋友可以參考下
    2024-11-11
  • 一文精通Java中的volatile關(guān)鍵字

    一文精通Java中的volatile關(guān)鍵字

    volatile是java中的關(guān)鍵詞之一,這篇文章主要給大家介紹了關(guān)于Java中volatile關(guān)鍵字的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Mybatis通過數(shù)據(jù)庫表自動生成實(shí)體類和xml映射文件

    Mybatis通過數(shù)據(jù)庫表自動生成實(shí)體類和xml映射文件

    這篇文章主要介紹了Mybatis通過數(shù)據(jù)庫表自動生成實(shí)體類和xml映射文件的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java代碼如何實(shí)現(xiàn)存取數(shù)據(jù)庫的blob字段

    java代碼如何實(shí)現(xiàn)存取數(shù)據(jù)庫的blob字段

    這篇文章主要介紹了java代碼如何實(shí)現(xiàn)存取數(shù)據(jù)庫的blob字段問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • springboot-jta-atomikos多數(shù)據(jù)源事務(wù)管理實(shí)現(xiàn)

    springboot-jta-atomikos多數(shù)據(jù)源事務(wù)管理實(shí)現(xiàn)

    本文主要介紹了springboot-jta-atomikos多數(shù)據(jù)源事務(wù)管理實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 關(guān)于Redis鍵值出現(xiàn)\xac\xed\x00\x05t\x00&錯誤的解決方法

    關(guān)于Redis鍵值出現(xiàn)\xac\xed\x00\x05t\x00&錯誤的解決方法

    這篇文章主要介紹了關(guān)于Redis鍵值出現(xiàn)\xac\xed\x00\x05t\x00&的解決方法,出現(xiàn)該問題的原因是, redis template向redis存放使用java對象序列化的值,序列化方式和string的一般方式不同,需要的朋友可以參考下
    2023-08-08
  • java 8如何自定義收集器(collector)詳解

    java 8如何自定義收集器(collector)詳解

    這篇文章主要給大家介紹了關(guān)于java 8如何自定義收集器(collector)的相關(guān)資料,文中介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-06-06

最新評論

永福县| 霸州市| 游戏| 清涧县| 绍兴市| 宜君县| 蓬莱市| 安阳市| 伊金霍洛旗| 门头沟区| 广东省| 垫江县| 乃东县| 丰宁| 买车| 隆回县| 阿坝| 内黄县| 吕梁市| 冷水江市| 临海市| 富蕴县| 大渡口区| 常宁市| 昭苏县| 呼和浩特市| 齐河县| 乌拉特中旗| 海晏县| 信阳市| 蓝山县| 会同县| 汕尾市| 邵阳县| 松潘县| 静宁县| 漠河县| 集贤县| 北安市| 福建省| 祁东县|