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
2018-09-27 16:17:06 +08:00

440 lines
15 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
}*/
}