1265 lines
51 KiB
Java
1265 lines
51 KiB
Java
package com.nms.server.thread.detecData;
|
||
|
||
import java.io.File;
|
||
import java.sql.PreparedStatement;
|
||
import java.sql.SQLException;
|
||
import java.text.SimpleDateFormat;
|
||
import java.util.ArrayList;
|
||
import java.util.Arrays;
|
||
import java.util.Calendar;
|
||
import java.util.Collections;
|
||
import java.util.Comparator;
|
||
import java.util.ConcurrentModificationException;
|
||
import java.util.Date;
|
||
import java.util.HashMap;
|
||
import java.util.Iterator;
|
||
import java.util.LinkedList;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
import java.util.Map.Entry;
|
||
import java.util.concurrent.Callable;
|
||
|
||
import org.apache.commons.lang.StringUtils;
|
||
import org.apache.log4j.Logger;
|
||
|
||
import com.nms.server.bean.DetectInfo;
|
||
import com.nms.server.bean.EmailInfo;
|
||
import com.nms.server.bean.TableColumnsModel;
|
||
import com.nms.server.common.Common;
|
||
import com.nms.server.common.Constants;
|
||
import com.nms.server.common.EmailTypeConstants;
|
||
import com.nms.server.dao.CommonDao;
|
||
import com.nms.server.service.CommonService;
|
||
import com.nms.server.thread.socket.SSLClient;
|
||
import com.nms.server.util.CSVUtils;
|
||
import com.nms.server.util.FileUtils;
|
||
import com.nms.server.util.StringUtil;
|
||
|
||
/**
|
||
* CSV解析线程
|
||
* @author ZGGG3
|
||
*
|
||
*/
|
||
public class NewDetecDataResoveThread implements Callable<Object> {
|
||
Logger logger = Logger.getLogger(NewDetecDataResoveThread.class);
|
||
volatile boolean stop = false;//线程是否被取消标志
|
||
private String name; // 自定义Thread Name
|
||
private LinkedList<byte []> dsbList;
|
||
private SimpleDateFormat format2 = new SimpleDateFormat(Constants.COMMON_DATE_FORMAT); //Java Date 类型数据格式化格式
|
||
|
||
private long infoId = -1;
|
||
private long currentId = -1;
|
||
private long interval = -1;
|
||
private int warnResumeNum = 0;
|
||
private PreparedStatement infoNewInsertStmt;
|
||
private PreparedStatement infoNewUpdateStmt;
|
||
private List<Object[]> insertDataTonew;
|
||
private List<Object[]> updateDataTonew;
|
||
private PreparedStatement warnUpdateStmt;
|
||
public NewDetecDataResoveThread(String name,LinkedList<byte []> dsbList) {
|
||
this.name = name;
|
||
this.dsbList = dsbList;
|
||
}
|
||
|
||
/*
|
||
* 线程操作
|
||
*
|
||
* 依次解析urlList中仍存在的Files
|
||
*
|
||
* 实现了依次解析Files,由于后期实现多线程解析操作
|
||
*/
|
||
public Object call() {
|
||
// 为当前线程命名 ,用与开发阶段友好输出。
|
||
Thread.currentThread().setName(name +"-"+System.currentTimeMillis());
|
||
logger.info("配置文件设置批量入库监测数据条数:"+ Constants.DETECTION_INFO_DATA_MAX_ROWS);
|
||
CommonDao dao = null;
|
||
try {
|
||
dao = new CommonDao();
|
||
CommonService service = new CommonService(dao);
|
||
|
||
//-- 空数据集合 结束操作
|
||
if(dsbList == null || dsbList.size() == 0 ){
|
||
logger.debug("缓存监测数据 为空,无需解析");
|
||
return null;
|
||
}
|
||
|
||
//用于判断网络端口
|
||
long eNewTime = System.currentTimeMillis();
|
||
Map<String,List<String>> allPortName= service.getAllPortName();//之后如果数据大了,影响性能了,可以改成获取一个seqid的数据和一个端口的list,查询seqid,得到下标,再从list中获取信息,目前先暂时不改
|
||
long portTime = System.currentTimeMillis()-eNewTime;
|
||
int portTimeM=(int)portTime/1000/60;
|
||
int portTimeS=(int)((long)(portTime/1000)%60);
|
||
int portTimeMS=(int)portTime%1000;
|
||
logger.info("第零步:获取端口表的所有数据,总耗时:"+(portTimeM)+"分 "+(portTimeS)+"秒 "+(portTimeMS)+"毫秒");
|
||
|
||
|
||
logger.debug("缓存监测数据 " + (dsbList.size())+ "条,解析开始");
|
||
|
||
//-- 遍历解析
|
||
Iterator<byte []> dsbIte = dsbList.iterator();
|
||
int totalCount = dsbList.size();
|
||
int successCount=0;
|
||
int falseCount = 0;
|
||
int zeroByteCount = 0;
|
||
|
||
int count = 1;
|
||
int resoveCount=1;
|
||
int allResove = 0;
|
||
int allSuccess = 0;
|
||
int allFail = 0;
|
||
int allZero = 0;
|
||
/*
|
||
* 第一步:解析所有数据
|
||
* 新格式数据,旧格式同一放入 newDataMap 集合
|
||
*/
|
||
//存放解析之后的数据:[["systemdate",["5",["1602",[{detectInfo1,detectInfo2,...}]],...],...],...]
|
||
List<List<Object>> dataList = new LinkedList<List<Object>>();
|
||
long sTime = System.currentTimeMillis();
|
||
while (dsbIte.hasNext()&& !stop) {//线程未被中断
|
||
/* 单条解析异常捕捉处理 */
|
||
byte [] dsb = null;
|
||
try {
|
||
dsb = dsbIte.next();
|
||
/* 零字节文件记录和过滤 */
|
||
if (dsb != null && dsb.length > 0) {
|
||
/* 解析非0字节文件内容 */
|
||
List<String []> strsList = CSVUtils.csvBytesParser(dsb,Constants.COMMON_TEXT_CODING);
|
||
/* 新旧解析格式判断 */
|
||
/**
|
||
* 新旧解析格式区别:
|
||
* 区别:第一行基本信息数据 新格式12列固定比旧格式至少15列
|
||
* */
|
||
if(strsList!=null && strsList.size()>0){ //多行数据判断
|
||
Object[] detecInfo = null;
|
||
String [] detailsStr = strsList.get(0); //取第一行数据
|
||
|
||
if(detailsStr != null){
|
||
if(detailsStr.length > 12){//旧格式 解析
|
||
logger.debug("旧格式数据");
|
||
detecInfo = service.resoveOldData(strsList,allPortName);//解析数据,不判断状态变更
|
||
}else if(detailsStr.length<12){
|
||
logger.debug( "基本数据解析长度:"+detailsStr.length+" 小于最小解析标准,不予解析;");
|
||
}else{//新格式 解析
|
||
logger.debug("新格式数据");
|
||
detecInfo = service.resoveNewData(strsList,allPortName);//解析数据,不判断状态变更
|
||
}
|
||
}
|
||
|
||
//将解析之后的数据放入集合,不为空说明解析成功
|
||
if(detecInfo != null){
|
||
successCount++;//成功解析
|
||
detecAddToList(dataList, detecInfo);
|
||
}else{
|
||
falseCount ++;//解析失败
|
||
String filePath = getFilePath();//Constants.ERROR_DETEC_FILE_DIR+"/"+Common.getDateDirName()+"/"+Calendar.getInstance().getTimeInMillis()+".csv";
|
||
logger.error("Abnormal monitoring data format,file has been saved to "+filePath);
|
||
FileUtils.wirteBytesToFile(dsb, filePath);
|
||
}
|
||
}
|
||
}else{
|
||
zeroByteCount++;
|
||
}
|
||
|
||
//解析入库一条数据,从list中remove一条数据
|
||
dsbIte.remove();
|
||
//判断当前线程是否被中断
|
||
if (Thread.currentThread().isInterrupted()) {
|
||
// 线程中断状态,不会改变中断状态的值
|
||
logger.info("监测数据解析线程 被中断");
|
||
stop = true;//如果中断执行(重启、或者升级),就停止解析数据,之后将数据入库
|
||
}
|
||
}catch (InterruptedException e) {
|
||
logger.error("Monitoring data parsing threads are interrupted",e);
|
||
stop = true;
|
||
|
||
}catch (ConcurrentModificationException e) {
|
||
logger.debug("获取下一条监测数据 异常 停止本轮解析!",e);
|
||
stop = true;//由于获取next的时候出错,之后的都出错了就,所以此处stop=true,停止循环
|
||
}catch (Exception e) {
|
||
logger.debug("一条监测数据解析失败!",e);
|
||
}
|
||
|
||
if(count%Constants.BATCH_RESOVE_COUNT==0||stop||count==totalCount){
|
||
long resoveCurTime = System.currentTimeMillis();
|
||
long resoveTime = resoveCurTime-sTime;
|
||
int resoveTimeM=(int)resoveTime/1000/60;
|
||
int resoveTimeS=(int)((long)(resoveTime/1000)%60);
|
||
int resoveTimeMS=(int)resoveTime%1000;
|
||
logger.info("第一步:解析完毕,共:"+(resoveCount)+"条[成功:"+successCount+"条,失败:"+falseCount+"条,空数据:"+zeroByteCount+"条]"
|
||
+" 总耗时:"+(resoveTimeM)+"分 "+(resoveTimeS)+"秒 "+(resoveTimeMS)+"毫秒");
|
||
insertDataTonew=new ArrayList<Object[]>();
|
||
updateDataTonew=new ArrayList<Object[]>();
|
||
warnUpdateStmt=dao.getConn().prepareStatement(DetectInfo.getChangeWarningInfoSql());
|
||
judgeStateAndSave(dataList,sTime,resoveCount,successCount,falseCount,zeroByteCount,service, dao);
|
||
dataList.clear();
|
||
allResove = allResove + resoveCount;
|
||
allSuccess = allSuccess+ successCount;
|
||
allFail = allFail + falseCount;
|
||
allZero = allZero + zeroByteCount;
|
||
warnResumeNum = 0;
|
||
resoveCount=0;
|
||
successCount=0;
|
||
falseCount=0;
|
||
zeroByteCount=0;
|
||
}
|
||
resoveCount++;
|
||
count++;
|
||
}
|
||
dsbList.clear();
|
||
|
||
//将监测数据入库后,需要检查新入库的数据是否为无效(处理监测数据的有效性标志)
|
||
long startUpdateTime = System.currentTimeMillis();
|
||
updateDetectDataValid(dao);
|
||
long updateCurTime = System.currentTimeMillis()-startUpdateTime;
|
||
int updateCurTimeM=(int)updateCurTime/1000/60;
|
||
int updateCurTimeS=(int)((long)(updateCurTime/1000)%60);
|
||
int updateCurTimeMS=(int)updateCurTime%1000;
|
||
logger.info("第四步:更新监测数据有效性完毕,总耗时:"+(updateCurTimeM)+"分 "+(updateCurTimeS)+"秒 "+(updateCurTimeMS)+"毫秒");
|
||
|
||
|
||
long eTime = System.currentTimeMillis();
|
||
long curTime = eTime-sTime;
|
||
int m=(int)curTime/1000/60;
|
||
int s=(int)((long)(curTime/1000)%60);
|
||
int ms=(int)curTime%1000;
|
||
logger.info("第一到四步,整体解析批量入库监测数据全过程执行完毕,共:"+(allResove)+"条[成功:"+allSuccess+"条,失败:"+allFail+"条,空数据:"+allZero+"条]"
|
||
+" 总耗时:"+(m)+"分 "+(s)+"秒 "+(ms)+"毫秒");
|
||
|
||
} catch (Exception e) {
|
||
logger.error("Running exception",e);
|
||
}finally{
|
||
dao.closeCommonBatchStatement();
|
||
dao.closeDetailBatchStatement();
|
||
if(dao!=null){
|
||
dao.close();
|
||
dao=null;
|
||
}
|
||
//1:由web 主控控制入库
|
||
if(Constants.DETECT_INSERT_MODE == 1 ||Constants.DETECT_INSERT_MODE == 3){
|
||
//入库完成,通知web 主控释放锁
|
||
SSLClient.sengReleaseDetect();
|
||
}
|
||
logger.debug("数据清理 解析完成");
|
||
}
|
||
return null;
|
||
}
|
||
|
||
|
||
public void judgeStateAndSave(List<List<Object>> dataList,long sTime, int resoveCount, int successCount, int falseCount, int zeroByteCount, CommonService service,CommonDao dao) throws Exception{
|
||
/**
|
||
* 第二步:判断监测状态变更
|
||
*/
|
||
long resoveCurTime = System.currentTimeMillis();
|
||
if(dataList != null && dataList.size() >0){
|
||
for(List<Object> checkTypeList : dataList){
|
||
int checkTypeSize = checkTypeList.size();
|
||
for(int i = 1,j =checkTypeSize; i < j; i ++){
|
||
List<Object> setIdList = (List<Object>) checkTypeList.get(i);
|
||
String setId = (String) setIdList.get(0);//监测设置id
|
||
|
||
List<Object[]> detectionInfoNewData = null;
|
||
List<String> seqList = new ArrayList<String>();
|
||
int setIdSize = setIdList.size();
|
||
/**
|
||
* 2017年1月9日11:15:21 新增 添加过滤条件查询new表数据(只查询当前解析数据seqid的new表数据)
|
||
*/
|
||
for(int h = 1;h<setIdSize;h++){
|
||
List<Object> seqIdList = (List<Object>) setIdList.get(h);
|
||
String seqId = (String) seqIdList.get(0);//seqId
|
||
seqList.add(seqId);
|
||
}
|
||
/**以上*/
|
||
|
||
//获取new表中对应监测设置的监测数据
|
||
detectionInfoNewData = service.getDetectionInfoNewListBySet(setId,seqList);
|
||
for(int ii = 1; ii < setIdSize ; ii ++){
|
||
List<Object> seqIdList = (List<Object>) setIdList.get(ii);
|
||
String seqId = (String) seqIdList.get(0);//seqId
|
||
List<Object[]> allDeteInfo = (List<Object[]>) seqIdList.get(1);
|
||
if(allDeteInfo != null && allDeteInfo.size() > 0){
|
||
//detection_info_new中的 最新监测数据
|
||
Object[] oldDetecInfo = null;
|
||
if(detectionInfoNewData != null){//detectionInfoNewData:监测设置--节点--监测信息
|
||
oldDetecInfo = service.getIndexObj(seqList, seqId,detectionInfoNewData);
|
||
}else{
|
||
oldDetecInfo = null;
|
||
}
|
||
//数据库中没有当前监测类别对应的seqid节点的监测信息,不需要判断状态变更
|
||
if(oldDetecInfo != null){
|
||
if(allDeteInfo.size() <2 ){//只有一条数据直接比较数据库中的数据
|
||
//只有一条最新监测
|
||
Object[] newDetecInfo = allDeteInfo.get(0);
|
||
|
||
int state = (Integer) newDetecInfo[DetectInfo.STATE];
|
||
/*
|
||
* 入库数据不是延时数据时,与数据库中的最新数据比对判断状态变更
|
||
* 数据库中的监测时间小于当前需要入库的监测时间
|
||
*/
|
||
if((Long)oldDetecInfo[DetectInfo.CHECKTIME] < (Long)newDetecInfo[DetectInfo.CHECKTIME]){
|
||
/*判断状态变更*/
|
||
stateChange(newDetecInfo, oldDetecInfo);
|
||
}else{//监测时间小于数据库中监测数据的时间,说明当前需要入库的监测为延迟数据
|
||
if(state != 1){//延迟数据监测状态没有成功,数据库入库的是正常数据,补录一条报警信息
|
||
if((Integer) newDetecInfo[DetectInfo.STATE] == 1 && (Integer)oldDetecInfo[DetectInfo.PLEVEL] == 99){
|
||
newDetecInfo[DetectInfo.APPENDWARNINGINFO]= oldDetecInfo;
|
||
warnResumeNum++;
|
||
}
|
||
}
|
||
}
|
||
}else{//大于两条数据时,排序之后判断数据库的数据是否为最接近的时间数据
|
||
//未入库的数据排序
|
||
Collections.sort(allDeteInfo, new Comparator<Object[]>() {
|
||
@Override
|
||
public int compare(Object[] o1,
|
||
Object[] o2) {
|
||
Long time1 = (Long) o1[DetectInfo.CHECKTIME];
|
||
Long time2 = (Long) o2[DetectInfo.CHECKTIME];
|
||
return time1 < time2 ? -1 : 1;
|
||
}
|
||
});
|
||
/*判断状态变更*/
|
||
judgeState(allDeteInfo, oldDetecInfo);
|
||
}
|
||
judgeAndCollect(allDeteInfo, oldDetecInfo, updateDataTonew,service);
|
||
}else{//如果new表中没有数据,应为detection_info status_change_time设置初始值-->data_check_time
|
||
if(allDeteInfo!=null&&allDeteInfo.size()>0){
|
||
for (Object[] newInfo : allDeteInfo) {
|
||
if(newInfo[DetectInfo.STATUSCHANGTIME]==null||(Long)newInfo[DetectInfo.STATUSCHANGTIME]==-1){
|
||
newInfo[DetectInfo.STATUSCHANGTIME]=
|
||
newInfo[DetectInfo.CHECKTIME]==null?newInfo[DetectInfo.STARTTIME]:newInfo[DetectInfo.CHECKTIME];
|
||
}
|
||
}
|
||
insertDataTonew.addAll(allDeteInfo);
|
||
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//清理内存
|
||
detectionInfoNewData.clear();
|
||
detectionInfoNewData = null;
|
||
}
|
||
}
|
||
}
|
||
long stateCurTime = System.currentTimeMillis();
|
||
long stateCheckTime = stateCurTime-resoveCurTime;
|
||
int stateCheckM=(int)stateCheckTime/1000/60;
|
||
int stateCheckS=(int)((long)(stateCheckTime/1000)%60);
|
||
int stateCheck=(int)stateCheckTime%1000;
|
||
logger.info("第二步:判断监测状态变更完毕(只针对解析成功的),共:"+resoveCount+"条 总耗时:"+(stateCheckM)+"分 "+(stateCheckS)+"秒 "+(stateCheck)+"毫秒");
|
||
logger.info(" 第二步-1: 补录告警恢复告警信息:"+warnResumeNum+"条");
|
||
|
||
/**
|
||
* 第三步:批量入库
|
||
*/
|
||
//判断入库标示
|
||
if(Constants.FLAG_RESOVE_COMMIT_DB != 1){
|
||
String s = "file.resove.commitDB.flag 不为1,数据不可保存,请检查配置文件";
|
||
logger.warn(s);
|
||
// return null;
|
||
return ;
|
||
}
|
||
int failBatchInsert=0;
|
||
String failBatchInsertCheckType = "";//批量入库失败的监测类别信息
|
||
if(dataList != null && dataList.size() >0){
|
||
int infoCount = 0;
|
||
int detailCount = 0;
|
||
int sysinfoCount = 0;
|
||
int warnningCount = 0;
|
||
int statusChange = 0;
|
||
int emailCount = 0;
|
||
//监测设置对应的联系人email地址
|
||
Map<String,List<String>> setInfoEmail = null;
|
||
//未指定的监测设置通过seqid找到对应的联系人
|
||
Map<String,List<String>> seqIdEmail = null;
|
||
// List<String> logList = new ArrayList<String>();
|
||
dao.setAutoCommit(false);
|
||
LinkedList<byte []> dsbBatchList = new LinkedList<byte[]>();//用于批量入库后是否将监测数据存入硬盘的overrun :每次入库,或者存硬盘都需要清空此列表
|
||
|
||
//迭代器遍历,方便删除数据
|
||
Iterator<List<Object>> iteDataList = dataList.iterator();
|
||
while(iteDataList.hasNext()){
|
||
List<Object> checkTypeList = iteDataList.next();//["cpu",["1",["1602",[{detecAllInfo}]]]],
|
||
String checkType = (String) checkTypeList.get(0);//监测类型
|
||
|
||
int checkTypeRecordNum=0;//每种监测类别入库的记录数
|
||
String insertDetailSql = null;//插入详细参数
|
||
List<String> fieldNames = new ArrayList<String>();//detail表的字段名
|
||
//详细信息对应的表名
|
||
String detailTableName = Common.getInsertTable().get(checkType) == null ? null : Common.getInsertTable().get(checkType).getTableName();
|
||
if(detailTableName == null){
|
||
logger.error(checkType + " the corresponding detailed table was not found and the data could not be stored");
|
||
continue;
|
||
}
|
||
String seqId = null;
|
||
|
||
Iterator<Object> checkIte = checkTypeList.iterator();
|
||
boolean firstKey1 = true;
|
||
while(checkIte.hasNext()){
|
||
if(firstKey1){
|
||
checkIte.next();
|
||
firstKey1 = false;
|
||
}else{
|
||
List<Object> setIdList = (List<Object>) checkIte.next();//["1",["1602",[{detecAllInfo}]]]
|
||
String setInfoId = (String) setIdList.get(0);//监测设置id
|
||
Iterator<Object> setIte = setIdList.iterator();
|
||
boolean firstKey2 = true;
|
||
while(setIte.hasNext()){
|
||
if(firstKey2){
|
||
firstKey2 = false;
|
||
setIte.next();
|
||
}else{
|
||
List<Object> seqIdList = (List<Object>) setIte.next();//["1602",[{detecAllInfo,detecAllInfo}]]
|
||
seqId = (String) seqIdList.get(0);//seqid
|
||
List<Object[]> detecDatas = (List<Object[]>) seqIdList.get(1);//{detecAllInfo,detecAllInfo}
|
||
Iterator<Object[]> detecIte = detecDatas.iterator();
|
||
|
||
long statusChangeTime = -1;//状态变更时间
|
||
while(detecIte.hasNext()){
|
||
Object[] temInfo = detecIte.next();
|
||
//将解析之后的数据还原
|
||
byte[] dsb = objectToString(temInfo);
|
||
//将还原之后的数据缓存,出现异常时保存到文件
|
||
dsbBatchList.add(dsb);
|
||
if(temInfo != null){
|
||
// 计算 详细表的 外键 时间戳(10) + seqId(5)+ setId (3),主要是为了使用 java 中long 类型
|
||
String checkTime = temInfo[DetectInfo.CHECKTIME].toString();
|
||
String setId = temInfo[DetectInfo.SETINFOID].toString();
|
||
String seqid = temInfo[DetectInfo.SEQID].toString();
|
||
String id = DetectInfo.computeId(checkTime, seqId, setId);
|
||
// currentId = getSequenceId(service);
|
||
currentId = Long.parseLong(id);
|
||
//addbatch
|
||
service.addInfoStmt(currentId,temInfo);
|
||
|
||
infoCount ++;
|
||
logger.debug(" detection_info表id:" + currentId + ",监测类别:" + checkType +",监测设置id:" + setInfoId + ",seqId:" + seqId);
|
||
//添加详细信息
|
||
if((Boolean) temInfo[DetectInfo.DELYFLAG]){
|
||
//当delyFlag 为false时 不插入详细信息
|
||
List<Map<String,String>> details = (List<Map<String, String>>) temInfo[DetectInfo.DETAILS];
|
||
if(details!= null && details.size()>0 ){
|
||
for(Map<String,String> tempMap :details){
|
||
//首先组织sql语句
|
||
if(insertDetailSql == null || "".equals(insertDetailSql)){
|
||
//组织detail表的insert语句
|
||
insertDetailSql = createDetailSql(fieldNames,detailTableName,tempMap);
|
||
logger.debug("监测设置id: " + setInfoId +" ,detail表插入语句:" + insertDetailSql);
|
||
}
|
||
dao.setDetailVals(insertDetailSql,fieldNames,tempMap,currentId,detailTableName);
|
||
checkTypeRecordNum++;
|
||
detailCount ++;
|
||
}
|
||
}
|
||
}
|
||
//特殊格式追加信息
|
||
if(Constants.DETEC_SYSTEMINFO_STR.equalsIgnoreCase(checkType) ){
|
||
List<String[]> diskInfoList = (List<String[]>) temInfo[DetectInfo.DISKINFOLIST];
|
||
List<String[]> netInfoList = (List<String[]>) temInfo[DetectInfo.NETINFOLIST];
|
||
if(diskInfoList != null && diskInfoList.size() > 0){//disk
|
||
for(String[] temDiskInfo : diskInfoList){
|
||
if(temDiskInfo != null && temDiskInfo.length >7){
|
||
service.addDiskStmt(currentId,temDiskInfo);
|
||
sysinfoCount ++;
|
||
}
|
||
}
|
||
}
|
||
if(netInfoList != null && netInfoList.size() > 0){//net
|
||
for(String[] temNetInfo : netInfoList){
|
||
if(temNetInfo != null && temNetInfo.length >7){
|
||
service.addNetStmt(currentId,temNetInfo);
|
||
sysinfoCount ++;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//添加告警信息:告警信息=状态异常+状态改变+推迟入库的
|
||
if((Integer)temInfo[DetectInfo.STATE] != 1 || (Boolean)temInfo[DetectInfo.STATECHANGEFLAG]){
|
||
service.addWarningStmt(currentId +"",temInfo);
|
||
// logList.addAll(generateLog(dsb," 第三步-1: 添加一条告警信息,状态发生变更或者数据异常!state="+temInfo[DetectInfo.STATE]+",isChange="+(Boolean)temInfo[DetectInfo.STATECHANGEFLAG]));
|
||
warnningCount ++;
|
||
}
|
||
//延迟监测数据追加告警信息
|
||
if(temInfo[DetectInfo.APPENDWARNINGINFO] != null){
|
||
Object[] warningInfo = (Object[]) temInfo[DetectInfo.APPENDWARNINGINFO];
|
||
service.addWarningStmt((String)warningInfo[DetectInfo.DETECTIONINFOID],warningInfo);
|
||
// logList.addAll(generateLog(dsb," 第三步-1: 追加一条延迟数据的告警信息!"));
|
||
warnningCount ++;
|
||
}
|
||
//添加邮件信息
|
||
if(Constants.flag_email != 1){
|
||
logger.info("邮件功能已关闭");
|
||
}else{
|
||
if((Boolean) temInfo[DetectInfo.SENDEMAILFLAG]){
|
||
EmailInfo emailInfo = (EmailInfo) temInfo[DetectInfo.EMAILINFO];
|
||
if(emailInfo != null){
|
||
if(setInfoEmail == null){
|
||
setInfoEmail = service.getDetecSetEmailListOf123();
|
||
}
|
||
if(seqIdEmail == null){
|
||
seqIdEmail = service.getDetecEmailListOf4();
|
||
}
|
||
if((setInfoEmail == null || setInfoEmail.size() == 0) && (seqIdEmail == null || seqIdEmail.size() == 0)){
|
||
logger.debug("未找到邮件地址!");
|
||
}else{
|
||
List<String> emailAddress = null;
|
||
//1.首先通过监测设置的map中查找
|
||
if(setInfoEmail != null){
|
||
emailAddress = setInfoEmail.get(setInfoId);
|
||
}
|
||
if(emailAddress == null){
|
||
emailAddress = seqIdEmail.get(seqId);
|
||
}
|
||
if(emailAddress != null && emailAddress.size() >0){
|
||
for(String tempAddress : emailAddress){
|
||
if(StringUtils.isNotEmpty(tempAddress)){
|
||
emailCount ++;
|
||
//addbatch
|
||
service.addEmailStmt(emailInfo,tempAddress);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/*判断状态变更时间的最大时间,用于更新new表
|
||
当监测类型为 nmsclient 时,比较多条相同监测节点数据的状态变更时间,取最大的一个
|
||
*/
|
||
if(checkType.equalsIgnoreCase(Constants.DETEC_NMSC_STR)){
|
||
long temChangeTime = (Long) temInfo[DetectInfo.STATUSCHANGTIME];
|
||
if(temChangeTime > 0 ){
|
||
if(temChangeTime > statusChangeTime){
|
||
statusChangeTime = temChangeTime;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//dsbBatchList.add((byte[]) temInfo[27]);
|
||
//判断infoStmt的数量是否达到最大入库条数
|
||
/*if(infoCount != 0 && infoCount % Constants.DETECTION_INFO_DATA_MAX_ROWS == 0){
|
||
int dataLen = dsbBatchList.size();
|
||
try {
|
||
//执行批处理
|
||
dao.executeBatchAllStmt(false);
|
||
//提交事务
|
||
dao.commit();
|
||
} catch (SQLException e){
|
||
dao.rollback();
|
||
handleException(dsbBatchList, e);
|
||
failBatchInsert = failBatchInsert + dataLen;
|
||
failBatchInsertCheckType = failBatchInsertCheckType + checkType+" ";
|
||
}catch (Exception e) {
|
||
logger.error("批处理保存失败,数据库错误,共"+dataLen+"条",e);
|
||
dao.rollback();
|
||
|
||
//批量入库失败以后,要将失败的监测数据存到硬盘的overrun里,以备下次进行再次入库
|
||
Common.saveByteToFile(dsbBatchList);
|
||
failBatchInsert = failBatchInsert + dataLen;
|
||
failBatchInsertCheckType = failBatchInsertCheckType + checkType+" ";
|
||
}
|
||
dsbBatchList.clear();
|
||
}*/
|
||
detecIte.remove();//删除,内存优化
|
||
}
|
||
/*
|
||
* 更新状态变更时间
|
||
* 只有当监测类型:nmsclient 时,statusChangeTime才会大于0
|
||
*/
|
||
if(statusChangeTime > 0){
|
||
service.addStateChangeStmt(statusChangeTime,seqId);
|
||
statusChange++;
|
||
logger.info("状态变更详细信息:seqId="+seqId+" changeTime="+statusChangeTime);
|
||
}
|
||
}
|
||
setIte.remove();//删除监测设置
|
||
}
|
||
}
|
||
checkIte.remove();//删除监测设置,内存优化
|
||
}
|
||
iteDataList.remove();//删除监测类型,内存优化
|
||
|
||
int dataLastLen = dsbBatchList.size();
|
||
try{
|
||
//执行批处理
|
||
dao.executeBatchAllStmt(true);
|
||
service.saveToNew(insertDataTonew, 0, infoNewInsertStmt);
|
||
service.saveToNew(updateDataTonew, 1, infoNewUpdateStmt);
|
||
warnUpdateStmt.executeBatch();
|
||
//提交事务
|
||
dao.commit();
|
||
}catch (SQLException e){
|
||
logger.error("",e);
|
||
dao.rollback();
|
||
handleException(dsbBatchList, e);
|
||
failBatchInsert = failBatchInsert + dataLastLen;
|
||
failBatchInsertCheckType = failBatchInsertCheckType + checkType+" ";
|
||
}catch(Exception e){
|
||
logger.error("Batch save failed, database error, total"+dsbBatchList.size(),e);
|
||
dao.rollback();
|
||
//批量入库失败以后,要将失败的监测数据存到硬盘的overrun里,以备下次进行再次入库
|
||
logger.error("Monitoring data batch storage, database error, the file has been saved to the hard disk.");
|
||
Common.saveByteToFile(dsbBatchList);
|
||
failBatchInsert = failBatchInsert + dataLastLen;
|
||
failBatchInsertCheckType = failBatchInsertCheckType + checkType+" ";
|
||
}finally{
|
||
//关闭stmt:此处逻辑不太顺,最后会有一个对dao的整体的关闭,但是本线程中使用的都是自己定义的preparedstatement,不够统一
|
||
dao.closeDetailBatchStatement();
|
||
dsbBatchList.clear();
|
||
}
|
||
// logList.add(" 第三步-1: 监测类型:" + checkType +" ,批量入库结束,记录数: "+checkTypeRecordNum);
|
||
|
||
}
|
||
long endTime = System.currentTimeMillis();
|
||
long curTime = endTime-stateCurTime;
|
||
int m=(int)curTime/1000/60;
|
||
int s=(int)((long)(curTime/1000)%60);
|
||
int ms=(int)curTime%1000;
|
||
// logList.add(" 第三步-1: 共"+dataList.size()+" 种详细信息 " );
|
||
// logList.add(" 第三步-1: new表状态变更 共"+statusChange+" 条 " );
|
||
logger.info("第三步:批量保存入库完毕(只针对解析成功的),共:"+(dataList.size())+"条[共插入detection_info表: " + infoCount +" 条,detail表: " + detailCount +" 条,特殊追加信息: " + sysinfoCount +" 条,warning 表: " +warnningCount +" 条。]"
|
||
+" 总耗时:"+(m)+"分 "+(s)+"秒 "+(ms)+"毫秒,批量入库失败记录数:"+failBatchInsert+" 具体"+failBatchInsertCheckType);
|
||
// printLogs(logList);
|
||
}
|
||
|
||
}
|
||
|
||
public void handleException(LinkedList<byte[]> dsbBatchList,
|
||
SQLException e) {
|
||
try
|
||
{
|
||
//如果数据过错误是:1、ORA-01861:文字与格式字符串不匹配
|
||
// (一般情况下) 2、ORA-01400:不能将空值插入 3、ORA-01722:无效数字
|
||
// 4、ORA-00351:时间无效
|
||
// 5、ORA-01401: 插入的值过大
|
||
// 属于文件内容的错误所以保存到 错误文件夹中
|
||
|
||
int size = dsbBatchList.size();
|
||
if(e.getMessage().indexOf("ORA-01722")>=0
|
||
|| e.getMessage().indexOf("ORA-01400")>=0
|
||
|| e.getMessage().indexOf("ORA-01401")>=0
|
||
|| e.getMessage().indexOf("ORA-01861")>=0
|
||
|| e.getMessage().indexOf("ORA-00351")>=0){
|
||
logger.error("Monitoring data batch storage:Monitor data format exception,a total of"+size+",the file has been saved to "+getParentDirPath(),e);
|
||
for(int j=0;j<size;j++) {
|
||
byte[] data= dsbBatchList.get(0);//因为每次循环都会dataList.remove(0);所以每次操作的都是第0条记录
|
||
FileUtils.wirteBytesToFile(data, getFilePath());
|
||
}
|
||
}else{
|
||
//批量入库失败以后,要将失败的监测数据存到硬盘的overrun里,以备下次进行再次入库
|
||
logger.error("Monitoring data batch storage, database error,a total of "+size+",the file has been saved to the hard disk.",e);
|
||
Common.saveByteToFile(dsbBatchList);
|
||
}
|
||
|
||
} catch (Exception e2)
|
||
{
|
||
logger.error("Batch storage of hard disk abnormal after batch storage of abnormal monitoring data",e2);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 1.将解析之后的对象放进list
|
||
* 2.设置默认值
|
||
* @param dataList
|
||
* @param detecInfo
|
||
*/
|
||
public void detecAddToList(List<List<Object>> dataList,Object[] detecInfo){
|
||
String checkType = (String) detecInfo[DetectInfo.CHECKTYPE];
|
||
String setInfoId = (String) detecInfo[DetectInfo.SETINFOID];
|
||
String seqId = (String) detecInfo[DetectInfo.SEQID];
|
||
/**
|
||
* 设置默认值
|
||
*/
|
||
if(detecInfo[DetectInfo.STATE] == null){
|
||
detecInfo[DetectInfo.STATE] = -1;//state
|
||
}
|
||
if(detecInfo[DetectInfo.PLEVEL] == null){
|
||
detecInfo[DetectInfo.PLEVEL] = 99;//pLevel
|
||
}
|
||
if(detecInfo[DetectInfo.DELYFLAG] == null){
|
||
detecInfo[DetectInfo.DELYFLAG] = false;//delyFlag
|
||
}
|
||
if(detecInfo[DetectInfo.URGENTLEVEL] == null){
|
||
detecInfo[DetectInfo.URGENTLEVEL] = 0;//urgentLevel
|
||
}
|
||
if(detecInfo[DetectInfo.SENDEMAILFLAG] == null){
|
||
detecInfo[DetectInfo.SENDEMAILFLAG] = false;//sendEmailFlag
|
||
}
|
||
if(detecInfo[DetectInfo.STATECHANGEFLAG] == null){
|
||
detecInfo[DetectInfo.STATECHANGEFLAG] = false;//stateChangeFlag
|
||
}
|
||
if(detecInfo[DetectInfo.STATUSCHANGTIME] == null){
|
||
detecInfo[DetectInfo.STATUSCHANGTIME] = -1L;//statusChangeTime
|
||
}
|
||
|
||
if(dataList.size() == 0){
|
||
List<Object[]> detecList = new LinkedList<Object[]>();
|
||
detecList.add(detecInfo);
|
||
List<Object> seqList = new LinkedList<Object>();//seqid list
|
||
seqList.add(seqId);
|
||
seqList.add(detecList);
|
||
List<Object> setIdList = new LinkedList<Object>();//监测设置 id list
|
||
setIdList.add(detecInfo[DetectInfo.SETINFOID]);
|
||
setIdList.add(seqList);
|
||
List<Object> checkTypeList = new LinkedList<Object>();
|
||
checkTypeList.add(checkType);
|
||
checkTypeList.add(setIdList);
|
||
dataList.add(checkTypeList);
|
||
}else{
|
||
//第一层 checkType
|
||
for(int i = 0 , j = dataList.size(); i < j ; i ++){
|
||
List<Object> tempObj = dataList.get(i);
|
||
String key = (String)tempObj.get(0);//第一个为key
|
||
if(checkType.equals(key)){//监测类型已存在
|
||
for(int ii = 1 , jj = tempObj.size(); ii < jj ; ii ++){
|
||
List<Object> tempSet = (LinkedList<Object>) tempObj.get(ii);
|
||
String setKey = (String) tempSet.get(0);//监测设置id
|
||
if(setInfoId.equals(setKey)){
|
||
for(int iii = 1 ,jjj = tempSet.size(); iii < jjj; iii ++){
|
||
List<Object> tempSeq = (LinkedList<Object>) tempSet.get(iii);
|
||
String seqKey = (String) tempSeq.get(0);//监测设置id
|
||
if(seqId.equals(seqKey)){//seqId 存在
|
||
List<Object[]> detecList = (List<Object[]>) tempSeq.get(1);
|
||
detecList.add(detecInfo);
|
||
break;
|
||
}else if(iii == jjj -1){//seqid 不存在
|
||
List<Object[]> detecList = new LinkedList<Object[]>();
|
||
detecList.add(detecInfo);
|
||
List<Object> seqList = new LinkedList<Object>();//seqid list
|
||
seqList.add(seqId);
|
||
seqList.add(detecList);
|
||
tempSet.add(seqList);
|
||
}
|
||
}
|
||
break;
|
||
}else if(ii == jj-1){//监测设置id不存在
|
||
List<Object[]> detecList = new LinkedList<Object[]>();
|
||
detecList.add(detecInfo);
|
||
List<Object> seqList = new LinkedList<Object>();//seqid list
|
||
seqList.add(seqId);
|
||
seqList.add(detecList);
|
||
List<Object> setIdList = new LinkedList<Object>();//监测设置 id list
|
||
setIdList.add(detecInfo[DetectInfo.SETINFOID]);
|
||
setIdList.add(seqList);
|
||
tempObj.add(setIdList);
|
||
}
|
||
}
|
||
break;//跳出循环
|
||
}else if(i == j-1){//不存在
|
||
List<Object[]> detecList = new LinkedList<Object[]>();
|
||
detecList.add(detecInfo);
|
||
List<Object> seqList = new LinkedList<Object>();//seqid list
|
||
seqList.add(seqId);
|
||
seqList.add(detecList);
|
||
List<Object> setIdList = new LinkedList<Object>();//监测设置 id list
|
||
setIdList.add(detecInfo[DetectInfo.SETINFOID]);
|
||
setIdList.add(seqList);
|
||
List<Object> checkTypeList = new LinkedList<Object>();
|
||
checkTypeList.add(checkType);
|
||
checkTypeList.add(setIdList);
|
||
dataList.add(checkTypeList);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 组织detail表的insert语句
|
||
* @param fieldNames
|
||
* @param detailTableName
|
||
* @param tempMap
|
||
* @return
|
||
*/
|
||
public String createDetailSql(List<String> fieldNames,
|
||
String detailTableName, Map<String, String> tempMap) {
|
||
String insertDetailSql;
|
||
StringBuffer preSql = new StringBuffer();
|
||
StringBuffer sufSql = new StringBuffer();
|
||
preSql.append(",detection_info_id");
|
||
sufSql.append(",?");
|
||
fieldNames.add("detection_info_id");
|
||
for(String tempField : tempMap.keySet()){
|
||
fieldNames.add(tempField);
|
||
preSql.append("," + tempField);
|
||
String value = tempMap.get(tempField);
|
||
sufSql.append(",?");
|
||
}
|
||
insertDetailSql = "insert into "+detailTableName +" ( "+ preSql.substring(1) +" ) values (" + sufSql.substring(1) +" )";
|
||
return insertDetailSql;
|
||
}
|
||
|
||
/**
|
||
* 状态变更判断:只对大于等于new表监测时间的监测数据进行是否告警的判断
|
||
* @param allDetectInfo
|
||
* @param inDbInfo
|
||
*/
|
||
public void judgeState(List<Object[]> allDetectInfo , Object[] inDbInfo){
|
||
/*判断每一个的状态变更
|
||
* 1.监测时间小于已经入库的监测数据时间不做判断
|
||
* */
|
||
int startIndex = 0;
|
||
for(int i = 0, j = allDetectInfo.size(); i < j ; i++){
|
||
Object[] newDetecInfo = allDetectInfo.get(i);
|
||
Object[] oldDetecInfo = null;//前一条监测数据
|
||
//监测时间小于已经入库的监测数据时间不做判断,只在最后一条数据判断插入告警信息
|
||
if( newDetecInfo== null || (Long) newDetecInfo[DetectInfo.CHECKTIME] < (Long)inDbInfo[DetectInfo.CHECKTIME]){
|
||
startIndex++;
|
||
if(i < j -1){
|
||
continue;
|
||
}else{
|
||
//集合中的最后一条数据监测时间也小于数据库中的时间时,最后一条数据判断是否插入一条告警信息
|
||
if((Integer)newDetecInfo[DetectInfo.STATE] != 1){//延迟数据监测状态没有成功,数据库入库的是正常数据,补录一条报警信息
|
||
if((Integer)inDbInfo[DetectInfo.STATE] == 1 && (Integer)inDbInfo[DetectInfo.PLEVEL] == 99){
|
||
newDetecInfo[DetectInfo.APPENDWARNINGINFO] = oldDetecInfo;
|
||
warnResumeNum++;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//判断最新的监测数据
|
||
if(i== startIndex){
|
||
oldDetecInfo = inDbInfo;
|
||
}else{
|
||
oldDetecInfo = allDetectInfo.get(i-1);
|
||
}
|
||
/*判断状态变更*/
|
||
stateChange(newDetecInfo, oldDetecInfo);
|
||
}
|
||
|
||
}
|
||
/**
|
||
* 判断状态变更具体实现
|
||
* @param newDetecInfo
|
||
* @param oldDetecInfo
|
||
*/
|
||
public void stateChange(Object[] newDetecInfo,Object[] oldDetecInfo ){
|
||
/**
|
||
* 判断状态变更
|
||
*/
|
||
|
||
if(newDetecInfo == null || oldDetecInfo == null
|
||
|| ((Long)newDetecInfo[DetectInfo.CHECKTIME] < (Long)oldDetecInfo[DetectInfo.CHECKTIME])){
|
||
return;
|
||
}
|
||
if(((Integer)oldDetecInfo[DetectInfo.STATE] != (Integer)newDetecInfo[DetectInfo.STATE]) || //状态改变
|
||
(((Integer)oldDetecInfo[DetectInfo.STATE] == (Integer)newDetecInfo[DetectInfo.STATE]
|
||
&& (Integer)oldDetecInfo[DetectInfo.PLEVEL]!= (Integer)newDetecInfo[DetectInfo.PLEVEL] ))){//状态未变,告警级别改变
|
||
|
||
int state = (Integer)newDetecInfo[DetectInfo.STATE];
|
||
//邮件告警信息
|
||
StringBuffer alarmInfo = new StringBuffer((String)newDetecInfo[DetectInfo.ALARMINFO]);//告警信息
|
||
String dsinfo = (String) newDetecInfo[DetectInfo.DSINFO];//状态信息
|
||
String checkType = (String) newDetecInfo[DetectInfo.CHECKTYPE];//监测类别
|
||
long checkTime = (Long) newDetecInfo[DetectInfo.CHECKTIME];
|
||
int actionType = 11;
|
||
int urgentLevel = EmailTypeConstants.URGENT_LATER;
|
||
//整理告警数据,拼写邮件信息
|
||
if(state == -1){ //执行失败
|
||
// alarmInfo.append("监测执行失败\n ");
|
||
// alarmInfo.append("Failure to monitor execution\n ");
|
||
alarmInfo.append("i18n_server.DetecDataResoveThread.alarmInfo1_n81i\n ");
|
||
alarmInfo.append(dsinfo+"\n");
|
||
actionType= EmailTypeConstants.TYPE_DETECTION_INFO_EXCEPTION;
|
||
if(Constants.DETEC_NMSC_STR.equalsIgnoreCase(checkType)) {
|
||
urgentLevel = EmailTypeConstants.URGENT_IMMEDIATELY;
|
||
|
||
}
|
||
}else if(state == 0){ //一般异常
|
||
alarmInfo.append(" "+dsinfo+"\n");
|
||
//如果是握手监测,不添加告警设置字段相关信息
|
||
if(!Constants.DETEC_NMSC_STR.equalsIgnoreCase(checkType)) {
|
||
alarmInfo.append(dsinfo+" \n");
|
||
}else {
|
||
alarmInfo.delete(0,alarmInfo.length());//如果是握手监测,则不添加告警设置字段相关信息
|
||
alarmInfo.append(dsinfo+" \n");
|
||
urgentLevel = EmailTypeConstants.URGENT_IMMEDIATELY;
|
||
}
|
||
actionType= EmailTypeConstants.TYPE_DETECTION_INFO_EXCEPTION;
|
||
}else if(state == 1){ //恢复正常
|
||
// alarmInfo.append("监测恢复正常");
|
||
// alarmInfo.append("Monitoring back to normal");
|
||
alarmInfo.append("i18n_server.DetecDataResoveThread.alarmInfo1_n81i");
|
||
actionType= EmailTypeConstants.TYPE_DETECTION_INFO_RECOVER;
|
||
urgentLevel = EmailTypeConstants.URGENT_LATER;
|
||
//更新该节点所有监测时间为当前监测时间
|
||
if(checkType.equalsIgnoreCase(Constants.DETEC_NMSC_STR)){
|
||
newDetecInfo[DetectInfo.STATUSCHANGTIME] = (checkTime);
|
||
}
|
||
}
|
||
// 报警通知
|
||
|
||
newDetecInfo[DetectInfo.STATECHANGEFLAG] = (true);
|
||
newDetecInfo[DetectInfo.ALARMINFO] = (alarmInfo.toString());
|
||
newDetecInfo[DetectInfo.SENDEMAILFLAG] = (true);
|
||
newDetecInfo[DetectInfo.URGENTLEVEL] = (urgentLevel);
|
||
//目前代码中是否紧急和紧急级别不对应,有的是紧急,但是级别是2,所以此处进行修改,如果是紧急,则级别修改为0级
|
||
if(EmailTypeConstants.URGENT_IMMEDIATELY==urgentLevel){
|
||
newDetecInfo[DetectInfo.PLEVEL] = Constants.LEVEL_OF_EMERGENCY;
|
||
}
|
||
//如果是0级,则设置为紧急,使得紧急状态和级别一致
|
||
if(newDetecInfo[DetectInfo.PLEVEL].equals(Constants.LEVEL_OF_EMERGENCY)){
|
||
newDetecInfo[DetectInfo.URGENTLEVEL] = EmailTypeConstants.URGENT_IMMEDIATELY;
|
||
}
|
||
long seqIdLong = Long.parseLong((String)newDetecInfo[DetectInfo.SEQID]);
|
||
long setInfoIdLong = Long.parseLong((String)newDetecInfo[DetectInfo.SETINFOID]);
|
||
|
||
String emailContent = alarmInfo.toString();
|
||
if(emailContent.getBytes().length>290){
|
||
emailContent = StringUtil.substring(emailContent,290);
|
||
}
|
||
|
||
EmailInfo emailInfo = new EmailInfo(actionType,Common.getSetInfoNameMape().get(setInfoIdLong)+"("+Common.getCheckTypeNameMape().get(checkType)+")",Common.getNodeIpByUUID(seqIdLong), format2.format(new Date(checkTime)),emailContent,EmailTypeConstants.FLAG_SEND_LATER,urgentLevel);
|
||
|
||
newDetecInfo[DetectInfo.EMAILINFO] = (emailInfo);
|
||
//如果新入数据和new表中的监测状态不同,或者监测状态相同,告警级别不同 ,修改 状态改变时间 为获取新入数据的时间(data_check_time)
|
||
newDetecInfo[DetectInfo.STATUSCHANGTIME]=newDetecInfo[DetectInfo.CHECKTIME];
|
||
}
|
||
else{//如果新入数据和new表中的监测状态相同,且告警级别相同 ,则状态改变时间更新为new表中的时间
|
||
newDetecInfo[DetectInfo.STATUSCHANGTIME]=oldDetecInfo[DetectInfo.STATUSCHANGTIME];
|
||
}
|
||
}
|
||
/**
|
||
* id 和 currentId 同时 = -1时,为第一次获取sequence id
|
||
* result[0] 为currentID
|
||
* result[1] 为基准id,获取的sequence id
|
||
* @param id
|
||
* @param currentId
|
||
* @return
|
||
*/
|
||
public long getSequenceId(CommonService service){
|
||
|
||
long result = -1L;
|
||
if( infoId != -1 && currentId != -1 && currentId < (infoId + interval -1) && interval != -1){
|
||
currentId ++;
|
||
result = currentId;
|
||
}else{
|
||
//-- 申请sequences for detection_info
|
||
long[] temp = service.getDetectionInfoSequenceID();
|
||
if(temp[0] > 0){
|
||
result = infoId = currentId = temp[0];//获取的id
|
||
interval = temp[1];//步进
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
|
||
/**
|
||
*
|
||
* 获取文件路径,判断当天目录下的文件如果>=500个,则新创建父目录,
|
||
* 创建父目录的原则是"日期_1"、"日期_2"、"日期_3"累加的形式
|
||
*
|
||
* @author jsj Apr 28, 2013
|
||
* @version 1.0
|
||
* @return
|
||
*/
|
||
private String getFilePath()
|
||
{
|
||
String filePath = "";
|
||
try
|
||
{
|
||
String parentDirPath = getParentDirPath();
|
||
filePath = parentDirPath + "/" + Calendar.getInstance().getTimeInMillis() + ".csv";
|
||
|
||
} catch (Exception e)
|
||
{
|
||
logger.error("Getting the error file path exception", e);
|
||
}
|
||
return filePath;
|
||
}
|
||
|
||
/**
|
||
*
|
||
*获取文件的父目录
|
||
* 获取当天的父母目录,如果父目录不存在,则为第一次写入文件,直接返回当天的目录,
|
||
存在则判断目录下的文件是否>-500,>=500则新建日期目录,否则取当前目录
|
||
* @author jsj Apr 28, 2013
|
||
* @version 1.0
|
||
* @return
|
||
*/
|
||
private String getParentDirPath()
|
||
{
|
||
String parentDirPath = Constants.ERROR_DETEC_FILE_DIR;
|
||
String currentDirName = Common.getDateDirName();
|
||
String dirPath = parentDirPath + "/" + currentDirName;
|
||
File parentDirFile = new File(parentDirPath);
|
||
List<File> existDir = new ArrayList<File>();
|
||
|
||
if (parentDirFile.exists())
|
||
{
|
||
File[] dirFiles = parentDirFile.listFiles();
|
||
if (dirFiles.length > 0)
|
||
{
|
||
for (File dirFile: dirFiles)
|
||
{
|
||
if (dirFile.getName().contains(Common.getDateDirName()))
|
||
{
|
||
existDir.add(dirFile);
|
||
}
|
||
}
|
||
}
|
||
|
||
} else
|
||
{
|
||
return dirPath;
|
||
}
|
||
|
||
boolean isGetFile = false;
|
||
|
||
for (File dirFile: existDir)
|
||
{
|
||
File[] files = dirFile.listFiles();
|
||
if (currentDirName.compareTo(dirFile.getName()) < 0)
|
||
{
|
||
currentDirName = dirFile.getName();
|
||
}
|
||
if (files.length < Constants.ERROR_DETEC_FILE_DIR_FILE_SIZES)
|
||
{
|
||
dirPath = dirFile.getAbsolutePath();
|
||
isGetFile = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!isGetFile)
|
||
{
|
||
String[] currentDirNames = currentDirName.split("_");
|
||
if (currentDirNames.length == 1)
|
||
{
|
||
currentDirName += "_1";
|
||
} else
|
||
{
|
||
currentDirName = currentDirNames[0] + "_"
|
||
+ +(Integer.parseInt(currentDirNames[1]) + 1);
|
||
}
|
||
dirPath = parentDirPath + "/" + currentDirName;
|
||
}
|
||
return dirPath;
|
||
}
|
||
|
||
|
||
//检查入库的监测数据中是否有无效的数据,有则置为无效
|
||
public void updateDetectDataValid(CommonDao dao) throws Exception{
|
||
CommonService service = new CommonService(dao);
|
||
Map<String,String> detectSetSeqIdMap = service.getDetectSetInfo();//查询有效监测数值对应的seqid
|
||
Map<String,String[]> detectDataSeqIdMap = service.getDetectSeq(Constants.DETECTION_INFO_TABLE_NAME);//统计 监测数据 表: 监测设置<->已有有效数据的seqid
|
||
Iterator detectDateSeqIte = detectDataSeqIdMap.entrySet().iterator();
|
||
String invalidSeqIds = "";
|
||
List<String> sqls = new ArrayList<String>();
|
||
while(detectDateSeqIte.hasNext()) {
|
||
invalidSeqIds = "";
|
||
Entry en = (Entry)detectDateSeqIte.next();
|
||
String setId = (String)en.getKey();
|
||
String seqIdsValid = detectSetSeqIdMap.get(setId);//得到监测设置当前有效的seqids:1,2,3
|
||
if(seqIdsValid!=null) {//如果有效的监测设置内没有此监测设置,则不予处理
|
||
seqIdsValid = "," + seqIdsValid + ",";
|
||
String[] seqIds = (String[])en.getValue();
|
||
for(String seqIdTmp:seqIds) {
|
||
if(seqIdTmp!=null && !"".equals(seqIdTmp)) {
|
||
if(!seqIdsValid.contains(","+seqIdTmp+",")) {//不在有效范围内,则更新为无效
|
||
invalidSeqIds = invalidSeqIds + seqIdTmp + ",";
|
||
}
|
||
}
|
||
}
|
||
if(invalidSeqIds.endsWith(",")) {
|
||
invalidSeqIds = invalidSeqIds.substring(0,invalidSeqIds.length()-1);
|
||
sqls.add("update "+Constants.DETECTION_INFO_TABLE_NAME+" t set valid=0 where t.valid=1 and t.detection_set_info_id="+setId+" and t.seq_id in ("+invalidSeqIds+")");
|
||
}
|
||
}
|
||
}
|
||
if(sqls.size()>0){//一般情况下不需要更新,所以,如果不加if判断,则每次都会浪费时间去创建statement
|
||
dao.dbUpdateByBatch(sqls);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
*打印统计的监测数据:监测类别--监测设置--节点--监测信息
|
||
*/
|
||
private void printDetectDataInfo(Map<String, Map<String,Map<String,List<Object[]>>>> newDataMap) {
|
||
/**
|
||
*打印统计的监测数据:监测类别--监测设置--节点--监测信息
|
||
*/
|
||
if(newDataMap != null && newDataMap.size()>0){
|
||
logger.debug("解析完毕:共" +newDataMap.size()+ "个监测类型");
|
||
for(Map.Entry<String, Map<String,Map<String,List<Object[]>>>> setInfoIdMap :newDataMap.entrySet()){
|
||
logger.debug("监测类型: " + setInfoIdMap.getKey() + " 共有:" + setInfoIdMap.getValue().size() +" 个监测设置项");
|
||
if(setInfoIdMap.getValue() != null){
|
||
for(Map.Entry<String, Map<String,List<Object[]>>> me : setInfoIdMap.getValue().entrySet() ){
|
||
if(me.getValue() != null){
|
||
logger.debug("监测设置id: " + me.getKey() + " 共包含:" + me.getValue().size() +" 节点");
|
||
for(Map.Entry<String, List<Object[]>> seqMe : me.getValue().entrySet()){
|
||
if(seqMe.getValue() != null){
|
||
logger.debug("seqId : " + seqMe.getKey() + " 共包含:" + seqMe.getValue().size() +" 条监测数据");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 将解析之后的监测数据写入到文件
|
||
* @param temInfo
|
||
* @param file
|
||
* @return
|
||
*/
|
||
private byte[] objectToString(Object[] temInfo){
|
||
byte[] dsb = null;
|
||
try {
|
||
// ------- 总监测数据组织
|
||
int index = 0;
|
||
String[] totalData = new String[12];
|
||
totalData[index++] = (String) temInfo[DetectInfo.SEQID];// UUID
|
||
totalData[index++] = (String) temInfo[DetectInfo.SETINFOID];// 监测设置ID
|
||
String checkType = totalData[index++] = (String) temInfo[DetectInfo.CHECKTYPE];// 监测类别
|
||
totalData[index++] = (String) temInfo[DetectInfo.PROCESS];// 进程名称
|
||
totalData[index++] = temInfo[DetectInfo.STARTTIME] +"";// 监测服务启动时间
|
||
totalData[index++] = temInfo[DetectInfo.DELAYTIME] +"";// 检测时延(秒)
|
||
totalData[index++] = temInfo[DetectInfo.CHECKTIME]+ "";// 本次检测时间
|
||
totalData[index++] = temInfo[DetectInfo.CURRENTTIMES] + "";// 尝试次数
|
||
totalData[index++] = temInfo[DetectInfo.NEXTCHECKTIME]+"";// 下次计划监测时间
|
||
totalData[index++] = temInfo[DetectInfo.STATE] + "";// 执行状态是否成功是否正常
|
||
totalData[index++] = temInfo[DetectInfo.DSINFO] +"";// 状态信息(描述信息)
|
||
totalData[index++] = temInfo[DetectInfo.PDATA] +"";// 性能数据
|
||
|
||
/**
|
||
* 详细数据前三个告警相关信息
|
||
*/
|
||
List<String> showNumList = (List<String>) temInfo[DetectInfo.SHOWNUMLIST];
|
||
List<String> plevelList = (List<String>) temInfo[DetectInfo.PLEVELLIST];
|
||
List<String> alarmList = (List<String>) temInfo[DetectInfo.ALARMLIST];
|
||
|
||
List<String[]> dataList = new LinkedList<String[]>();
|
||
// 总数据
|
||
dataList.add(totalData);
|
||
|
||
//详细信息
|
||
List<Map<String,String>> details = (List<Map<String, String>>) temInfo[DetectInfo.DETAILS];
|
||
if(details != null && details.size() > 0){
|
||
Map<Integer, TableColumnsModel> tableMap = Common.getTableMap().get(checkType);
|
||
Map<String,Integer> fieldMap = fieldNameToLower(tableMap);//将表字段名称转换成小写
|
||
// 详细信息
|
||
dataList.add(new String[]{"details", details.size()+ ""});// details(解析标识),详细信息条数
|
||
List<String[]> detailDataList = new LinkedList<String[]>();
|
||
int listIndex = 0;
|
||
for(Map<String,String> temp : details){
|
||
//单条详细信息
|
||
String[] tempDetail = new String[tableMap.size() + 4];
|
||
tempDetail[0] = showNumList.get(listIndex);
|
||
tempDetail[1] = plevelList.get(listIndex);
|
||
tempDetail[2] = alarmList.get(listIndex);
|
||
for(Map.Entry<String, String> tempEntry : temp.entrySet()){
|
||
String fieldName = tempEntry.getKey().toLowerCase();
|
||
if("seq_id".equals(fieldName) || //解析时添加的数据跳过
|
||
"detectioned_state".equals(fieldName) ||
|
||
"detection_set_info_id".equals(fieldName) ||
|
||
"data_check_time_digital".equals(fieldName) ||
|
||
"data_check_time".equals(fieldName) ||
|
||
"data_arrive_time_digital".equals(fieldName) ||
|
||
"data_arrive_time".equals(fieldName) ){
|
||
continue;
|
||
}
|
||
String value = tempEntry.getValue();
|
||
int arrIndex = fieldMap.get(fieldName) + 2;
|
||
tempDetail[arrIndex] = value;
|
||
}
|
||
detailDataList.add(tempDetail);
|
||
listIndex ++;
|
||
}
|
||
|
||
dataList.addAll(detailDataList);// 具体的详细数据
|
||
|
||
// 特殊数据定制(目前是针对系统信息监测systeminfo)
|
||
if ("systeminfo".equalsIgnoreCase(checkType)) {
|
||
List<String[]> netList = (List<String[]>) temInfo[DetectInfo.NETINFOLIST];
|
||
if(netList != null && netList.size() > 0){
|
||
dataList.add(new String[]{"net", netList.size() + ""});// 解析标识, 行数(当前解析标识指定的类型有多少条数据)
|
||
dataList.addAll(netList);// 多条数据
|
||
}
|
||
List<String[]> diskList = (List<String[]>) temInfo[DetectInfo.DISKINFOLIST];
|
||
if(netList != null && diskList.size() > 0){
|
||
dataList.add(new String[]{"disk", netList.size() + ""});// 解析标识, 行数(当前解析标识指定的类型有多少条数据)
|
||
dataList.addAll(diskList);// 多条数据
|
||
}
|
||
}
|
||
}
|
||
dsb = CSVUtils.csvBytesPrinter1(dataList, Constants.COMMON_TEXT_CODING);
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
logger.error("Conversion from Object[] to byte[] failure",e);
|
||
}
|
||
return dsb;
|
||
}
|
||
/**
|
||
* 表字段名称全部转换成小写,并fieldName做key
|
||
* @param tableMap
|
||
* @return
|
||
*/
|
||
private Map<String,Integer> fieldNameToLower(Map<Integer, TableColumnsModel> tableMap){
|
||
Map<String,Integer> result = new HashMap<String,Integer>();
|
||
if(tableMap != null && tableMap.size()>0){
|
||
for(Map.Entry<Integer, TableColumnsModel> temp : tableMap.entrySet()){
|
||
TableColumnsModel column = temp.getValue();
|
||
if(column != null){
|
||
result.put(column.getFiledName().toLowerCase(), temp.getKey());
|
||
}
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
|
||
private List<String> generateLog(byte[] info,String head) {
|
||
List<String> warnInfoList = new ArrayList<String>();
|
||
try
|
||
{
|
||
//byte[] info = (byte[]) temInfo[27];
|
||
List<String []> strsList = CSVUtils.csvBytesParser(info,Constants.COMMON_TEXT_CODING);
|
||
String time = System.currentTimeMillis()+"";
|
||
for(String[] strArr:strsList) {
|
||
// logger.info(head+" "+time +" "+StringUtils.join(strArr,","));
|
||
warnInfoList.add(head+" "+time +" "+StringUtils.join(strArr,","));
|
||
}
|
||
|
||
} catch (Exception e){
|
||
}
|
||
return warnInfoList;
|
||
}
|
||
|
||
private void printLogs(List<String> logList) {
|
||
for(String log:logList){
|
||
logger.info(log);
|
||
}
|
||
}
|
||
private void judgeAndCollect(List<Object[]> allDeteInfo, Object[] oldDetecInfo,List<Object[]> newDataList,CommonService service){
|
||
Object[] newDeteInfo = allDeteInfo.get(0);
|
||
if((Long)newDeteInfo[DetectInfo.CHECKTIME]>(Long)oldDetecInfo[DetectInfo.CHECKTIME]){
|
||
newDataList.add(newDeteInfo);
|
||
}
|
||
if((Integer)newDeteInfo[DetectInfo.STATE]==1){
|
||
Object[] params={newDeteInfo[DetectInfo.SEQID],newDeteInfo[DetectInfo.SETINFOID]};
|
||
try {
|
||
service.addRecordToStatement(warnUpdateStmt, params);
|
||
} catch (SQLException e) {
|
||
// TODO Auto-generated catch block
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
}
|
||
|
||
public static void main(String[] args) {
|
||
|
||
}
|
||
|
||
|
||
}
|