The company's server needs real-time monitoring, and when the user space is full, the operation fails, or when the program exception occurs, real-time reminders are needed to facilitate network management and programmer adjustments, so that the real-time monitoring system is divided into two parts.
Part 1: Real-time system monitoring (cpu utilization, cpu temperature, total memory size, used memory size)
Part 2: Real-time alarms are not refreshed and real-time, so they can only use Ajax. No ajax framework is used here, because the call is relatively simple. As we all know, due to the innate shortcomings of Java, calls and operations on the underlying system are generally completed by JN. Especially the CPU temperature, you can't get it by using the command line under Windows, but since our server system is Linux, you can use Java to get system information without calling jni. Runtime is used here. The exec() function of queries local information by parsing the results of local command calls.
* Get CPU and memory information under the Linux system* * */ public final class LinuxSystemTool { /** * get memory by used info * * @return int[] result * result.length==4;in t[0]=MemTotal ;int[1]=MemFree;int[2]=SwapTotal;int[3]=SwapFree; * @throws IOException * @throws InterruptedException */ public static int [] get MemInfo() 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 = nu ll ; StringTokenizer token = null ; while (( str = br.readLine()) != null ) { token = new StringTokenizer(str); if (!token.hasMoreTokens()) continue ; str = token.nextToken(); if (!token.hasMoreT okens()) continue ; if (str.equalsIgnoreCase( "MemTotal:" )) result[0 ] = Integer.parseInt(token.nextToken()); else if (str.equalsIgnoreCase( "MemFree:" )) result[0 ] = Integer.parseInt(token.nextToken()); else if (str.equalsIgnoreCase( "MemFree:" )) result t[1] = Integer.parseInt (token.nextToken()); else if (str.equalsIgnoreCase( "SwapTotal:" )) result[2 ] = Integer.parseInt(token.nextToken()); else if (str.equalsIgno reCase( "SwapFree:" )) result[3 ] = Integer.parseInt(token.nextToken()); } return result; } /** * get memory by used info * * @return float efficiency * @throws IOEx ception * @throws InterruptedException */ public static float getCpuInfo () throws IOException, InterruptedException { File file = new File( "/proc/stat" ); BufferedReader br = new BufferedReader( new InputStreamReader( new FileInpu tStream(file))); StringTokenizer token = new StringTokenizer(br.readLine()) ; token.nextToken(); int user1 = Integer.parseInt(token.nextToken()); int nice1 = Integer.parseInt(token.nextToken()); int sys1 = Integer.parseIn t(token.nextToken()); int idle1 = Integer.parseInt(token.nextToken()); Thread.sleep(1000); br = new BufferedReader( new InputStreamReader( new FileInputStream(file))); token = new S twistTokenizer(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)); } }
Here are two methods, let me explain it.
Method 1 file "/proc/meminfo" contains memory information, and swap information. For example:
$ cat /proc/meminfo total: used: free: shared: buffers: cached: Mem: 1057009664 851668992 205340672 0 67616768 367820800 Swap: 2146787328 164429824 198 2357504 MemTotal: 1032236 kB MemFree: 200528 kB MemShared: 0 kB
In this way, you can use the method of intercepting strings to obtain linux memory information.
Method 2 contains CPU information in the file "/proc/stat". Every tick of each CPU is used in this file. The following numbers are: user, nice, sys, idle, iowait. Some versions of kernel do not have the iowait item. These values indicate where each tick of the CPU is used from the start of the computer. For example:
cpu0 256279030 0 11832528 1637168262
That is, since CPU0 started, 256279030 ticks are used for user consumption, and 11832528 is used for sys consumption. So if you want to calculate the CPU load per unit time (for example, 1s), you only need to calculate the difference between the values before and after 1 second divided by the number of ticks per second.
OK, there is still CPU temperature left, how to do it? I found a file "cat /proc/acpi/thermal_zone/THM/temperature"; which can return the Linux temperature of the machine.
It's probably like this:
temperature: 68C
But not every Linux machine has this THM. You have to make sure that your Linux loads this THM to use this file. InputStreamReader(new FileInputStream(new File("/proc/acpi/thermal_zone/THM/temperature")) , Go to read this file, I believe everyone will do the following, just read the content and then divide the string to get this 68. ok, all the basic information of the system is completed, and then ok, there is only one thing now, which is to use it Ajax calls this class to get basic information and then returns to the page. I won’t repeat the usage of Ajax.
The following is the effect of system monitoring. Ajax goes to Linux every few seconds to get system information, and then displays it on the jsp page. The following is the effect.
At this point, the first part of the system monitoring part has been completed. Now we will complete the real-time alarm part to analyze the requirements.
1. The temperature and CPU exceed the rated value need to be alerted
2. The user's operating system fails, and the user's storage space is insufficient. There is also an alarm for our company's business operations failure. If an Exception occurs, it can only be alarmed. Of course, the information on the exception stack must be saved in the database. I designed it like this. If the user triggers these errors during the operation, it will be saved in the alarm table of the database, and then monitored in real time and then retrieved the information.
3. Alarms need to be real-time. So how do you check the current and future data from the alarm table? At the beginning, I thought of using the current time, adding the Ajax sending time interval at the current time, select * from warninglist where date>new Date()+ AjaxTime, later found that the time is very incorrect, network delay, program processing time, (cpu information uses sleep function), etc. You often find that some alarm information is ruthlessly let go, and sometimes there are Repeat data, so I thought of using id. Every time I enter the alarm system, I first check the maximum alarm id, and then save it in session. Then when ajax gets the alarm information from the database, I check the data after this id (that is, I enter the monitoring The latest data after the system) and the session saves the new maximum id. The next time ajax fetches the maximum id, the next time ajax fetches the maximum id, so that the information can be guaranteed to be the latest when ajax fetches it, and there is no duplication. Very good !I did this and designed an alarm processing table
CREATE TABLE `warnlist` ( `Id` bigint (20) NOT NULL auto_increment, `warnleave` tinyint(2) NOT NULL default '0' ,//Alarm level: the severity of the alarm `fromguy` varchar (20) NOT NU LL, //Warning `warncontent` varchar (100) NOT NULL ,//Alarm content, such as CPU usage rate exceeds 80% `aviliablevalue` varchar (12) default NULL ,//Authorized value such as 85% `warnvalue ` varchar (12) default NULL ,//Alarm value 80 `warntime` datetime NOT NULL ,//Alarm time `stackinfo` varchar (255) default NULL ,//Exception stack information`dealwith` tinyint(2) NOT N ULL default '0' ,//Processing result `version` int (11) default NULL ,//version `organizerID` varchar (20) default NULL ,//Organization id `des` varchar (255) default NULL , PRIMARY KEY (`I d `) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Suppose I get information from the system, then I need to write a logic, if(cpuTempature>75C) or if(cpuUserd>80%) is written to the database, and then query the alarm information greater than the maximum id of the Ajax database sent last time ( If the following errors occur during this period are found together: the user's storage space is insufficient, and our company's business operation failure alarm, Exception, etc.), loop into an xml parsing class, probably the form is Ajax returns this xml for Page extraction information
< response > < cpuUsed > 67 </ cpuUsed > < cpuTemp > 76 < cpuTemp > < Memory > 1023422 </ Memory > < freeMemory > 43244 </ freeMemory > < wannlist > < warning > 2 </ warnid > < war ncontent > System Storage Insufficient space</ warningcontent > < fromguy > kakaluyi </ fromguy > ...... </ wanrlist > < warninglist > < warnid > 3 </ warnid > < warningcontent > CPU temperature is too high </ warningcontent > < fromguy > System</ fromguy > < orgid > System</ orgid > < warningvalue > 78 </ warningvalue > ............ </ warninglist > ..... ... </ response >
The display code of the system information is related to the picture above:
var cpuUsed = req .responseXML.getElementsByTagName('cpuUsed')[0].firstChild.nodeValue; var totalMemory = req .responseXML.getElementsByTagN ame('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" widt h = "20%" >
Server CPU usage:
</ td > < td class = "text" > < font color = "#FF0000" size = "+2" > < label id = "cpuUsed" > </ label > </ font > < Alarm pre-determined threshold: 80 % > </ td > </ tr > .........
Then there is the problem of the page display. Here I used the addition and deletion of the dom node. A page keeps 50 records. If more than 50, the previous node will be deleted. The code is:
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) //If it is greater than 50 items, look for the table of the alarm list, get the child node of the alarm information, and then delete the extra earliest alarm information { 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); }
Then insert a new alarm message.
for ( var i=0;i<length;i++) { var onewarnlist=req.responseXML.getElementsByTagName( 'warnlist' )[i].childNodes; if (onewarnlist[0].firstChil d.nodeValue==0) { var leave = "Enterprise-level alarm" ; } else { var leave= "Operator-level alarm" ; } var from=onewarnlist[1].firstChild.nodeValue; var warningcontent=onewarnlist[2].firstChild.nodeValue ; var available value=onewarnlist[ 3].firstChild.nodeValue; var warningvalue=onewarnlist[4].firstChild.nodeValue; var warningtime=onewarnlist[5].firstChild.nodeValue; var id=one warninglist[8].firstChild.nodeValue; if (onewarnlist[6]. firstChild.nodeValue==0) { var dealwith= "Unprocessed" ; } else { var dealwith= "<font color='red'>processed</font>" ; } var table=document.getElementBy Id( '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=d ocument.createElement( 'td' ); td1.className ='listText' ; td1.innerHTML = leave; tr.appendChild(td1); var td2=document.createElement( 'td' ); td2.className ='li stText' ; td2.innerHTML = from; tr .appendChild(td2); var td3=document.createElement( 'td' ); td3.className ='listText' ; td3.innerHTML = warningcontent; tr.appendChild(td3); 6 var td4=document.createElement( 'td' ); td4.className ='listText' ; td4.innerHTML = availablevalue; tr.appendChild(td4); var td5=document.createElement( 'td' ); td5.classNa me ='listText' ; td5.innerHTML = '<font color="#FF0000">' +warnvalue+ '</font>' ; tr.appendChild(td5); var td6=document.createElement( 'td' ); td6.className ='listText' ; tt d6.innerHTML = warning time; 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, everything is done, the following is the final effect