public static void main(String[] args) {
String data = "{\"dashboardId\":15,\"evalMatches\":[{\"value\":30,\"metric\":\"172.16.0.13:9082\",\"tags\":{\"__name__\":\"tomcat_threads_current_threads\",\"application\":\"cms\",\"instance\":\"172.16.0.13:9082\",\"job\":\"app-prometheus\",\"name\":\"http-nio-9082\",\"service\":\"cms\"}},{\"value\":30,\"metric\":\"172.16.0.4:9082\",\"tags\":{\"__name__\":\"tomcat_threads_current_threads\",\"application\":\"cms\",\"instance\":\"172.16.0.4:9082\",\"job\":\"app-prometheus\",\"name\":\"http-nio-9082\",\"service\":\"cms\"}}],\"message\":\"cms服务健康异常,请紧急处理!\",\"orgId\":1,\"panelId\":2,\"ruleId\":34,\"ruleName\":\"service-monitor-health\",\"ruleUrl\":\"http://localhost:9997/grafana/d/ScxflbaGz/fu-wu-jian-kang-pei-zhi?fullscreen\\u0026edit\\u0026tab=alert\\u0026panelId=2\\u0026orgId=1\",\"state\":\"alerting\",\"tags\":{},\"title\":\"[Alerting] service-monitor-health\"}";
String s = parsePlaceholder("主机{{evalMatches.[*].tags.instance}}异常,状态:{{state}}", data);
System.out.println(s);
}
/**
* @param str 含占位符需要处理的字符串
* @param placeholderDataSource 只能为json字符串或map
*/
@SuppressWarnings({ "unchecked" })
private static String parsePlaceholder(String str, Object placeholderDataSource) {
if (StringUtils.isBlank(str) || placeholderDataSource == null) {
return str;
}
if (!(placeholderDataSource instanceof CharSequence) && !(placeholderDataSource instanceof Map)) {
return str;
}
Pattern compile = Pattern.compile("\\{\\{[\\[\\*\\]\\.\\w-]+\\}\\}");
Matcher matcher = compile.matcher(str);
Set<String> klist = new HashSet<String>();
while (matcher.find()) {
String gstr = matcher.group();
klist.add(gstr);
}
if (klist.size() == 0) {
return str;
}
Map<Object, Object> map = null;
if (placeholderDataSource instanceof CharSequence) {
map = JsonUtils.parseObject(placeholderDataSource.toString(), new TypeReference<Map<Object, Object>>() {});
} else {
map = (Map<Object, Object>) placeholderDataSource;
}
Map<String, Object> dmap = new HashMap<String, Object>();
parse(null, map, dmap);
for (String key : klist) {
String pkey = key.substring(2, key.length() - 2);
Object tval = dmap.get(pkey);
String val = StringUtils.EMPTY;
if (tval != null) {
val = JsonUtils.toString(tval);
}
str = str.replace(key, val);
}
return str;
}
@SuppressWarnings("unchecked")
private static Map<String, Object> parse(String ckey, Object data, Map<String, Object> pdataMap) {
if (data == null || pdataMap == null || pdataMap.size() > 10000) return pdataMap;
if (StringUtils.isNotEmpty(ckey)) {
pdataMap.put(ckey, data);
}
if (data instanceof Map) {
Map<Object, Object> map = (Map<Object, Object>) data;
Set<Entry<Object, Object>> eset = map.entrySet();
for (Entry<Object, Object> entry : eset) {
Object tmpkey = entry.getKey();
if (tmpkey == null || !(tmpkey instanceof CharSequence)) {
continue;
}
String key = tmpkey.toString();
Object value = entry.getValue();
String newKey = StringUtils.isEmpty(ckey) ? key : (ckey + SeparatorChar.POINT + key);
parse(newKey, value, pdataMap);
}
} else if (data instanceof List) {
List<Object> list = (List<Object>) data;
List<Map<String, Object>> ilist = new LinkedList<Map<String,Object>>();
for (int i = 0; i < list.size(); i++) {
Map<String, Object> idataMap = new HashMap<String, Object>();
Object object = list.get(i);
String ikey = ckey + ".[" + i + "]";
pdataMap.put(ikey, object);
parse(ikey, object, idataMap);
ilist.add(idataMap);
}
Map<String, String> kmappingMap = new HashMap<String, String>();
ilist.parallelStream().map(p -> p.keySet()).forEach(p -> p.parallelStream().forEach(p1 -> {
String mkey = p1.replaceAll("\\.\\[[0-9]+\\]", "\\.\\[\\*\\]");
kmappingMap.put(p1, mkey);
}));
Map<String, List<Object>> arrmap = new HashMap<String, List<Object>>();
kmappingMap.entrySet().stream().forEach(p -> {
String k = p.getKey();
String pkey = p.getValue();
List<Object> iplist = arrmap.get(pkey);
if (iplist == null) {
arrmap.put(pkey, iplist = new LinkedList<Object>());
}
for (int i = 0; i < ilist.size(); i++) {
Map<String, Object> tmap = ilist.get(i);
Object val = tmap.get(k);
if (val == null) {
continue;
}
iplist.add(val);
}
});
pdataMap.putAll(arrmap);
ilist.parallelStream().forEach(pdataMap::putAll);
}
return pdataMap;
}