Parcourir la source

补充分区的小时分析逻辑

andyliu il y a 1 semaine
Parent
commit
b09fad2d9c

+ 170 - 7
src/main/java/com/shkpr/service/warncore/bizhandler/ZoneDataWarnHandler.java

@@ -47,7 +47,135 @@ public class ZoneDataWarnHandler {
                 code = pickWarnByMonth(planDetail, rules);
             }
             break;
+            case FrequencyUnit.HOUR:{
+                code = pickWarnByHour(planDetail, rules);
+            }
+            break;
+        }
+        return code;
+    }
+
+    private static ResponseCode pickWarnByHour(OrdWarnPlanDetail planDetail, List<OrdWarnPlanRules> rules){
+        ResponseCode code = ResponseCode.RESULT_NORMAL;
+        String step = "Start to pre analysis.";
+        if (getWarnPlanInfoDBService().existsLineEx(OrdWarnPlanInfoTable.R_INFO.TABLE
+                , new HashMap<String, Object>(){{put(OrdWarnPlanInfoTable.R_INFO.STATUS, CommFieldStatus.ENABLE);
+                    put(OrdWarnPlanInfoTable.R_INFO.UNIQUE_ID, planDetail.getUid());
+                    put(OrdWarnPlanInfoTable.R_INFO.VERSION, planDetail.getVersion());
+                }}, null, "") <= 0){
+            step = "Plan is changed,do analysis next time";
+            code = ResponseCode.RESULT_BAD;
+        }
+
+        boolean doForTodayBefore = false;//是否只分析今日之前的数据
+        final long curUTCTm = TimeTool.getCurMsUTC();
+        int curClock = (int)((curUTCTm/1000/60/60%24+8)%24);
+        long queryBeginUTC = 0L, queryEndUTC = 0L, conditionMinUTC = 0L;
+        final String curDate = TimeTool.convertUTC2DateStr(curUTCTm, TimeTool.YEAR_MONTH_DAY_FORMAT);
+        curClock = curClock - 1;
+        if (curClock < 0){
+            curClock = 23;
+            doForTodayBefore = true;
+        }
+
+        OrdWarnPlanTempStep thisStepTempRes = new OrdWarnPlanTempStep(planDetail);
+        thisStepTempRes.setLastAnalyTime(curUTCTm);
+        thisStepTempRes.setCompareTimes(planDetail.getCompareTimes()+1);
+        do {
+            if (code != ResponseCode.RESULT_NORMAL)
+                break;
+
+            int findStartClock = -1;
+            for (int i=rules.size()-1;i>=0;i--){
+                if (i == 0)
+                    conditionMinUTC = TimeTool.convertDateStr2UTC(String.format("%s %2d:00:00", curDate, rules.get(i).getStarts()));
+                if (curClock >= rules.get(i).getStarts() && curClock <= rules.get(i).getEnds()){
+                    findStartClock = rules.get(i).getStarts();
+                    queryEndUTC = Math.min(TimeTool.convertDateStr2UTC(String.format("%s %2d:59:59", curDate, curClock))
+                            , TimeTool.convertDateStr2UTC(String.format("%s %2d:59:59", curDate, rules.get(i).getEnds())));
+                    break;
+                }
+            }
+            if (findStartClock < 0){
+                step = "Now out in time range,do analysis next time";
+                code = ResponseCode.RESULT_BAD;
+                break;
+            }
+            if (doForTodayBefore){//只分析昨日23:00:00-23:59:59的数据
+                queryBeginUTC = TimeTool.getTodayBeginUTC()-TimeTool.MS_ONE_HOUR;
+                queryEndUTC = TimeTool.getTodayBeginUTC()-TimeTool.MS_ONE_SEC;
+                conditionMinUTC = Math.min(conditionMinUTC-TimeTool.MS_ONE_DAY, queryBeginUTC);//针对昨日:触发规则列表中第一个时段的起始时刻
+            }else {
+                findStartClock = findStartClock-1;
+                for (int i=rules.size()-1;i>=0;i--){
+                    if (findStartClock < 0)
+                        break;
+                    if (findStartClock == rules.get(i).getEnds())
+                        findStartClock = rules.get(i).getStarts()-1;
+                }
+                queryBeginUTC = TimeTool.convertDateStr2UTC(String.format("%s %2d:00:00", curDate, findStartClock+1));
+            }
+
+            if (thisStepTempRes.getLastCompareSampleTime() <= 0L //从未分析过则重新计数
+                    || thisStepTempRes.getLastCompareSampleTime() < queryBeginUTC){//样本跨了时段则重新计数
+                thisStepTempRes.resetData();
+            }else if (thisStepTempRes.getLastCompareSampleTime() >= queryBeginUTC){
+                queryBeginUTC = thisStepTempRes.getLastCompareSampleTime() + TimeTool.MS_ONE_HOUR;
+            }
+
+            if (queryBeginUTC > queryEndUTC){
+                step = "Time is invalid,do analysis next time.";
+                code = ResponseCode.RESULT_BAD;
+                break;
+            }
+
+            thisStepTempRes.setDoForTodayBefore(doForTodayBefore);
+            thisStepTempRes.setQueryBeginUTC(queryBeginUTC);
+            thisStepTempRes.setQueryEndUTC(queryEndUTC);
+            thisStepTempRes.setConditionMinUTC(conditionMinUTC);
+            thisStepTempRes.setCycleTriggerTimes(planDetail.getCycleTriggerTimes());
+            if (planDetail.getLastEventTime() < conditionMinUTC)
+                thisStepTempRes.setCycleTriggerTimes(0);
+            if (planDetail.getCycleTriggerUpperTimes() > 0
+                    && thisStepTempRes.getCycleTriggerTimes() >= planDetail.getCycleTriggerUpperTimes()){//触发事件达到最大个数
+                step = "Event arrive at max limit,stop analysis for today.";
+                code = ResponseCode.RESULT_BAD;
+                break;
+            }
+
+            if (!StringUtils.isEmpty(planDetail.getLastEventId())){
+                int action = CommToolHandler.checkOrdWarnEventAction(planDetail.getLastEventId());
+                if (action < 0){
+                    step = "Last event check error,do analysis next time.";
+                    code = ResponseCode.RESULT_BAD;
+                    break;
+                }else if (action == 0){//lastEvent事件被手动意外删除
+                    thisStepTempRes.setLastEventId("");
+                    thisStepTempRes.setLastEventTime(0L);
+                    thisStepTempRes.setLastEventAction(1);
+                }else
+                    thisStepTempRes.setLastEventAction(action);
+            }
+
+        }while (false);
+        if (code == ResponseCode.RESULT_NORMAL){
+            code = analysisDataStepByStep(planDetail, rules, thisStepTempRes);
+        }else {//单独更新预警方案的分析时间、次数、说明
+            thisStepTempRes.setLastAnalyExplain(step);
+            Map<String, Object> updatePlan = thisStepTempRes.genUpdatePlan();
+            updatePlan.put(OrdWarnPlanInfoTable.W_INFO.VERSION, planDetail.getVersion()+1);
+            updatePlan.put(OrdWarnPlanInfoTable.W_INFO.UPDATE_TIME, System.currentTimeMillis());
+            if (getWarnPlanInfoDBService().updatePlanForTrigger(new HashMap<String, Object>(){{
+                put(OrdWarnPlanInfoTable.W_INFO.UNIQUE_ID, planDetail.getUid());
+                put(OrdWarnPlanInfoTable.W_INFO.VERSION, planDetail.getVersion());
+            }}, updatePlan, null, null) <= 0){
+                step = "Update warn plan trigger result to db failed.";
+                code = ResponseCode.RESULT_BAD;
+            }
         }
+        LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBusinessType, mStrClassName
+                , String.format("Pick Zone Data By Hour:{planId=%s} {step=%s} {%s}...",
+                        planDetail.getUid(), step, code.toString()));
         return code;
     }
 
@@ -70,6 +198,8 @@ public class ZoneDataWarnHandler {
         long queryBeginUTC = 0L, conditionMinUTC = 0L;
         long queryEndUTC = TimeTool.getMonthBeginUTC(curUTCTm);
         OrdWarnPlanTempStep thisStepTempRes = new OrdWarnPlanTempStep(planDetail);
+        thisStepTempRes.setLastAnalyTime(curUTCTm);
+        thisStepTempRes.setCompareTimes(planDetail.getCompareTimes()+1);
         do {
             if (code != ResponseCode.RESULT_NORMAL)
                 break;
@@ -115,6 +245,7 @@ public class ZoneDataWarnHandler {
             thisStepTempRes.setQueryBeginUTC(queryBeginUTC);
             thisStepTempRes.setQueryEndUTC(queryEndUTC);
             thisStepTempRes.setConditionMinUTC(conditionMinUTC);
+            thisStepTempRes.setCycleTriggerTimes(planDetail.getCycleTriggerTimes());
             if (thisStepTempRes.getLastEventTime() > 0L){//月分析时,比较每年的事件数上限数
                 int lastEventTmInYear = TimeTool.getYearIndex(thisStepTempRes.getLastEventTime());
                 if (lastEventTmInYear == preMonthInYear){
@@ -144,7 +275,7 @@ public class ZoneDataWarnHandler {
         }while (false);
 
         if (code == ResponseCode.RESULT_NORMAL){
-            code = analysisDataByDayOrMonth(planDetail, rules, thisStepTempRes);
+            code = analysisDataStepByStep(planDetail, rules, thisStepTempRes);
         }else {//单独更新预警方案的分析时间、次数、说明
             thisStepTempRes.setLastAnalyExplain(step);
             Map<String, Object> updatePlan = thisStepTempRes.genUpdatePlan();
@@ -182,6 +313,8 @@ public class ZoneDataWarnHandler {
         long queryBeginUTC = 0L, conditionMinUTC = 0L;
         long queryEndUTC = TimeTool.getTodayBeginUTC();
         OrdWarnPlanTempStep thisStepTempRes = new OrdWarnPlanTempStep(planDetail);
+        thisStepTempRes.setLastAnalyTime(curUTCTm);
+        thisStepTempRes.setCompareTimes(planDetail.getCompareTimes()+1);
         do {
             if (code != ResponseCode.RESULT_NORMAL)
                 break;
@@ -228,6 +361,7 @@ public class ZoneDataWarnHandler {
             thisStepTempRes.setQueryBeginUTC(queryBeginUTC);
             thisStepTempRes.setQueryEndUTC(queryEndUTC);
             thisStepTempRes.setConditionMinUTC(conditionMinUTC);
+            thisStepTempRes.setCycleTriggerTimes(planDetail.getCycleTriggerTimes());
             if (thisStepTempRes.getLastEventTime() > 0L){//月分析时,比较每月的事件数上限数
                 int lastEventTmInMonth = TimeTool.getMonthIndex(thisStepTempRes.getLastEventTime());
                 if (lastEventTmInMonth == preDayInMonth){
@@ -257,7 +391,7 @@ public class ZoneDataWarnHandler {
         }while (false);
 
         if (code == ResponseCode.RESULT_NORMAL){
-            code = analysisDataByDayOrMonth(planDetail, rules, thisStepTempRes);
+            code = analysisDataStepByStep(planDetail, rules, thisStepTempRes);
         }else {//单独更新预警方案的分析时间、次数、说明
             thisStepTempRes.setLastAnalyExplain(step);
             Map<String, Object> updatePlan = thisStepTempRes.genUpdatePlan();
@@ -277,7 +411,7 @@ public class ZoneDataWarnHandler {
         return code;
     }
 
-    private static ResponseCode analysisDataByDayOrMonth(OrdWarnPlanDetail planDetail, List<OrdWarnPlanRules> rules, OrdWarnPlanTempStep thisTempStep){
+    private static ResponseCode analysisDataStepByStep(OrdWarnPlanDetail planDetail, List<OrdWarnPlanRules> rules, OrdWarnPlanTempStep thisTempStep){
         String step = "Start to deep analysis";
         ResponseCode code = ResponseCode.RESULT_NORMAL;
         long curTime = TimeTool.getCurMsUTC();
@@ -351,7 +485,7 @@ public class ZoneDataWarnHandler {
                     continue;
                 }//本次匹配成功进入下一步
 
-                long triggerEventPeriodSwitch = planDetail.getFrequency()*planDetail.getThreshold();//触发预警事件的最小时长(单位:天/月)
+                long triggerEventPeriodSwitch = planDetail.getFrequency()*planDetail.getThreshold();//触发预警事件的最小时长(单位:时/天/月)
                 if (thisTempStep.getLastCompareSampleResult() <= COMPARE_FALSE){//上一次没有匹配成功
                     thisTempStep.setLastCompareSampleTime(sampleRecordTm);
                     thisTempStep.setLastCompareSampleResult(COMPARE_TURE);
@@ -373,8 +507,10 @@ public class ZoneDataWarnHandler {
                 long diffMatch = 0L;//两个最近匹配样本之间的采集时间差
                 if (FrequencyUnit.MONTH.equals(planDetail.getFrequencyUnit()))
                     diffMatch = TimeTool.getMonthCountsBetweenTm(sampleRecordTm, thisTempStep.getLastCompareSampleTime());//换算成月
-                else
+                else if (FrequencyUnit.DAY.equals(planDetail.getFrequencyUnit()))
                     diffMatch = (sampleRecordTm-thisTempStep.getLastCompareSampleTime())/TimeTool.MS_ONE_DAY;//换算成天
+                else if (FrequencyUnit.HOUR.equals(planDetail.getFrequencyUnit()))
+                    diffMatch = (sampleRecordTm-thisTempStep.getLastCompareSampleTime())/TimeTool.MS_ONE_HOUR;//换算成小时
                 if (diffMatch > triggerEventPeriodSwitch){//两个最近匹配样本间缺失的数据太多、或跨了天/月、或跨了时段,可认为重新计数
                     thisTempStep.setLastCompareSampleTime(sampleRecordTm);
                     thisTempStep.setLastCompareSampleResult(COMPARE_TURE);
@@ -396,12 +532,37 @@ public class ZoneDataWarnHandler {
                     continue;
                 }//两个最近匹配样本间隔很近,可认为是持续匹配,则进入下一步
 
+                if (FrequencyUnit.HOUR.equals(planDetail.getFrequencyUnit())){
+                    if (thisTempStep.getLastCompareSampleTime() < thisTempStep.getConditionMinUTC()){//上一个匹配样本是非当前天的,可认为重新计数
+                        thisTempStep.setLastCompareSampleTime(sampleRecordTm);
+                        thisTempStep.setLastCompareSampleResult(COMPARE_TURE);
+                        thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
+                        thisTempStep.setLastCompareSampleExplain("This is matched, but last is not today.");
+                        if (triggerEventPeriodSwitch <= 1){//触发事件
+                            thisTempStep.setLastEventTime(TimeTool.getCurMsUTC());
+                            thisTempStep.setLastCompareSampleExplain("This is matched and trigger short period, it will gen event.");
+
+                            JPOrdWarnEventInfo newEvent = new JPOrdWarnEventInfo(planDetail, rules, thisTempStep, thisTempStep.getLastEventTime());
+                            newEvent2Gen.put(newEvent.getUid(), newEvent);
+                            thisTempStep.setLastEventId(newEvent.getUid());
+                            thisTempStep.setLastEventAction(newEvent.getAction());
+                            thisTempStep.setCycleTriggerTimes(thisTempStep.getCycleTriggerTimes()+1);
+                        }else {
+                            thisTempStep.setLastEventId("");
+                            thisTempStep.setLastEventTime(0L);
+                        }
+                        continue;
+                    }//上一个匹配样本是当天的,则进入下一步
+                }
+
                 long matchLen = 0L;//样本匹配的持续时长
                 if (thisTempStep.getFirstMatchSampleTime() > 0L){
                     if (FrequencyUnit.MONTH.equals(planDetail.getFrequencyUnit()))
                         matchLen = TimeTool.getMonthCountsBetweenTm(sampleRecordTm, thisTempStep.getFirstMatchSampleTime())+1;//换算成月
-                    else
+                    else if (FrequencyUnit.DAY.equals(planDetail.getFrequencyUnit()))
                         matchLen = ((sampleRecordTm-thisTempStep.getFirstMatchSampleTime())/TimeTool.MS_ONE_DAY)+1;//换算成天
+                    else if (FrequencyUnit.HOUR.equals(planDetail.getFrequencyUnit()))
+                        matchLen = ((sampleRecordTm-thisTempStep.getFirstMatchSampleTime())/TimeTool.MS_ONE_HOUR)+1;//换算成小时
                 }
                 if (StringUtils.isEmpty(thisTempStep.getLastEventId())){//之前无预警事件
                     if (matchLen < triggerEventPeriodSwitch){//还得持续等待,达不到触发事件的累计时长
@@ -495,8 +656,10 @@ public class ZoneDataWarnHandler {
             code = ResponseCode.RESULT_BAD;
         }
         LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO, mBusinessType, mStrClassName
-                , String.format("Analysis Data By Day Or Month:{planId=%s,zoneId=%s} {step=%s} {%s}...",
+                , String.format("Analysis Data Step By Step:{planId=%s,zoneId=%s} {step=%s} {%s}...",
                         planDetail.getUid(), zoneId, step, code.toString()));
         return code;
     }
+
+
 }