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 datas = new ArrayList(); //拼写数据格式 已安全进入公共数据解析入口 //--初始部分数据整理 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 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 pubDatas = new ArrayList(); // 拼写数据格式 //- DetecDatas 拼写 Header datasHeader(pubDatas); int version = Common.getSnmpVerByUUID(Common.getIpSeqIdMap().get(ip)); // int version = SnmpConstants.version2c; //-- 执行和解析 即获取详细数据 int state = -1; Map snmpDatas = new HashMap() ; 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 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; i0){ 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(); }*/ }