440 lines
15 KiB
Java
440 lines
15 KiB
Java
package com.nms.server.thread.monitor;
|
||
|
||
import java.io.BufferedReader;
|
||
import java.io.IOException;
|
||
import java.io.InputStreamReader;
|
||
import java.math.BigDecimal;
|
||
import java.net.Socket;
|
||
import java.text.DecimalFormat;
|
||
import java.text.SimpleDateFormat;
|
||
import java.util.ArrayList;
|
||
import java.util.Arrays;
|
||
import java.util.Calendar;
|
||
import java.util.Date;
|
||
import java.util.HashMap;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
import java.util.concurrent.CountDownLatch;
|
||
|
||
import org.apache.commons.lang.StringUtils;
|
||
import org.apache.log4j.Logger;
|
||
import org.snmp4j.Target;
|
||
import org.snmp4j.mp.SnmpConstants;
|
||
|
||
import com.nms.server.bean.AlarmInfo;
|
||
import com.nms.server.bean.SetInfo;
|
||
import com.nms.server.common.Common;
|
||
import com.nms.server.common.Constants;
|
||
import com.nms.server.util.CSVUtils;
|
||
import com.nms.server.util.DateUtil;
|
||
import com.nms.server.util.ExceptionPrintUtils;
|
||
import com.nms.server.util.SNMP4JUtils;
|
||
|
||
/**
|
||
* 监测数据
|
||
* 监测NMSClient端是否执行执行线程
|
||
* @author ZhangGang
|
||
*
|
||
*/
|
||
public class NMSClientForSNMPThread implements Runnable{
|
||
private Logger logger = Logger.getLogger(NMSClientForSNMPThread.class);
|
||
private SimpleDateFormat format = new SimpleDateFormat(Constants.COMMON_DATE_FORMAT);
|
||
private String name;
|
||
private String ip;
|
||
private int port = Constants.SNMP_CLIENT_PORT;
|
||
private String checkTypeName = null;
|
||
private Long startTime = null;
|
||
private Long sitInfoId = null;
|
||
private long outTime = 2;
|
||
private long maxTimes = 3;
|
||
private long gap = 0 ;
|
||
protected Socket socket = null; //Socket
|
||
private String processIden = null;
|
||
private CountDownLatch downLatch = null;
|
||
/**
|
||
* 构造方法
|
||
* @param name 线程名称
|
||
* @param ip 被监测端IP
|
||
* @param port socket通信端口
|
||
* @param info
|
||
*/
|
||
public NMSClientForSNMPThread(String name,String ip,SetInfo info,Long startTime,CountDownLatch downLatch) {
|
||
this.name = name;
|
||
this.ip = ip;
|
||
this.sitInfoId = info.getId();
|
||
this.checkTypeName = info.getCheckTypeName();
|
||
this.startTime = startTime;
|
||
this.outTime = info.getCheckOutTime();
|
||
this.maxTimes = info.getCheckMaxTimes();
|
||
this.processIden = info.getProcessIden()==null ? "" : info.getProcessIden();
|
||
this.downLatch = downLatch;
|
||
}
|
||
|
||
public NMSClientForSNMPThread(String name,String ip,SetInfo info,Long startTime) {
|
||
this.name = name;
|
||
this.ip = ip;
|
||
this.sitInfoId = info.getId();
|
||
this.checkTypeName = info.getCheckTypeName();
|
||
this.startTime = startTime;
|
||
this.outTime = info.getCheckOutTime();
|
||
this.maxTimes = info.getCheckMaxTimes();
|
||
this.processIden = info.getProcessIden()==null ? "" : info.getProcessIden();
|
||
this.downLatch = downLatch;
|
||
}
|
||
@Override
|
||
public void run() {
|
||
|
||
Thread.currentThread().setName(name+" "+ip);
|
||
|
||
try {
|
||
|
||
Calendar checkTime = Calendar.getInstance();
|
||
Calendar nextTime = Calendar.getInstance();
|
||
nextTime.add(Calendar.MINUTE, Long.valueOf(gap).intValue());
|
||
|
||
List<String> datas = new ArrayList<String>(); //拼写数据格式 已安全进入公共数据解析入口
|
||
//--初始部分数据整理
|
||
datas.add(Common.getIpSeqIdMap().get(ip)+"");//IP,
|
||
datas.add(sitInfoId+"");//监测设置ID,
|
||
datas.add(checkTypeName);//监测类别,
|
||
datas.add(processIden);//进程名称(检查类别设置名称),
|
||
|
||
String stateInfo ="";
|
||
int state = -1;
|
||
String[] datas2 = new String[6];
|
||
int a = 0;
|
||
String msgArr = "";
|
||
boolean isSuccess = false;
|
||
datas2[3] = Calendar.getInstance().getTimeInMillis()+"";
|
||
isSuccess = this.sockeHandshake(msgArr);
|
||
datas2[4] = Calendar.getInstance().getTimeInMillis()+"";
|
||
datas2[0] = "snmp:"+"1.3.6.1.2.1.1.5.0";
|
||
datas2[1] = msgArr;
|
||
// stateInfo += "开始"+format.format(new Date(Long.parseLong(datas2[3])))+ " SNMP握手";
|
||
// stateInfo += "Start"+format.format(new Date(Long.parseLong(datas2[3])))+ " SNMP Shakehand";
|
||
stateInfo += "i18n_server.NMSClientForSNMPThread.begin_n81i"+format.format(new Date(Long.parseLong(datas2[3])))+ " i18n_server.NMSClientForSNMPThread.snmpShake_n81i";
|
||
datas.add(startTime+"");//监测服务启动时间,
|
||
if(isSuccess){ //成功
|
||
// stateInfo += format.format(new Date(Long.parseLong(datas2[4]))) + " 成功 ";
|
||
stateInfo += format.format(new Date(Long.parseLong(datas2[4]))) + " i18n_server.NMSClientForSNMPThread.success_n81i ";
|
||
datas2[2] = "0";
|
||
}else{ //失败
|
||
// stateInfo += format.format(new Date(Long.parseLong(datas2[4]))) + " 失败 ";
|
||
stateInfo += format.format(new Date(Long.parseLong(datas2[4]))) + " i18n_server.NMSClientForSNMPThread.fail_n81i ";
|
||
datas2[2] = "1";
|
||
String [] pingData = pingHandshake();
|
||
|
||
if ((StringUtils.isEmpty(pingData[1]) || "0".equals(pingData[1])) ) {
|
||
// stateInfo = "网络异常";
|
||
stateInfo = "i18n_server.NMSClientForSNMPThread.netErr_n81i";
|
||
} else {
|
||
// stateInfo = "请检查目标主机NMSClient是否启动";
|
||
}
|
||
}
|
||
datas2[5] = DateUtil.getSecondsFromBeinToEnd(new Date(Long
|
||
.parseLong(datas2[3].toString())).getTime(), new Date(Long
|
||
.parseLong(datas2[4].toString())).getTime())
|
||
+ "";
|
||
state = 0;
|
||
|
||
|
||
datas.add("0");//检测时延(秒)
|
||
datas.add(checkTime.getTimeInMillis()+"");//本次检测时间,
|
||
|
||
if(state!=-1){
|
||
datas.add(a+"");// 尝试次数,+"/"+maxTimes
|
||
datas.add(nextTime.getTimeInMillis()+"");// 下次计划监测时间,
|
||
String [] pArray = getAlarmState(Common.getAlarmInfoMap().get(sitInfoId.longValue()+""), datas2);
|
||
if(isSuccess){
|
||
datas.add("1"); // 执行状态
|
||
datas.add(""); // 告警列序号,
|
||
datas.add(""); // 告警级别,
|
||
datas.add(""); // 告警值,
|
||
}else {
|
||
datas.add("0"); // 执行状态
|
||
datas.add(pArray==null?"":pArray[0]); // 告警列序号,
|
||
datas.add(pArray==null?"":pArray[1]); // 告警级别,
|
||
datas.add(pArray==null?"":pArray[2]); // 告警值,
|
||
}
|
||
datas.add(stateInfo); // 状态信息(描述信息),
|
||
datas.add(stateInfo); // 性能数据,
|
||
datas.addAll(Arrays.asList(datas2));//监测具体数据信息(每个字段一列)
|
||
} else {
|
||
datas.add(a+"");// 尝试次数,+"/"+maxTimes
|
||
datas.add(nextTime.getTimeInMillis()+"");// 下次计划监测时间,
|
||
datas.add("-1"); // 执行状态
|
||
datas.add("3"); // 告警列序号,(丢包数 列 序号 为3)
|
||
datas.add("1"); // 告警级别,
|
||
datas.add("1"); // 告警值,
|
||
datas.add(stateInfo); // 状态信息(描述信息),
|
||
datas.add(stateInfo); // 性能数据,
|
||
}
|
||
datas.add(checkTime.getTimeInMillis()+"");//本次检测时间,
|
||
|
||
//- 存入缓存
|
||
try {
|
||
logger.debug("data:"+Arrays.toString(datas.toArray()));
|
||
Common.addDeteData(CSVUtils.csvBytesPrinter(datas, Constants.COMMON_TEXT_CODING));
|
||
logger.debug("监测数据以 CSV格式 保存完成");
|
||
} catch (Exception e) {
|
||
logger.error("Monitoring data to save exceptions in CSV format", e);
|
||
}
|
||
} catch (Exception ex) {
|
||
logger.error(ExceptionPrintUtils.printExceptionStack(ex));
|
||
String[] alarm = Common.alarmExceptionInfo(sitInfoId, ip, Constants.DETEC_NMSC_STR, processIden, startTime, 1,Constants.DETECTION_INFO_ALARM_WRONG, ex.getMessage());
|
||
Common.addAlarmData(alarm);
|
||
}finally{
|
||
if(downLatch != null){
|
||
downLatch.countDown();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void datasHeader(List<String> pubDatas){
|
||
|
||
logger.debug("监测数据头拼写开始");
|
||
|
||
// --初始部分数据整理
|
||
pubDatas.add(Common.getIpSeqIdMap().get(ip)+"");// uuid,
|
||
pubDatas.add(sitInfoId + "");// 监测设置ID,
|
||
pubDatas.add(checkTypeName);// 监测类别,
|
||
pubDatas.add("");// 进程名称(检查类别设置名称),
|
||
pubDatas.add(startTime + "");// 监测服务启动时间,
|
||
pubDatas.add("0");// 检测时延(秒)
|
||
|
||
}
|
||
|
||
private boolean sockeHandshake(String value){
|
||
//- 通过 CloumnsMap 获取 oids
|
||
String [] oidArray = new String []{"1.3.6.1.2.1.1.5.0"};
|
||
//- 监测数据集合
|
||
List<String> pubDatas = new ArrayList<String>(); // 拼写数据格式
|
||
|
||
//- DetecDatas 拼写 Header
|
||
datasHeader(pubDatas);
|
||
|
||
int version = Common.getSnmpVerByUUID(Common.getIpSeqIdMap().get(ip));
|
||
// int version = SnmpConstants.version2c;
|
||
//-- 执行和解析 即获取详细数据
|
||
int state = -1;
|
||
|
||
Map<String, String> snmpDatas = new HashMap<String, String>() ;
|
||
StringBuffer stateInfo = new StringBuffer();
|
||
try {
|
||
Target target= null;
|
||
if(version == SnmpConstants.version3){
|
||
target = SNMP4JUtils.createUserTarget(ip, port+"", (int)maxTimes, (int)outTime*1000);
|
||
}else{
|
||
target = SNMP4JUtils.createCommunityTarget(ip, port+"", Constants.SNMP_COMMUNITY, (int)maxTimes, (int)outTime*1000, SnmpConstants.version2c);
|
||
}
|
||
SNMP4JUtils.snmpGet(snmpDatas, oidArray, target);
|
||
|
||
state = 1;
|
||
} catch (Exception e) {
|
||
state = -1;
|
||
stateInfo.append(e.getMessage());
|
||
logger.error((version == SnmpConstants.version3?"version3":"version2c")+" GET失败", e);
|
||
}
|
||
|
||
//- DetecDatas 拼写 Body
|
||
if(state==1 && snmpDatas.size()>0 && StringUtils.isNotBlank(snmpDatas.get(oidArray[0]))){
|
||
value = snmpDatas.get(oidArray[0]);
|
||
logger.debug((version == SnmpConstants.version3?"version3":"version2c")+" GET:"+oidArray[0]+" "+snmpDatas.get(oidArray[0]));
|
||
return true;
|
||
}else{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
private String[] pingHandshake(){
|
||
|
||
String command = ""; // 命令语句
|
||
int minTime = Integer.MAX_VALUE, maxTime = 0, totalTime = 0, curTime; // 最短时间,最长时间,总时间,时间变量
|
||
int snum = 0, fnum = 0; // 发包成功和失败数
|
||
|
||
// 判断系统类型 win or Linux
|
||
String system = (String) (System.getProperty("os.name")).toLowerCase();
|
||
|
||
if (system.indexOf("win") != -1) {
|
||
command += "ping -n 4 -w 4000 " + ip;
|
||
} else if (system.indexOf("linux") != -1) {
|
||
command += "ping -c 4 -w 4000 " + ip;
|
||
} else {
|
||
command += "ping " + ip;
|
||
}
|
||
|
||
String stateInfo = "";
|
||
String[] datas2 = new String[7];
|
||
Process process = null;
|
||
BufferedReader in = null; // 读取 Ping命令返回的信息
|
||
StringBuffer buffer = new StringBuffer();
|
||
try {
|
||
process = Runtime.getRuntime().exec(command);
|
||
in = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||
String line = null;
|
||
long count = maxTimes + 10;
|
||
int index;
|
||
// 最多多读10行
|
||
while ((line = in.readLine()) != null && count != 0) {
|
||
if ("".equals(line)) {
|
||
continue;
|
||
} // 空串跳过
|
||
buffer.append(line + "\n");
|
||
line = line.toLowerCase();
|
||
logger.debug("line:"+line);
|
||
if (line.indexOf("ttl") > 0) { // 获得成功响应的数据
|
||
count--; // 计数器自减1
|
||
// 截取time 值
|
||
if ((index = line.lastIndexOf("ms")) != -1) {
|
||
byte[] buf = line.getBytes();
|
||
int start = 0, end = buf.length, i, j;
|
||
// 下标末点
|
||
for (i = index; i >= 0; i--) {
|
||
if (Character.isDigit((char) buf[i])) {
|
||
end = i;
|
||
break;
|
||
}
|
||
}
|
||
if (i == 0)
|
||
continue;
|
||
// 下标起点
|
||
for (j = end; j >= 0; j--) {
|
||
if (!Character.isDigit((char) buf[j])) {
|
||
start = j + 1;
|
||
break;
|
||
}
|
||
}
|
||
// 时间值截取
|
||
curTime = Integer.parseInt(new String(buf, start,
|
||
end + 1 - start));
|
||
snum++; // 成功接收次数加1
|
||
totalTime += curTime; // 计算总时间
|
||
|
||
if (curTime < minTime) {
|
||
minTime = curTime;
|
||
} // 最小时间
|
||
|
||
if (curTime > maxTime) {
|
||
maxTime = curTime;
|
||
} // 最大时间
|
||
}
|
||
} else if (line.split(" ").length < 4) {
|
||
count--; // 计数器自减1
|
||
fnum++; // 失败接收次数加1
|
||
} else {
|
||
stateInfo += line + "\n";
|
||
}
|
||
}
|
||
|
||
if (totalTime == 0) {
|
||
minTime = 0;
|
||
}
|
||
|
||
// 已发送包数
|
||
datas2[0] = "" + (snum + fnum);
|
||
datas2[1] = "" + snum;
|
||
datas2[2] = "" + fnum;
|
||
|
||
BigDecimal fnum0 = new BigDecimal(fnum);
|
||
BigDecimal tnum0 = new BigDecimal(snum + fnum);
|
||
DecimalFormat df = new DecimalFormat("####0.00");
|
||
datas2[3] = ""
|
||
+ ((new BigDecimal(df.format(fnum0.divide(tnum0))))
|
||
.multiply(new BigDecimal(100)));
|
||
datas2[4] = "" + minTime;
|
||
datas2[5] = "" + maxTime;
|
||
datas2[6] = "" + (snum == 0 ? 0 : (totalTime / snum));
|
||
} catch (Exception e) {
|
||
logger.error(ExceptionPrintUtils.printExceptionStack(e));
|
||
}finally{
|
||
if(in!=null){try {
|
||
in.close();
|
||
} catch (IOException e) {
|
||
logger.error("",e);
|
||
}}
|
||
if(process!= null)process.destroy();
|
||
process = null;
|
||
}
|
||
|
||
/*if(state==-1){
|
||
isSuccess = false;
|
||
}else{
|
||
isSuccess = true;
|
||
}*/
|
||
return datas2;
|
||
}
|
||
|
||
//获得当前的报警设置信息,与相应字段值比较
|
||
private String[] getAlarmState(List<AlarmInfo> alarmInfos, String[] sysData){
|
||
String[] strs = null;
|
||
if(alarmInfos!=null){
|
||
strs = new String[]{"", "", ""};
|
||
for(AlarmInfo alarm : alarmInfos){
|
||
if(sysData.length>=alarm.getShowNum()){
|
||
Double data = Math.abs(Double.parseDouble(sysData[alarm.getShowNum()-1]));
|
||
if("equal".equals(alarm.getPoliceSysmbols())){
|
||
if((data+"").equals(alarm.getPoliceValue())){
|
||
strs[0] += alarm.getShowNum() + "|";// 告警序列号
|
||
strs[1] += alarm.getPoliceLevel() + "|"; //告警级别
|
||
strs[2] += alarm.getPoliceValue() + "|"; //告警值
|
||
}
|
||
}
|
||
else if("include".equals(alarm.getPoliceSysmbols())){
|
||
if((data+"").indexOf(alarm.getPoliceValue())!=-1){
|
||
strs[0] += alarm.getShowNum() + "|";// 告警序列号
|
||
strs[1] += alarm.getPoliceLevel() + "|"; //告警级别
|
||
strs[2] += alarm.getPoliceValue() + "|"; //告警值
|
||
}
|
||
}
|
||
else if("exclude".equals(alarm.getPoliceSysmbols())){
|
||
if((data+"").indexOf(alarm.getPoliceValue())==-1){
|
||
strs[0] += alarm.getShowNum() + "|";// 告警序列号
|
||
strs[1] += alarm.getPoliceLevel() + "|"; //告警级别
|
||
strs[2] += alarm.getPoliceValue() + "|"; //告警值
|
||
}
|
||
}
|
||
else{
|
||
double result = data - Double.parseDouble(alarm.getPoliceValue());
|
||
if ((">".equals(alarm.getPoliceSysmbols()) && result > 0)
|
||
|| ("<".equals(alarm.getPoliceSysmbols()) && result < 0)
|
||
|| ("=".equals(alarm.getPoliceSysmbols()) && result == 0)
|
||
|| (">=".equals(alarm.getPoliceSysmbols()) && result >= 0)
|
||
|| ("<=".equals(alarm.getPoliceSysmbols()) && result <=0) ) {
|
||
strs[0] += alarm.getShowNum() + "|";// 告警序列号
|
||
strs[1] += alarm.getPoliceLevel() + "|"; //告警级别
|
||
strs[2] += alarm.getPoliceValue() + "|"; //告警值
|
||
}
|
||
}
|
||
}
|
||
}
|
||
for(int i=0; i<strs.length; i++){
|
||
if(strs[i].length()>0){
|
||
strs[i] = strs[i].substring(0, strs[i].length()-1);
|
||
}
|
||
}
|
||
}
|
||
|
||
if(strs!=null && "".equals(strs[0])){
|
||
strs = null;
|
||
}
|
||
|
||
return strs;
|
||
}
|
||
|
||
public NMSClientForSNMPThread(String name,Long sitInfoId,String socketIp,long gap,long outTime,long maxTimes) {
|
||
this.name = name;
|
||
this.ip = socketIp;
|
||
this.sitInfoId = sitInfoId;
|
||
this.outTime = outTime;
|
||
this.maxTimes = maxTimes;
|
||
this.gap = gap;
|
||
}
|
||
|
||
/*public static void main(String [] args) {
|
||
Thread thread = new Thread(new NMSClientForSNMPThread("NMSC Thread",10l,"10.0.6.254",2,100,3));
|
||
// String name,Long sitInfoId,String socketIp,int socketPort,long gap,long outTime,long maxTimes
|
||
thread.start();
|
||
}*/
|
||
|
||
}
|