This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
nms-nmsserver/src/com/nms/server/thread/monitor/NMSClientForSNMPThread.java

440 lines
15 KiB
Java
Raw Normal View History

2018-09-27 16:17:06 +08:00
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();
}*/
}