Просмотр исходного кода

完善分析类的月分析逻辑

andyliu недель назад: 2
Родитель
Сommit
c3de0a419c

+ 1 - 1
src/main/java/com/shkpr/service/warncore/bizhandler/SiteDataWarnHandler.java

@@ -458,7 +458,7 @@ public class SiteDataWarnHandler {
                     continue;
                 }//上一个匹配样本是当天的,则进入下一步
 
-                long matchLen = (thisTempStep.getFirstMatchSampleTime()<=0)?0:((sampleRecordTm-thisTempStep.getFirstMatchSampleTime())/TimeTool.MS_ONE_HOUR);//样本匹配的持续时长(单位:小时)
+                long matchLen = (thisTempStep.getFirstMatchSampleTime()<=0)?0:(((sampleRecordTm-thisTempStep.getFirstMatchSampleTime())/TimeTool.MS_ONE_HOUR)+1);//样本匹配的持续时长(单位:小时)
                 if (StringUtils.isEmpty(thisTempStep.getLastEventId())){//之前无预警事件
                     if (matchLen < triggerEventPeriodSwitch){//还得持续等待,达不到触发事件的累计时长
                         thisTempStep.setLastCompareSampleTime(sampleRecordTm);

+ 3 - 3
src/main/java/com/shkpr/service/warncore/bizhandler/TimeCheckWarnPlanMgr.java

@@ -31,9 +31,9 @@ public class TimeCheckWarnPlanMgr {
     public static void checkWarnPlanByMinute(int curClock, int curMinute){
         long thisDayBegin = TimeTool.getTodayBeginUTC();
         Map<String, Object> mapSel = getThisDBService().totalWillAnalysisCounts(new HashMap<String, Object>(){{
-                    put(OrdWarnPlanInfoTable.W_INFO.STATUS, CommFieldStatus.ENABLE);
-                    put(OrdWarnPlanInfoTable.W_INFO.DISUSED, 0);
-                    put(OrdWarnPlanInfoTable.W_INFO.FREQUENCY_UNIT, FrequencyUnit.MIN);
+                    put(OrdWarnPlanInfoTable.R_INFO.STATUS, CommFieldStatus.ENABLE);
+                    put(OrdWarnPlanInfoTable.R_INFO.DISUSED, 0);
+                    put(OrdWarnPlanInfoTable.R_INFO.FREQUENCY_UNIT, FrequencyUnit.MIN);
                 }}
                 , null
                 , ""

+ 100 - 14
src/main/java/com/shkpr/service/warncore/bizhandler/ZoneDataWarnHandler.java

@@ -3,6 +3,7 @@ package com.shkpr.service.warncore.bizhandler;
 import com.shkpr.service.warncore.commtools.CommTool;
 import com.shkpr.service.warncore.commtools.TimeTool;
 import com.shkpr.service.warncore.constants.CommFieldStatus;
+import com.shkpr.service.warncore.constants.FrequencyUnit;
 import com.shkpr.service.warncore.dbdao.DBMgrProxy;
 import com.shkpr.service.warncore.dbdao.services.intef.OrdWarnPlanInfoDBService;
 import com.shkpr.service.warncore.dbdao.services.intef.OrdWarnPlanRulesDBService;
@@ -24,6 +25,80 @@ public class ZoneDataWarnHandler {
         return DBMgrProxy.getInstance().applyXXXApi(OrdWarnPlanRulesDBService.class);
     }
 
+    public static ResponseCode handlerDataByMonth(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;
+        }
+
+        final long curUTCTm = TimeTool.getCurMsUTC();
+        final long lastMonthThisTm = TimeTool.getTimeChgMonth(curUTCTm, -1);//前一个月的当前时间
+        final int preMonth = TimeTool.getMonthIndex(lastMonthThisTm);//月分析时,分析前一月
+        final int preMonthInYear = TimeTool.getYearIndex(lastMonthThisTm);//月分析时,分析前一月所在的年份
+        long queryBeginUTC = 0L, conditionMinUTC = 0L;
+        long queryEndUTC = TimeTool.getMonthBeginUTC(curUTCTm);
+        OrdWarnPlanTempStep thisStepTempRes = new OrdWarnPlanTempStep(planDetail);
+        do {
+            int findStartRange = -1;
+            for (int i=rules.size()-1;i>=0;i--){
+                if (preMonth >= rules.get(i).getStart() && preMonth <= rules.get(i).getEnd()){
+                    findStartRange = rules.get(i).getStart();
+                }
+            }
+            if (findStartRange < 0){
+                step = "Not in time range,do analysis next time";
+                code = ResponseCode.RESULT_BAD;
+                break;
+            }
+            findStartRange = findStartRange-1;
+            for (int i=rules.size()-1;i>=0;i--){
+                if (findStartRange <= 0)
+                    break;
+                if (findStartRange == rules.get(i).getEnd())
+                    findStartRange = rules.get(i).getStart()-1;
+            }
+            queryBeginUTC = TimeTool.convertDateStr2BeginUTC(String.format("%d-%2d-01 00:00:00", preMonthInYear, findStartRange+1));
+            conditionMinUTC = queryBeginUTC;
+            long before3MonthUTC =  TimeTool.getTimeChgMonth(queryEndUTC,-3);//最多只往前分析3个月
+            if (before3MonthUTC > queryBeginUTC)
+                queryBeginUTC = before3MonthUTC;
+
+            if (thisStepTempRes.getLastCompareSampleTime() <= 0L
+                    || thisStepTempRes.getLastCompareSampleTime() < queryBeginUTC) {//从未分析过则重新计数)
+                thisStepTempRes.resetData();
+            }else if (thisStepTempRes.getLastCompareSampleTime() >= queryBeginUTC) {
+                queryBeginUTC = TimeTool.getTimeChgMonth(thisStepTempRes.getLastCompareSampleTime(), 1);
+            }
+            if (queryBeginUTC >= queryEndUTC){
+                step = "Time is invalid,do analysis next time";
+                code = ResponseCode.RESULT_BAD;
+                break;
+            }
+
+            thisStepTempRes.setDoForTodayBefore(true);
+            thisStepTempRes.setQueryBeginUTC(queryBeginUTC);
+            thisStepTempRes.setQueryEndUTC(queryEndUTC);
+            thisStepTempRes.setConditionMinUTC(conditionMinUTC);
+
+            if (!StringUtils.isEmpty(planDetail.getLastEventId())){
+                //向数据库中快速查询事件最近处理阶段action的值
+                //并赋值给thisTempStep
+            }
+        }while (false);
+
+        if (code == ResponseCode.RESULT_NORMAL){
+            code = analysisDataByDayOrMonth(planDetail, rules, thisStepTempRes);
+        }else {//单独更新预警方案的分析时间、次数、说明
+        }
+        return code;
+    }
+
     public static ResponseCode handlerDataByDay(OrdWarnPlanDetail planDetail, List<OrdWarnPlanRules> rules){
         ResponseCode code = ResponseCode.RESULT_NORMAL;
         String step = "Start to pre analysis.";
@@ -39,7 +114,6 @@ public class ZoneDataWarnHandler {
         final long curUTCTm = TimeTool.getCurMsUTC();
         final int preDayInYear = TimeTool.getYearIndex(curUTCTm-TimeTool.MS_ONE_DAY);//日分析时,分析前一日所在的年份
         final int preDayInMonth = TimeTool.getMonthIndex(curUTCTm-TimeTool.MS_ONE_DAY);//日分析时,分析前一日所在的月份
-
         long queryBeginUTC = 0L, conditionMinUTC = 0L;
         long queryEndUTC = TimeTool.getTodayBeginUTC();
         OrdWarnPlanTempStep thisStepTempRes = new OrdWarnPlanTempStep(planDetail);
@@ -65,9 +139,9 @@ public class ZoneDataWarnHandler {
 
             queryBeginUTC = TimeTool.convertDateStr2BeginUTC(String.format("%d-%2d-01 00:00:00", preDayInYear, findStartRange+1));
             conditionMinUTC = queryBeginUTC;
-            long before3Day = queryEndUTC-TimeTool.MS_ONE_DAY*3;//最多只往前分析3天
-            if (before3Day > queryBeginUTC)
-                queryBeginUTC = before3Day;
+            long before3DayUTC = queryEndUTC-TimeTool.MS_ONE_DAY*3;//最多只往前分析3天
+            if (before3DayUTC > queryBeginUTC)
+                queryBeginUTC = before3DayUTC;
 
             if (thisStepTempRes.getLastCompareSampleTime() <= 0L
                     || thisStepTempRes.getLastCompareSampleTime() < queryBeginUTC) {//从未分析过则重新计数)
@@ -90,24 +164,26 @@ public class ZoneDataWarnHandler {
                 //向数据库中快速查询事件最近处理阶段action的值
                 //并赋值给thisTempStep
             }
-
-            return analysisDataByDay(planDetail, rules, thisStepTempRes);
         }while (false);
+
+        if (code == ResponseCode.RESULT_NORMAL){
+            code = analysisDataByDayOrMonth(planDetail, rules, thisStepTempRes);
+        }else {//单独更新预警方案的分析时间、次数、说明
+        }
         return code;
     }
 
-    private static ResponseCode analysisDataByDay(OrdWarnPlanDetail planDetail, List<OrdWarnPlanRules> rules, OrdWarnPlanTempStep thisTempStep){
-        ResponseCode code = ResponseCode.RESULT_NORMAL;
+    private static ResponseCode analysisDataByDayOrMonth(OrdWarnPlanDetail planDetail, List<OrdWarnPlanRules> rules, OrdWarnPlanTempStep thisTempStep){
         String step = "Start to deep analysis";
+        ResponseCode code = ResponseCode.RESULT_NORMAL;
         long curTime = TimeTool.getCurMsUTC();
         final String zoneId = rules.get(0).getObjId();
         List<DateKeyValue> zoneStatsData = null;//要求数据按date升序
         Map<String, Long> eventId2NewEndUTC = new HashMap<>();//需要更新预警事件的样本截止时间
-
         do {
             String[] storeTagAndBackTag = rules.get(0).getConditions().get(0).getFormat().split("@");
             if (storeTagAndBackTag == null || storeTagAndBackTag.length < 2){
-                step = String.format("Format param valid in rules");
+                step = String.format("Format param invalid in rules");
                 code = ResponseCode.RESULT_BAD;
                 break;
             }
@@ -168,7 +244,7 @@ public class ZoneDataWarnHandler {
                     continue;
                 }//本次匹配成功进入下一步
 
-                long triggerEventPeriodSwitch = planDetail.getFrequency()*planDetail.getThreshold();//触发预警事件的最小时长(单位:天)
+                long triggerEventPeriodSwitch = planDetail.getFrequency()*planDetail.getThreshold();//触发预警事件的最小时长(单位:天/月)
                 if (thisTempStep.getLastCompareSampleResult() <= 0){//上一次没有匹配成功
                     thisTempStep.setLastCompareSampleTime(sampleRecordTm);
                     thisTempStep.setLastCompareSampleResult(1);
@@ -181,8 +257,12 @@ public class ZoneDataWarnHandler {
                     continue;
                 }//上一次匹配成功了进入下一步
 
-                long diffMatch = (sampleRecordTm-thisTempStep.getLastCompareSampleTime())/TimeTool.MS_ONE_DAY;//两个最近匹配样本之间的采集时间差(单位:天)
-                if (diffMatch > triggerEventPeriodSwitch){//两个最近匹配样本间缺失的数据太多、或跨了天、或跨了时段,可认为重新计数
+                long diffMatch = 0L;//两个最近匹配样本之间的采集时间差
+                if (FrequencyUnit.MONTH.equals(planDetail.getFrequencyUnit()))
+                    diffMatch = TimeTool.getMonthCountsBetweenTm(sampleRecordTm, thisTempStep.getLastCompareSampleTime());//换算成月
+                else
+                    diffMatch = (sampleRecordTm-thisTempStep.getLastCompareSampleTime())/TimeTool.MS_ONE_DAY;//换算成天
+                if (diffMatch > triggerEventPeriodSwitch){//两个最近匹配样本间缺失的数据太多、或跨了天/月、或跨了时段,可认为重新计数
                     thisTempStep.setLastCompareSampleTime(sampleRecordTm);
                     thisTempStep.setLastCompareSampleResult(1);
                     thisTempStep.setFirstMatchSampleTime(sampleRecordTm);
@@ -197,7 +277,13 @@ public class ZoneDataWarnHandler {
                     continue;
                 }//两个最近匹配样本间隔很近,可认为是持续匹配,则进入下一步
 
-                long matchLen = (thisTempStep.getFirstMatchSampleTime()<=0)?0:((sampleRecordTm-thisTempStep.getFirstMatchSampleTime())/TimeTool.MS_ONE_DAY);//样本匹配的持续时长(单位:天)
+                long matchLen = 0L;//样本匹配的持续时长
+                if (thisTempStep.getFirstMatchSampleTime() > 0L){
+                    if (FrequencyUnit.MONTH.equals(planDetail.getFrequencyUnit()))
+                        matchLen = TimeTool.getMonthCountsBetweenTm(sampleRecordTm, thisTempStep.getFirstMatchSampleTime())+1;//换算成月
+                    else
+                        matchLen = ((sampleRecordTm-thisTempStep.getFirstMatchSampleTime())/TimeTool.MS_ONE_DAY)+1;//换算成天
+                }
                 if (StringUtils.isEmpty(thisTempStep.getLastEventId())){//之前无预警事件
                     if (matchLen < triggerEventPeriodSwitch){//还得持续等待,达不到触发事件的累计时长
                         thisTempStep.setLastCompareSampleTime(sampleRecordTm);

+ 16 - 0
src/main/java/com/shkpr/service/warncore/commtools/TimeTool.java

@@ -3,6 +3,7 @@ import org.springframework.util.StringUtils;
 import java.text.SimpleDateFormat;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
 import java.util.*;
 
 public class TimeTool {
@@ -13,6 +14,7 @@ public class TimeTool {
     public static final long MIN_ONE_DAY = 24*60;        //一天中的分
     public static final long SEC_ONE_DAY = 24*60*60;     //一天中的秒
     public static final long MS_ONE_DAY = 24*60*60*1000; //一天中的毫秒
+    public static final long MS_ONE_MONTH = 30*MS_ONE_DAY; //一月中的毫秒
     public static final long MS_ONE_YEAR = 365*MS_ONE_DAY;//一年中的毫秒
     public static final long MS_ONE_HOUR = 60*60*1000;   //一小时的毫秒
     public static final String YEAR_FORMAT = "yyyy";
@@ -565,4 +567,18 @@ public class TimeTool {
         ZonedDateTime utcDateTime = instant.atZone(ZoneOffset.UTC);
         return utcDateTime.getYear();
     }
+
+    /**
+     * 计算两个时间相差的月份数
+     * @param start
+     * @param end
+     * @return:相差的月份数(绝对值)
+     */
+    public static long getMonthCountsBetweenTm(long start, long end){
+        ZonedDateTime date1 = Instant.ofEpochMilli(start)
+                .atZone(ZoneId.of("UTC"));
+        ZonedDateTime date2 = Instant.ofEpochMilli(end)
+                .atZone(ZoneId.of("UTC"));
+        return Math.abs(ChronoUnit.MONTHS.between(date1, date2));
+    }
 }

+ 1 - 1
src/main/java/com/shkpr/service/warncore/dbdao/providers/OrdWarnPlanInfoSqlProvider.java

@@ -69,7 +69,7 @@ public class OrdWarnPlanInfoSqlProvider extends BaseSqlProvider implements OrdWa
         String extend = (String)mapParams.get("extend");
 
         StringBuilder sql = new StringBuilder("");
-        sql.append("select count(*) AS total, min("+W_INFO.ID+") AS min_index, max("+W_INFO.ID+") AS max_index from " + getWTableName() + " where 1=1 ");
+        sql.append("select count(*) AS total, min("+R_INFO.ID+") AS min_index, max("+R_INFO.ID+") AS max_index from " + getRTableName() + " where 1=1 ");
 
         String strAndWheres = genWheres(andWheres, "andWheres", "and");
         String strOrWheres = genWheres(orWheres, "orWheres", "or");

+ 1 - 1
src/main/java/com/shkpr/service/warncore/globalmgr/ScheduleTaskMgr.java

@@ -69,7 +69,7 @@ public class ScheduleTaskMgr {
         ThreadTaskMgr.runTask(new TraceRunnable("S.CHECK.WARN.PLAN.BY.MIN") {
             @Override
             public void function() {
-                TimeCheckWarnPlanMgr.checkWarnPlanByMinute(curClock, curMinute==0?60:curMinute);
+                //TimeCheckWarnPlanMgr.checkWarnPlanByMinute(curClock, curMinute==0?60:curMinute);
             }
         });
     }