diff options
Diffstat (limited to 'src/com/nis/nmsclient/thread/alarm')
| -rw-r--r-- | src/com/nis/nmsclient/thread/alarm/AlarmPO.java | 146 | ||||
| -rw-r--r-- | src/com/nis/nmsclient/thread/alarm/AlarmThread.java | 315 | ||||
| -rw-r--r-- | src/com/nis/nmsclient/thread/alarm/AlarmUtil.java | 79 | ||||
| -rw-r--r-- | src/com/nis/nmsclient/thread/alarm/ErrorCode.java | 11 |
4 files changed, 551 insertions, 0 deletions
diff --git a/src/com/nis/nmsclient/thread/alarm/AlarmPO.java b/src/com/nis/nmsclient/thread/alarm/AlarmPO.java new file mode 100644 index 0000000..e1495ed --- /dev/null +++ b/src/com/nis/nmsclient/thread/alarm/AlarmPO.java @@ -0,0 +1,146 @@ +package com.nis.nmsclient.thread.alarm; + + +public class AlarmPO { + /** + * 监测ID + */ + private long id; + /** + * 监测类型 + */ + private String type; + /** + * 监测设置名称 + */ + private String procIden; + /** + * 时间间隔(单位:分钟) + */ + private long checkGap; + /** + * 是否是进程 + */ + private boolean isproc; + /** + * 进程路径与名称 + */ + private String proc; + /** + * PID文件 + */ + private String pidFileStr; + /** + * 进程搜索关键字 + */ + private String processSearchKeyCode; + /** + * 控制启动时间 + */ + private Long controlStartTime; + /** + * 是否系统启动(NMSAgent启动/第三方自己启动);默认0自启动;1NMSAgent启动 + */ + private String IsControlStart; + + public AlarmPO() { + super(); + } + + public AlarmPO(long id, String type, String procIden, long checkGap, + boolean isproc, String proc, String pidFileStr, + Long controlStartTime, String processSearchKeyCode, String IsControlStart) { + super(); + this.id = id; + this.type = type; + this.procIden = procIden; + this.checkGap = checkGap; + this.isproc = isproc; + this.proc = proc; + this.pidFileStr = pidFileStr; + this.controlStartTime = controlStartTime; + this.processSearchKeyCode = processSearchKeyCode; + this.IsControlStart = IsControlStart; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getProcIden() { + return procIden; + } + + public void setProcIden(String procIden) { + this.procIden = procIden; + } + + public long getCheckGap() { + return checkGap; + } + + public void setCheckGap(long checkGap) { + this.checkGap = checkGap; + } + + public boolean isIsproc() { + return isproc; + } + + public void setIsproc(boolean isproc) { + this.isproc = isproc; + } + + public String getProc() { + return proc; + } + + public void setProc(String proc) { + this.proc = proc; + } + + public String getPidFileStr() { + return pidFileStr; + } + + public void setPidFileStr(String pidFileStr) { + this.pidFileStr = pidFileStr; + } + + public Long getControlStartTime() { + return controlStartTime; + } + + public void setControlStartTime(Long controlStartTime) { + this.controlStartTime = controlStartTime; + } + + public String getProcessSearchKeyCode() { + return processSearchKeyCode; + } + + public void setProcessSearchKeyCode(String processSearchKeyCode) { + this.processSearchKeyCode = processSearchKeyCode; + } + + public String getIsControlStart() { + return IsControlStart; + } + + public void setIsControlStart(String isControlStart) { + IsControlStart = isControlStart; + } + +} diff --git a/src/com/nis/nmsclient/thread/alarm/AlarmThread.java b/src/com/nis/nmsclient/thread/alarm/AlarmThread.java new file mode 100644 index 0000000..41d989a --- /dev/null +++ b/src/com/nis/nmsclient/thread/alarm/AlarmThread.java @@ -0,0 +1,315 @@ +package com.nis.nmsclient.thread.alarm; + +import java.io.File; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; + +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.config.DetecConfOper; +import com.nis.nmsclient.util.DateUtil; +import com.nis.nmsclient.util.FileUtil; +import com.nis.nmsclient.util.ProcessUtil; +import com.nis.nmsclient.util.Utils; + +/** + * 主动报警线程:针对当前所有有效监测设置进行主动报警 + * 定时监测某设置是否正常生成数据,N次未取到数据后向Server报警,恢复正常后向Server发送提示信息 + * @date Mar 22, 2012 + * @author zhenzhen + * @version + */ +public class AlarmThread implements Runnable{ + Logger logger = Logger.getLogger(AlarmThread.class); + private String name; + + private Map<Long, AlarmStateMsg> alarmSmMap = new HashMap<Long, AlarmStateMsg>(); + + public AlarmThread(String name) { + super(); + this.name = name; + } + + public void run() { + Thread.currentThread().setName(name); + + logger.debug("主动预警检查开始 ~~~~~~~"); + try{ + Map<Long, AlarmPO> alarmPOs = new HashMap<Long, AlarmPO>(Common + .getAlarmPOs()); + // 清除垃圾数据 + if (alarmSmMap.size() > alarmPOs.size()) { + Iterator<Long> it = alarmSmMap.keySet().iterator(); + while (it.hasNext()) { + Long key = it.next(); + if(!alarmPOs.containsKey(key)){ + //alarmSmMap.remove(key); + it.remove();//update by jinsj for 2013-07-08 java.util.ConcurrentModificationException + } + } + + } + Set<Map.Entry<Long, AlarmPO>> entrys = alarmPOs.entrySet(); + int alarmCnt = 0; + StringBuffer alarmDescInfo = new StringBuffer(); + for (Map.Entry<Long, AlarmPO> entry : entrys) { + // 如果监测进程未启动,则不进行告警检查 + if (entry.getValue().getControlStartTime() != null + && entry.getValue().getControlStartTime() > System + .currentTimeMillis()) { + continue; + } + // 对各监测设置告警状态信息进行赋初值 + Long key = entry.getValue().getId(); + if (alarmSmMap.get(key) == null) { + alarmSmMap.put(key, new AlarmStateMsg(new Date(), 0, + new StringBuffer(), false)); + }else if(alarmSmMap.get(key).getAlarmMsg().length() == 0){ + alarmSmMap.get(key).setStart(new Date()); + } + + boolean flag = alarm(entry.getValue()); + if(flag){ + alarmCnt += 1; + alarmDescInfo.append("\tsetId: " + key + " >> " + entry.getValue().getType() + "_" + entry.getValue().getProcIden()); + alarmDescInfo.append("\n"); + } + } + logger.info("本次预警轮循检查监测设置总数:" + alarmPOs.size() + ",正常:" + + (alarmPOs.size() - alarmCnt) + ",不正常:" + alarmCnt); + if(alarmCnt>0){ + logger.info("本次预警检查不正常的监测如下:\n" + alarmDescInfo.toString()); + } + }catch (Exception e) { + logger.error("Active early warning thread exception:" + Utils.printExceptionStack(e)); + } + logger.debug("主动预警检查结束 ~~~~~~~"); + } + + /** + * 针对一个监测设置的主动预警具体逻辑实现 + * @param alarm + * @return true 告警监测不正常 false 监测正常 + * @throws Exception + */ + public boolean alarm(AlarmPO alarm) throws Exception{ + Long key = alarm.getId(); + String sonDirName = DetecConfOper.getFileName(alarm.getType(), alarm.getProcIden(), null); + StringBuffer sbMsg = new StringBuffer(); + /** + * 1、检查是否存在数据: alarmLevel 0 -- 数据存在,非0 -- 数据不存在 + */ + int alarmLevel = checkDataIsExist(sonDirName, alarm.getCheckGap(), sbMsg); + + /** + * 2、判断进程是否存在:是进程且数据不存在才判断,不是进程如系统类型CPU,则不进行这些操作 + */ + if(alarmLevel!=0 && alarm.isIsproc()){ + if("2".equals(alarm.getIsControlStart())) { // NC周期启动(脚本间断性执行且执行时间较短,通过判断Java定时任务确认进程) + if(Common.containPluginDetecFuture(key)){ // 进程存在 + String temp = sbMsg.toString(); + sbMsg.delete(0, sbMsg.length()); +// sbMsg.append("进程存在,但" + temp); + sbMsg.append("i18n_client.AlarmThread.processExists_n81i" + temp); + alarmLevel = 2; + } else { // 进程不存在 + sbMsg.delete(0, sbMsg.length()); +// sbMsg.append("定时任务“" + alarm.getType() + "”不存在"); + sbMsg.append("i18n_client.AlarmThread.loopMission1_n81i“" + alarm.getType() + "”i18n_client.AlarmThread.loopMission2_n81i"); + alarmLevel = 1; + } + } else { + Object[] objArr = ProcessUtil.checkPidAndGetPid(alarm.getPidFileStr(), alarm.getProcessSearchKeyCode()); + int isExistFlag = Integer.parseInt(objArr[0].toString()); + String pidInfo = objArr[1].toString(); + + if(isExistFlag==0){// 进程不存在(包括PID文件不存在,PID值不存在,搜索关键字也找不到进程) + sbMsg.delete(0, sbMsg.length()); + sbMsg.append(pidInfo); + alarmLevel = 1; + } else {// 进程存在(一个进程或多个进程) + String temp = sbMsg.toString(); + sbMsg.delete(0, sbMsg.length()); +// sbMsg.append("进程存在,但" + temp); + sbMsg.append("i18n_client.AlarmThread.processExists_n81i" + temp); + alarmLevel = 2; + } + } + } + + /** + * 3、统计并发送报警信息 + */ + AlarmStateMsg asMsg= alarmSmMap.get(key); + int times = asMsg.getTimes(); + boolean flag = true; + if (sbMsg.length()>0 && sbMsg.toString().equals(asMsg.getAlarmMsg().toString())) { + times ++ ; + + if (times == Contants.noDataTimes) {// Contants.noDataTime次未取到数据,报警 + AlarmUtil.sendAlarmMsg(alarm, asMsg.getStart(), new Date(), + alarmLevel, Contants.DETECTION_STATUS_ABNORMAL, asMsg + .getAlarmMsg().toString() +// + ",此状态持续了" + times + "次"); + + ",i18n_client.AlarmThread.state_n81i" + times + "i18n_client.AlarmThread.times_n81i"); + asMsg.setAlarmState(true); + } + } else if (sbMsg.length() > 0 + && !sbMsg.toString().equals(asMsg.getAlarmMsg().toString())) { + asMsg.getAlarmMsg().delete(0, asMsg.getAlarmMsg().length()); + asMsg.getAlarmMsg().append(sbMsg.toString()); + times = 1; + } else { + asMsg.getAlarmMsg().delete(0, asMsg.getAlarmMsg().length()); + times = 0; + if(asMsg.isAlarmState()){ + /*AlarmUtil.sendAlarmMsg(alarm, asMsg.getStart(), new Date(), + 99, Contants.DETECTION_STATUS_NORMAL, "恢复正常");*/ + asMsg.setAlarmState(false); + } + flag = false; + } + asMsg.setTimes(times); + alarmSmMap.put(key, asMsg); + + return flag; + } + + /** + * 检查是否存在数据 + * @param sonDirName + * @param checkGap + * @return + */ + private int checkDataIsExist(String sonDirName, long checkGap, StringBuffer sbMsg){ + int alarmLevel = 0; + // ------- 1、先查看当前正在写入的数据文件夹 + File curDir = new File(Contants.localDataFilePath + File.separator + sonDirName); + if(!curDir.exists()){ +// sbMsg.append("数据文件目录“" + curDir.getAbsolutePath() + "”不存在"); + sbMsg.append("i18n_client.AlarmThread.dataFileNotExists1_n81i“" + curDir.getAbsolutePath() + "”i18n_client.AlarmThread.dataFileNotExists2_n81i"); + alarmLevel = 1; + return alarmLevel; + } + long timeMillis = System.currentTimeMillis() - Contants.noDataTimes * checkGap * 60 * 1000; + File[] rightFiles = FileUtil.getFilesAfterMillis(curDir, timeMillis); + if(rightFiles!=null && rightFiles.length>0){// 找到数据,正常 + alarmLevel = 0; + return alarmLevel; + } + + // -------- 2、如果当前正在写入的数据文件夹没有找到符合条件的数据,则查找上传成功后备份到的相应目录 + // 2013-3-28 修改内容:原本只检查当天日期目录是否存在数据,针对监测时间间隔超过一天的存在问题,所以当间隔时间大于等于一天时,改为检查当天日期之前的目录 + String dateDirName = DateUtil.getCurrentDate(DateUtil.YYYYMMDD); + File doneDir = new File(Contants.localDataDonePath + File.separator + sonDirName); + if(doneDir.exists()){ + if(checkGap >= 1440){// --- 检查当天日期及之前的目录 + // 找到指定的日期目录及之前的日期目录,将其降序排列,是为了最先查找当天日期 + File[] dateDirs = FileUtil.sortDescByFileName(FileUtil.getDirsBeforeDateName(doneDir, dateDirName)); + // 在找到的日期目录下检查文件是否存在 + for(File dateDir : dateDirs){ + rightFiles = FileUtil.getFilesAfterMillis(dateDir, timeMillis); + if(rightFiles!=null && rightFiles.length>0){// 在任一目录找到则不再继续查找其他目录 + break; + } + } + }else {// --- 只检查当天日期 + File dateDir = new File(doneDir.getAbsolutePath() + File.separator + dateDirName); + if(dateDir.exists()){ + rightFiles = FileUtil.getFilesAfterMillis(dateDir, timeMillis); + } + } + } + if(rightFiles!=null && rightFiles.length>0){// 找到数据,正常 + alarmLevel = 0; + return alarmLevel; + } + + // -------- 3、查找不完整数据即0大小文件备份到的相应目录 + File[] errorFiles = null; + File errorDir = new File(Contants.localDataErrorPath + File.separator + sonDirName); + if(errorDir.exists()){ + if(checkGap >= 1440){// --- 检查当天日期及之前的目录 + // 找到指定的日期目录及之前的日期目录,将其降序排列,是为了最先查找当天日期 + File[] dateDirs = FileUtil.sortDescByFileName(FileUtil.getDirsBeforeDateName(errorDir, dateDirName)); + // 在找到的日期目录下检查文件是否存在 + for(File dateDir : dateDirs){ + errorFiles = FileUtil.getFilesAfterMillis(dateDir, timeMillis); + if(errorFiles!=null && errorFiles.length>0){// 在任一目录找到则不再继续查找其他目录 + break; + } + } + }else {// --- 只检查当天日期 + File dateDir = new File(doneDir.getAbsolutePath() + File.separator + dateDirName); + if(dateDir.exists()){ + errorFiles = FileUtil.getFilesAfterMillis(errorDir, timeMillis); + } + } + + } + if(errorFiles!=null && errorFiles.length>0){ +// sbMsg.append("监测数据文件大小为0"); + sbMsg.append("i18n_client.AlarmThread.dataSize_n81i"); + alarmLevel = 1; + }else{ +// sbMsg.append("未取到监测数据"); + sbMsg.append("i18n_client.AlarmThread.noDetecateData_n81i"); + alarmLevel = 1; + } + + return alarmLevel; + } + + /** + * 告警检查过程中针对每个监测设置的过程变量状态的封装类 + * @date Mar 22, 2012 + * @author zhenzhen + * @version + */ + class AlarmStateMsg { + private Date start;//告警检查不正常情况的开始时间 + private Integer times;//连续告警次数 + private StringBuffer alarmMsg;//告警信息 + private boolean alarmState;//是否向Server发送了主动告警请求 + + public AlarmStateMsg(Date start, Integer times, StringBuffer alarmMsg, + boolean alarmState) { + super(); + this.start = start; + this.times = times; + this.alarmMsg = alarmMsg; + this.alarmState = alarmState; + } + + public Date getStart() { + return start; + } + public void setStart(Date start) { + this.start = start; + } + public Integer getTimes() { + return times; + } + public void setTimes(Integer times) { + this.times = times; + } + public StringBuffer getAlarmMsg() { + return alarmMsg; + } + public void setAlarmMsg(StringBuffer alarmMsg) { + this.alarmMsg = alarmMsg; + } + public boolean isAlarmState() { + return alarmState; + } + public void setAlarmState(boolean alarmState) { + this.alarmState = alarmState; + } + } + +} diff --git a/src/com/nis/nmsclient/thread/alarm/AlarmUtil.java b/src/com/nis/nmsclient/thread/alarm/AlarmUtil.java new file mode 100644 index 0000000..1c0a76f --- /dev/null +++ b/src/com/nis/nmsclient/thread/alarm/AlarmUtil.java @@ -0,0 +1,79 @@ +package com.nis.nmsclient.thread.alarm; + +import java.util.Date; +import java.util.concurrent.Future; +import org.apache.log4j.Logger; +import com.nis.nmsclient.common.Common; +import com.nis.nmsclient.common.Contants; +import com.nis.nmsclient.config.DetecConfOper; +import com.nis.nmsclient.model.SetInfo; +import com.nis.nmsclient.thread.socket.CommonSocket; +import com.nis.nmsclient.thread.socket.SSLClient; +import com.nis.nmsclient.util.Utils; + +public class AlarmUtil { + static Logger logger = Logger.getLogger(AlarmUtil.class); + + public static void sendAlarmMsg(AlarmPO alarm, Date start, + Date end, int alarmLevel, int state, String alarmMsg,String... showNum) { + sendAlarmMsg(alarm.getId(), alarm.getType(), alarm + .getProcIden(), start, end, alarmLevel, state, alarmMsg,showNum); + } + + public static void sendAlarmMsg(Long alarmId, String checkType, + String procIden, Date start, Date end, int alarmLevel, int state, + String alarmMsg,String... showNum) { + String seprator = Contants.COMMON_MSG_SEPRATOR; + String showAlarmNum=""; + if (showNum!=null && showNum.length>0) + { + showAlarmNum = showNum[0]; + } + String msg = alarmId + seprator + Contants.AGENT_HOST_UUID + seprator + + checkType + seprator + procIden + seprator + start.getTime() + + seprator + end.getTime() + seprator + alarmLevel + seprator + + state + seprator + alarmMsg+ seprator + showAlarmNum; + + Common.service.submit(new SSLClient(Thread.currentThread() + .getName(), CommonSocket.REQ_ALARM, msg)); + + logger.warn("Active alarm level" + alarmLevel + " >> setId: " + alarmId + + "," + checkType + "_" + procIden + ",state: " + state + " > " + + alarmMsg+ ",showNum: " +showAlarmNum); + } + + public static AlarmPO getAlarmPO(SetInfo setInfo){ + AlarmPO alarmPO = new AlarmPO(setInfo.getId(), setInfo + .getCheckTypeName(), setInfo.getProcessIden(), setInfo + .getCheckGap(), DetecConfOper.isProcess(setInfo), DetecConfOper + .getProcess(setInfo), setInfo.getProcessFile(), setInfo + .getControlStartTime(), setInfo.getProcessSearchKeyCode(), + setInfo.getIsControlStart()); + + return alarmPO; + } + + // 向DC发送NC端的异常信息 + public static void sendNMSErrorMsg(ErrorCode errorCode, String errorIp, String errorDesc) { + String seprator = Contants.COMMON_MSG_SEPRATOR; + try { + //异常信息顺序:CODE、发送IP、发生错误IP、发生错误时间、处理状态(1)、错误描述 + String msg = errorCode.toString() + seprator + Utils.getLocalIp() + seprator + errorIp + + seprator + System.currentTimeMillis() + seprator + "1" + + seprator + errorDesc; + + Future<?> future = Common.service.submit(new SSLClient(Thread.currentThread() + .getName(), CommonSocket.REQ_ERROR_INFO, msg)); + + if(errorCode.equals(ErrorCode.ProtListenerError)){ + future.get(); + } + + logger.error("Abnormal information " + errorCode + " >> errorIp: " + errorIp + " > " + + errorDesc); + } catch (Exception e) { + logger.error(e); + } + + } +} diff --git a/src/com/nis/nmsclient/thread/alarm/ErrorCode.java b/src/com/nis/nmsclient/thread/alarm/ErrorCode.java new file mode 100644 index 0000000..0f62cb9 --- /dev/null +++ b/src/com/nis/nmsclient/thread/alarm/ErrorCode.java @@ -0,0 +1,11 @@ +package com.nis.nmsclient.thread.alarm; + +public enum ErrorCode { + ProcessNotExist, //进程不存在 + MultipleProcessExist,//多个进程存在 + ThreadRuntimeError, //执行异常 + HandShakeError, //通讯握手失败 + ProtListenerError, //端口监听失败 + DeamonNotExist, //守护进程不存在 + SocketError//通讯失败 +} |
