|
@@ -2,17 +2,29 @@ package cn.com.ctop.alarm.modules.service.impl;
|
|
|
|
|
|
import cn.com.ctop.alarm.modules.entity.AlarmEventMetric;
|
|
|
import cn.com.ctop.alarm.modules.entity.AlarmEventRule;
|
|
|
+import cn.com.ctop.alarm.modules.entity.AlarmEventSend;
|
|
|
import cn.com.ctop.alarm.modules.mapper.AlarmEventMetricMapper;
|
|
|
import cn.com.ctop.alarm.modules.mapper.AlarmEventRuleMapper;
|
|
|
+import cn.com.ctop.alarm.modules.mapper.AlarmEventSendMapper;
|
|
|
import cn.com.ctop.alarm.modules.service.IAlarmEventRuleService;
|
|
|
+import cn.com.ctop.common.module.service.IMessageTemplate;
|
|
|
+import cn.com.ctop.common.module.service.ISendMessageService;
|
|
|
import cn.com.ctop.common.module.utils.Check;
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.github.pagehelper.PageInfo;
|
|
|
+import com.xxl.job.core.enums.NoEn;
|
|
|
+import org.apache.shiro.SecurityUtils;
|
|
|
+import org.jeecg.common.system.vo.LoginUser;
|
|
|
+import org.jeecg.common.util.db.DataSourceCachePool;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.redis.core.HashOperations;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import javax.transaction.Transactional;
|
|
|
+import java.math.BigDecimal;
|
|
|
import java.util.List;
|
|
|
|
|
|
/**
|
|
@@ -24,6 +36,7 @@ import java.util.List;
|
|
|
* @version V1.0
|
|
|
* @date 2020-10-29
|
|
|
*/
|
|
|
+@Transactional
|
|
|
@Service
|
|
|
public class AlarmEventRuleServiceImpl extends ServiceImpl<AlarmEventRuleMapper, AlarmEventRule> implements IAlarmEventRuleService {
|
|
|
|
|
@@ -33,6 +46,31 @@ public class AlarmEventRuleServiceImpl extends ServiceImpl<AlarmEventRuleMapper,
|
|
|
@Autowired
|
|
|
private AlarmEventMetricMapper alarmEventMetricMapper;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private AlarmEventSendMapper alarmEventSendMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IMessageTemplate messageTemplate;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ISendMessageService sendMessageService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public PageInfo<AlarmEventRule> selectListPage(AlarmEventRule alarmEventRule) {
|
|
|
+ return new PageInfo<AlarmEventRule>(alarmEventRuleMapper.selectListPage(alarmEventRule));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void deleteById(String id) {
|
|
|
+ alarmEventRuleMapper.deleteById(id);
|
|
|
+ alarmEventMetricMapper.deleteByRuleId(id);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public PageInfo<AlarmEventRule> queryRunningRecordPage(AlarmEventRule alarmEventRule) {
|
|
|
+ return new PageInfo<AlarmEventRule>(alarmEventRuleMapper.queryRunningRecordPage(alarmEventRule));
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void addAlarmEventRule(JSONObject obj) {
|
|
|
AlarmEventRule rule = new AlarmEventRule();
|
|
@@ -42,7 +80,15 @@ public class AlarmEventRuleServiceImpl extends ServiceImpl<AlarmEventRuleMapper,
|
|
|
rule.setEventRuleLevel(obj.getString("eventRuleLevel"));
|
|
|
rule.setCheckFrequency(obj.getString("checkFrequency"));
|
|
|
rule.setProcessMethod(obj.getString("processMethod"));
|
|
|
- rule.setEventRuleStatus(obj.getString("eventRuleStatus"));
|
|
|
+ rule.setEventRuleStatus(NoEn.NO1.valueStr());
|
|
|
+ rule.setMetricValueCode(obj.getString("metricValueCode"));
|
|
|
+ rule.setMetricValueName(obj.getString("metricValueName"));
|
|
|
+ rule.setCreaterId(obj.getString("createrId"));
|
|
|
+
|
|
|
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
|
|
+ if (!Check.isNull(sysUser)) {
|
|
|
+ rule.setCreaterId(sysUser.getId());
|
|
|
+ }
|
|
|
alarmEventRuleMapper.insert(rule);
|
|
|
JSONArray metrics = obj.getJSONArray("alarmEventMetric");
|
|
|
for (int i = 0; i < metrics.size(); i++) {
|
|
@@ -55,6 +101,8 @@ public class AlarmEventRuleServiceImpl extends ServiceImpl<AlarmEventRuleMapper,
|
|
|
metric.setThreshold(mo.getString("threshold"));
|
|
|
metric.setMinThreshold(mo.getString("minThreshold"));
|
|
|
metric.setDataRange(mo.getString("dataRange"));
|
|
|
+ metric.setMetricValueCode(mo.getString("metricValueCode"));
|
|
|
+ metric.setMetricValueName(mo.getString("metricValueName"));
|
|
|
alarmEventMetricMapper.insert(metric);
|
|
|
}
|
|
|
}
|
|
@@ -82,6 +130,14 @@ public class AlarmEventRuleServiceImpl extends ServiceImpl<AlarmEventRuleMapper,
|
|
|
if (!Check.isNull(checkFrequency)) {
|
|
|
rule.setCheckFrequency(checkFrequency);
|
|
|
}
|
|
|
+ String metricValueCode = obj.getString("metricValueCode");
|
|
|
+ if (!Check.isNull(metricValueCode)) {
|
|
|
+ rule.setMetricValueCode(metricValueCode);
|
|
|
+ }
|
|
|
+ String metricValueName = obj.getString("metricValueName");
|
|
|
+ if (!Check.isNull(metricValueName)) {
|
|
|
+ rule.setMetricValueCode(metricValueName);
|
|
|
+ }
|
|
|
String processMethod = obj.getString("processMethod");
|
|
|
if (!Check.isNull(processMethod)) {
|
|
|
rule.setProcessMethod(processMethod);
|
|
@@ -91,10 +147,17 @@ public class AlarmEventRuleServiceImpl extends ServiceImpl<AlarmEventRuleMapper,
|
|
|
if (!Check.isNull(eventRuleStatus)) {
|
|
|
rule.setEventRuleStatus(eventRuleStatus);
|
|
|
}
|
|
|
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
|
|
+ if (!Check.isNull(sysUser)) {
|
|
|
+ rule.setCreaterId(sysUser.getId());
|
|
|
+ }
|
|
|
QueryWrapper<AlarmEventRule> ruleWrapper = new QueryWrapper<>();
|
|
|
ruleWrapper.eq("event_rule_id", obj.getLong("eventRuleId"));
|
|
|
alarmEventRuleMapper.update(rule, ruleWrapper);
|
|
|
JSONArray metrics = obj.getJSONArray("alarmEventMetric");
|
|
|
+ if (Check.isNull(metrics)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
for (int i = 0; i < metrics.size(); i++) {
|
|
|
JSONObject mo = metrics.getJSONObject(i);
|
|
|
AlarmEventMetric metric = new AlarmEventMetric();
|
|
@@ -102,9 +165,13 @@ public class AlarmEventRuleServiceImpl extends ServiceImpl<AlarmEventRuleMapper,
|
|
|
if (!Check.isNull(eventRuleId)) {
|
|
|
metric.setEventRuleId(eventRuleId);
|
|
|
}
|
|
|
- String metricValueCode = mo.getString("metricValueCode");
|
|
|
- if (!Check.isNull(metricValueCode)) {
|
|
|
- metric.setMetricValueCode(metricValueCode);
|
|
|
+ String valueCode = mo.getString("metricValueCode");
|
|
|
+ if (!Check.isNull(valueCode)) {
|
|
|
+ metric.setMetricValueCode(valueCode);
|
|
|
+ }
|
|
|
+ String valueName = mo.getString("metricValueName");
|
|
|
+ if (!Check.isNull(valueName)) {
|
|
|
+ metric.setMetricValueName(valueName);
|
|
|
}
|
|
|
String judgeType = mo.getString("judgeType");
|
|
|
if (!Check.isNull(judgeType)) {
|
|
@@ -135,9 +202,200 @@ public class AlarmEventRuleServiceImpl extends ServiceImpl<AlarmEventRuleMapper,
|
|
|
|
|
|
@Override
|
|
|
public AlarmEventRule selectById(String id) {
|
|
|
- AlarmEventRule alarmEventRule = alarmEventRuleMapper.selectById(id);
|
|
|
+ AlarmEventRule alarmEventRule = alarmEventRuleMapper.queryById(id);
|
|
|
List<AlarmEventMetric> alarmEventMetricList = alarmEventMetricMapper.selectByEventRuleId(id);
|
|
|
return alarmEventRule.setAlarmEventMetrics(alarmEventMetricList);
|
|
|
+ }
|
|
|
|
|
|
+ @Override
|
|
|
+ public void matchAlarmRules(String checkType) {
|
|
|
+ List<AlarmEventRule> allRules = getAllAlarmRules(checkType);
|
|
|
+ List<JSONObject> accountCosts = getCostInfo("account");
|
|
|
+ if (Check.isNull(allRules) || Check.isNull(accountCosts)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (JSONObject cost : accountCosts) {
|
|
|
+ for (AlarmEventRule rule : allRules) {
|
|
|
+ if (cost.getLong("accountId") - rule.getAccountId() == 0) {
|
|
|
+ matchRules(rule, cost);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ private void matchRules(AlarmEventRule rule, JSONObject cost) {
|
|
|
+ String rulesMetric = rule.getMetricValueCode();
|
|
|
+ //目标成本
|
|
|
+ BigDecimal value = cost.getBigDecimal(rulesMetric);
|
|
|
+ if (Check.isNull(value)) {
|
|
|
+ log.warn("规则中指标不匹配");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //总消耗
|
|
|
+ BigDecimal totalCost = cost.getBigDecimal("totalCost");
|
|
|
+ List<AlarmEventMetric> metrics = rule.getAlarmEventMetrics();
|
|
|
+ if (Check.isNull(metrics)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ boolean flag = true;
|
|
|
+ StringBuffer depletionStr = new StringBuffer();
|
|
|
+ StringBuffer valueStr = new StringBuffer();
|
|
|
+ StringBuffer roiStr = new StringBuffer();
|
|
|
+ if (metrics.size() > 1) {
|
|
|
+ depletionStr.append("消耗");
|
|
|
+ valueStr.append("并且成本");
|
|
|
+ roiStr.append("并且ROI");
|
|
|
+ } else {
|
|
|
+ valueStr.append(metrics.get(0).getMetricValueName());
|
|
|
+ }
|
|
|
+ for (AlarmEventMetric metric : metrics) {
|
|
|
+ if (flag) {
|
|
|
+ //阈值
|
|
|
+ BigDecimal threshold = new BigDecimal(metric.getThreshold());
|
|
|
+ String judgeMethod = metric.getJudgeMethod();
|
|
|
+ String metricValue = metric.getMetricValueCode();
|
|
|
+ String sub = metricValue.substring(metricValue.lastIndexOf("_") + 1);
|
|
|
+ //大于等于
|
|
|
+ if ("GT_EQ".equals(judgeMethod)) {
|
|
|
+ //判断阈值类型(cost-成本;depletion-消耗;roi)
|
|
|
+ if ("depletion".equals(sub)) {
|
|
|
+ flag = totalCost.compareTo(threshold) >= 0;
|
|
|
+ depletionStr.append("高于").append("账户设置的消耗值:").append(threshold).append("元");
|
|
|
+ continue;
|
|
|
+ } else if ("roi".equals(sub)) {
|
|
|
+ roiStr.append("高于").append("账户设置的ROI:").append(threshold.multiply(new BigDecimal(100)).setScale(2)).append("%");
|
|
|
+ flag = value.compareTo(threshold) >= 0;
|
|
|
+ continue;
|
|
|
+ } else {
|
|
|
+ valueStr.append("高于").append("账户设置的成本价格:").append(threshold).append("元");
|
|
|
+ flag = value.compareTo(threshold) >= 0;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //小于等于
|
|
|
+ } else if ("LT_EQ".equals(judgeMethod)) {
|
|
|
+ if ("depletion".equals(sub)) {
|
|
|
+ depletionStr.append("低于").append("账户设置的消耗值:").append(threshold).append("元");
|
|
|
+ flag = totalCost.compareTo(threshold) <= 0;
|
|
|
+ continue;
|
|
|
+ } else if ("roi".equals(sub)) {
|
|
|
+ roiStr.append("低于").append("账户设置的ROI:").append(threshold.multiply(new BigDecimal(100)).setScale(2)).append("%");
|
|
|
+ flag = value.compareTo(threshold) <= 0;
|
|
|
+ continue;
|
|
|
+ } else {
|
|
|
+ valueStr.append("低于").append("账户设置的成本价格:").append(threshold).append("元");
|
|
|
+ flag = value.compareTo(threshold) <= 0;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //介于
|
|
|
+ } else if ("BETWEEN".equals(judgeMethod)) {
|
|
|
+ BigDecimal minThreshold = new BigDecimal(metric.getMinThreshold());
|
|
|
+ if ("depletion".equals(sub)) {
|
|
|
+ flag = (totalCost.compareTo(threshold) > 0) || (totalCost.compareTo(minThreshold) < 0);
|
|
|
+ if (totalCost.compareTo(threshold) > 0) {
|
|
|
+ depletionStr.append("高于");
|
|
|
+ }
|
|
|
+ if (totalCost.compareTo(minThreshold) < 0) {
|
|
|
+ depletionStr.append("低于");
|
|
|
+ }
|
|
|
+ depletionStr.append("账户设置的消耗区间:").append(minThreshold).append("元-").append(threshold).append("元");
|
|
|
+ continue;
|
|
|
+ } else if ("roi".equals(sub)) {
|
|
|
+ flag = (value.compareTo(threshold) > 0) || (value.compareTo(minThreshold) < 0);
|
|
|
+ if (value.compareTo(threshold) > 0) {
|
|
|
+ roiStr.append("高于");
|
|
|
+ }
|
|
|
+ if (value.compareTo(minThreshold) < 0) {
|
|
|
+ roiStr.append("低于");
|
|
|
+ }
|
|
|
+ roiStr.append("账户设置的").append(rule.getMetricValueName()).append("区间:").append(minThreshold.multiply(new BigDecimal(100)).setScale(2)).append("%-").append(threshold.multiply(new BigDecimal(100)).setScale(2)).append("%");
|
|
|
+ continue;
|
|
|
+ } else {
|
|
|
+ flag = (value.compareTo(threshold) > 0) || (value.compareTo(minThreshold) < 0);
|
|
|
+ if (value.compareTo(threshold) > 0) {
|
|
|
+ valueStr.append("高于");
|
|
|
+ }
|
|
|
+ if (value.compareTo(minThreshold) < 0) {
|
|
|
+ valueStr.append("低于");
|
|
|
+ }
|
|
|
+ valueStr.append("账户设置的成本区间:").append(minThreshold).append("元-").append(threshold).append("元");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.warn("缺失判断条件");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //规则满足,产生预警
|
|
|
+ if (flag) {
|
|
|
+ cost.put("accountName", rule.getAccountName());
|
|
|
+ cost.put("name", rule.getMetricValueName());
|
|
|
+ if (metrics.size() > 1) {
|
|
|
+ if (rule.getMetricValueCode().toLowerCase().contains("roi")) {
|
|
|
+ cost.put("depletion", depletionStr.append("<br/>").append(roiStr).toString());
|
|
|
+ } else {
|
|
|
+ cost.put("depletion", depletionStr.append("<br/>").append(valueStr).toString());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ cost.put("depletion", valueStr.toString());
|
|
|
+ }
|
|
|
+ String msg = null;
|
|
|
+ if ("SEND".equals(rule.getProcessMethod())) {
|
|
|
+ cost.put("end", "请您及时查看并调整!");
|
|
|
+ msg = messageTemplate.getAlarmCostMessage(cost);
|
|
|
+ } else {
|
|
|
+ cost.put("end", "现已被关停,请您及时查看并调整!");
|
|
|
+ msg = messageTemplate.getAlarmCostMessage(cost);
|
|
|
+ }
|
|
|
+ if (!Check.isNull(msg)) {
|
|
|
+ sendMessageService.sendMessage(rule.getUserId(), msg);
|
|
|
+
|
|
|
+ AlarmEventSend send = new AlarmEventSend();
|
|
|
+ send.setAlarmDetail(msg);
|
|
|
+ send.setAlarmStatus(NoEn.NO1.valueStr());
|
|
|
+ send.setMetricValueCode(rule.getMetricValueCode());
|
|
|
+ send.setEventRuleId(rule.getEventRuleId());
|
|
|
+ send.setAlarmCondition(rule.getMetricValueName() + "预警:" + cost.getString("depletion"));
|
|
|
+ alarmEventSendMapper.insert(send);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取成本数据。
|
|
|
+ *
|
|
|
+ * @param code : unit 组级数据,account 账户级数据
|
|
|
+ * @return java.util.List<cn.com.ctop.kuaishou.modules.report.entity.KuaishouCostGroup>
|
|
|
+ * @throws
|
|
|
+ * @author ZHAOXA
|
|
|
+ */
|
|
|
+ private List<JSONObject> getCostInfo(String code) {
|
|
|
+ HashOperations<String, Object, Object> hahs = DataSourceCachePool.getRedisTemplate().opsForHash();
|
|
|
+ return (List<JSONObject>) hahs.get("KS_COST", code);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取告警规则集合
|
|
|
+ *
|
|
|
+ * @param
|
|
|
+ * @return java.util.List<cn.com.ctop.alarm.modules.entity.AlarmEventRules>
|
|
|
+ * @throws
|
|
|
+ * @author ZHAOXA
|
|
|
+ */
|
|
|
+ private List<AlarmEventRule> getAllAlarmRules(String checkType) {
|
|
|
+ AlarmEventRule alarmEventRule = new AlarmEventRule();
|
|
|
+ alarmEventRule.setEventRuleStatus(NoEn.NO1.valueStr());
|
|
|
+ alarmEventRule.setCheckFrequency(checkType);
|
|
|
+ List<AlarmEventRule> ruleList = alarmEventRuleMapper.selectListPage(alarmEventRule);
|
|
|
+ if (!Check.isNull(ruleList)) {
|
|
|
+ for (AlarmEventRule rule : ruleList) {
|
|
|
+ QueryWrapper<AlarmEventMetric> metricWrapper = new QueryWrapper<>();
|
|
|
+ metricWrapper.eq("event_rule_id", rule.getEventRuleId());
|
|
|
+ rule.setAlarmEventMetrics(alarmEventMetricMapper.selectList(metricWrapper));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ruleList;
|
|
|
+ }
|
|
|
+
|
|
|
}
|