perf(X-Pack): 阈值告警关注指标

This commit is contained in:
fit2cloud-chenyw 2024-08-20 18:42:53 +08:00
parent 8da780eec3
commit 43bc442eaf
4 changed files with 203 additions and 6 deletions

View File

@ -1,17 +1,23 @@
package io.dataease.chart.manage;
import io.dataease.api.chart.request.ThresholdCheckRequest;
import io.dataease.api.chart.vo.ThresholdCheckVO;
import io.dataease.dataset.manage.DatasetTableFieldManage;
import io.dataease.engine.constant.DeTypeConstants;
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
import io.dataease.extensions.view.dto.ChartViewDTO;
import io.dataease.extensions.view.filter.FilterTreeItem;
import io.dataease.extensions.view.filter.FilterTreeObj;
import io.dataease.utils.JsonUtil;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@Component("chartViewThresholdManage")
@ -20,6 +26,9 @@ public class ChartViewThresholdManage {
@Resource
private DatasetTableFieldManage datasetTableFieldManage;
@Resource
private ChartViewManege chartViewManege;
public String convertThresholdRules(Long tableId, String thresholdRules) {
List<DatasetTableFieldDTO> fieldList = datasetTableFieldManage.selectByDatasetGroupId(tableId);
FilterTreeObj filterTreeObj = JsonUtil.parseObject(thresholdRules, FilterTreeObj.class);
@ -60,7 +69,7 @@ public class ChartViewThresholdManage {
if (StringUtils.equals(filterType, "enum")) {
List<String> enumValue = item.getEnumValue();
String enumValueText = String.join(",", enumValue);
return fieldName + " 包括 " + "( " + enumValueText + " )";
return fieldName + " 属于 " + "( " + enumValueText + " )";
} else {
return fieldName + " " + translateTerm(item.getTerm()) + " " + item.getValue();
}
@ -74,8 +83,8 @@ public class ChartViewThresholdManage {
case "le" -> "小于等于";
case "gt" -> "大于";
case "ge" -> "大于等于";
case "in" -> "包括";
case "not in" -> "包括";
case "in" -> "属于";
case "not in" -> "属于";
case "like" -> "包含";
case "not like" -> "不包含";
case "null" -> "为空";
@ -91,4 +100,150 @@ public class ChartViewThresholdManage {
if (StringUtils.equals(logic, "and")) return "";
return "";
}
public ThresholdCheckVO checkThreshold(ThresholdCheckRequest request) throws Exception {
String thresholdTemplate = request.getThresholdTemplate();
String thresholdRules = request.getThresholdRules();
Long chartId = request.getChartId();
ChartViewDTO chart = chartViewManege.getChart(chartId);
Map<String, Object> data = chart.getData();
List<Map<String, Object>> tableRow = (List<Map<String, Object>>) data.get("tableRow");
List<DatasetTableFieldDTO> fields = (List<DatasetTableFieldDTO>) data.get("fields");
Map<Long, DatasetTableFieldDTO> fieldMap = fields.stream().collect(Collectors.toMap(DatasetTableFieldDTO::getId, item -> item));
FilterTreeObj filterTreeObj = JsonUtil.parseObject(thresholdRules, FilterTreeObj.class);
List<Map<String, Object>> rows = filterRows(tableRow, filterTreeObj, fieldMap);
if (CollectionUtils.isEmpty(rows)) {
return new ThresholdCheckVO(false, null, null, null);
}
String regex = "<span[^>]*id=\"changeText-(\\d+)(?!0$)(?!1$)\"[^>]*>.*?</span>";
Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
Matcher matcher = pattern.matcher(thresholdTemplate);
StringBuilder sb = new StringBuilder();
while (matcher.find()) {
long id = Long.parseLong(matcher.group(1));
// 根据id从map中获取替换文本
DatasetTableFieldDTO fieldDTO = fieldMap.get(id);
String fieldDTOName = fieldDTO.getName();
String dataeaseName = fieldDTO.getDataeaseName();
List<String> valueList = rows.stream().map(row -> row.get(dataeaseName).toString()).collect(Collectors.toList());
String replacement = fieldDTOName + ": " + JsonUtil.toJSONString(valueList);
// 替换文本
matcher.appendReplacement(sb, replacement);
}
matcher.appendTail(sb);
// 输出替换后的HTML内容
String result = sb.toString();
return new ThresholdCheckVO(true, result, null, null);
}
public List<Map<String, Object>> filterRows(List<Map<String, Object>> rows, FilterTreeObj conditionTree, Map<Long, DatasetTableFieldDTO> fieldMap) {
List<Map<String, Object>> filteredRows = new ArrayList<>();
for (Map<String, Object> row : rows) {
if (matchesConditionTree(row, conditionTree, fieldMap)) {
filteredRows.add(row);
}
}
return filteredRows;
}
private boolean matchesConditionTree(Map<String, Object> row, FilterTreeObj conditionTree, Map<Long, DatasetTableFieldDTO> fieldMap) {
if (conditionTree == null || conditionTree.getItems().isEmpty()) {
return true; // 如果没有条件树或条件列表为空返回所有行
}
List<FilterTreeItem> items = conditionTree.getItems();
if (conditionTree.getLogic().equals("or")) {
return matchesAnyItem(row, items, fieldMap);
}
return matchesAllItems(row, items, fieldMap);
}
private boolean matchesAllItems(Map<String, Object> row, List<FilterTreeItem> items, Map<Long, DatasetTableFieldDTO> fieldMap) {
for (FilterTreeItem item : items) {
if (!matchesConditionItem(row, item, fieldMap)) {
return false;
}
}
return true;
}
private boolean matchesAnyItem(Map<String, Object> row, List<FilterTreeItem> items, Map<Long, DatasetTableFieldDTO> fieldMap) {
for (FilterTreeItem item : items) {
if (matchesConditionItem(row, item, fieldMap)) {
return true;
}
}
return false;
}
private boolean matchesConditionItem(Map<String, Object> row, FilterTreeItem item, Map<Long, DatasetTableFieldDTO> fieldMap) {
if ("item".equals(item.getType())) {
DatasetTableFieldDTO fieldDTO = fieldMap.get(item.getFieldId());
return rowMatch(row, item, fieldDTO);
} else if ("tree".equals(item.getType()) && item.getSubTree() != null) {
return matchesConditionTree(row, item.getSubTree(), fieldMap);
}
return false; // 如果类型不匹配或没有子树不匹配
}
private boolean rowMatch(Map<String, Object> row, FilterTreeItem item, DatasetTableFieldDTO fieldDTO) {
String dataeaseName = fieldDTO.getDataeaseName();
String filterType = item.getFilterType();
Integer deType = fieldDTO.getDeType();
Object valueObj = row.get(dataeaseName);
if (StringUtils.equals(filterType, "enum")) {
List<String> enumValue = item.getEnumValue();
return ObjectUtils.isNotEmpty(valueObj) && enumValue.contains(valueObj);
} else {
String term = item.getTerm();
if (Objects.equals(deType, DeTypeConstants.DE_STRING)) {
if (StringUtils.equals(term, "eq")) {
return StringUtils.equals(item.getValue(), valueObj.toString());
} else if (StringUtils.equals(term, "not_eq")) {
return !StringUtils.equals(item.getValue(), valueObj.toString());
} else if (StringUtils.equals(term, "in")) {
return Arrays.stream(item.getValue().split(",")).toList().contains(valueObj.toString());
} else if (StringUtils.equals(term, "not_in")) {
return !Arrays.stream(item.getValue().split(",")).toList().contains(valueObj.toString());
} else if (StringUtils.equals(term, "like")) {
return StringUtils.contains(item.getValue(), valueObj.toString());
} else if (StringUtils.equals(term, "not_like")) {
return !StringUtils.contains(item.getValue(), valueObj.toString());
} else if (StringUtils.equals(term, "null")) {
return valueObj == null;
} else if (StringUtils.equals(term, "not_null")) {
return valueObj != null;
} else if (StringUtils.equals(term, "empty")) {
return StringUtils.isBlank(valueObj.toString());
} else if (StringUtils.equals(term, "not_empty")) {
return !StringUtils.isBlank(valueObj.toString());
} else {
return StringUtils.equals(item.getValue(), valueObj.toString());
}
} else if (Objects.equals(deType, DeTypeConstants.DE_INT) || Objects.equals(deType, DeTypeConstants.DE_FLOAT)) {
if (StringUtils.equals(term, "eq")) {
return StringUtils.equals(item.getValue().toString(), valueObj.toString());
} else if (StringUtils.equals(term, "not_eq")) {
return !StringUtils.equals(item.getValue().toString(), valueObj.toString());
} else if (StringUtils.equals(term, "gt")) {
return Float.parseFloat(item.getValue().toString()) < Float.parseFloat(valueObj.toString());
} else if (StringUtils.equals(term, "ge")) {
return Float.parseFloat(item.getValue().toString()) <= Float.parseFloat(valueObj.toString());
} else if (StringUtils.equals(term, "lt")) {
return Float.parseFloat(item.getValue().toString()) > Float.parseFloat(valueObj.toString());
} else if (StringUtils.equals(term, "le")) {
return Float.parseFloat(item.getValue().toString()) >= Float.parseFloat(valueObj.toString());
} else {
return StringUtils.equals(item.getValue().toString(), valueObj.toString());
}
} else if (Objects.equals(deType, DeTypeConstants.DE_TIME)) {
// 补充时间逻辑
return true;
} else {
return true;
}
}
}
}

@ -1 +1 @@
Subproject commit 7d33cdfc9cc735685e430cc5685c21608c589218
Subproject commit d321778819aefea132bfc13633684d4011b11f90

View File

@ -0,0 +1,18 @@
package io.dataease.api.chart.request;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
public class ThresholdCheckRequest implements Serializable {
@Serial
private static final long serialVersionUID = -8377694080272137660L;
private Long chartId;
private String thresholdRules;
private String thresholdTemplate;
}

View File

@ -0,0 +1,24 @@
package io.dataease.api.chart.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class ThresholdCheckVO implements Serializable {
@Serial
private static final long serialVersionUID = 2782520137890522432L;
private boolean valid;
private String content;
private String msg;
private Long taskId;
}