该服务器监控平台分为三部分:
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执行不同的任务所消耗的时间(从系统启动开始累计到当前时刻)。时间单位是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;
}
}
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 (