feat:2.5.0

https://gitee.com/aizuda/easy-retry/issues/I8GRK2
钉钉、飞书通知告警接新增@功能
This commit is contained in:
zuojunlin 2023-11-22 22:36:26 +08:00 committed by byteblogs168
parent 4fc1550243
commit 011e04f3df
8 changed files with 46 additions and 22 deletions

View File

@ -2,8 +2,10 @@ package com.aizuda.easy.retry.common.core.alarm;
import lombok.Data; import lombok.Data;
import java.util.List;
/** /**
* 飞书地址 * 飞书
* *
* @author: www.byteblogs.com * @author: www.byteblogs.com
* @date : 2023-05-31 13:45 * @date : 2023-05-31 13:45
@ -13,4 +15,8 @@ import lombok.Data;
public class LarkAttribute { public class LarkAttribute {
private String larkUrl; private String larkUrl;
private List<String> ats;
private boolean isAtAll;
} }

View File

@ -1,5 +1,4 @@
package com.aizuda.easy.retry.common.core.alarm.strategy; package com.aizuda.easy.retry.common.core.alarm.strategy;
import cn.hutool.http.ContentType; import cn.hutool.http.ContentType;
import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpResponse;
@ -14,7 +13,8 @@ import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.text.MessageFormat;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -31,6 +31,10 @@ import java.util.Map;
@Slf4j @Slf4j
public class LarkAlarm extends AbstractAlarm<AlarmContext> { public class LarkAlarm extends AbstractAlarm<AlarmContext> {
public static final String atLabel = "<at id={0}></at>";
@Override @Override
public Integer getAlarmType() { public Integer getAlarmType() {
return AlarmTypeEnum.LARK.getValue(); return AlarmTypeEnum.LARK.getValue();
@ -52,7 +56,7 @@ public class LarkAlarm extends AbstractAlarm<AlarmContext> {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
map.put("header", buildHeader(context.getTitle())); map.put("header", buildHeader(context.getTitle()));
map.put("elements", buildElements(context.getText())); map.put("elements", buildElements(context.getText(),larkAttribute.getAts(),larkAttribute.isAtAll()));
LarkMessage builder = LarkMessage.builder() LarkMessage builder = LarkMessage.builder()
.msgType("interactive") .msgType("interactive")
@ -71,10 +75,10 @@ public class LarkAlarm extends AbstractAlarm<AlarmContext> {
return true; return true;
} }
private List buildElements(final String text) { private List buildElements(String text,List<String> ats,boolean isAtAll) {
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
map.put("tag", "markdown"); map.put("tag", "markdown");
map.put("content", text); map.put("content", getAtText(text,ats,isAtAll));
return Collections.singletonList(map); return Collections.singletonList(map);
} }
@ -110,5 +114,16 @@ public class LarkAlarm extends AbstractAlarm<AlarmContext> {
private Map<String, Object> card; private Map<String, Object> card;
} }
public String getAtText(String text, List<String> ats, boolean isAtAll) {
StringBuilder sb = new StringBuilder(text);
if (isAtAll) {
sb.append(MessageFormat.format(atLabel, "all"));
} else {
if (!CollectionUtils.isEmpty(ats)) {
ats.forEach(at -> sb.append(MessageFormat.format(atLabel, at)));
}
}
return sb.toString();
}
} }

View File

@ -8,6 +8,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.text.MessageFormat;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -17,6 +18,9 @@ import java.util.List;
*/ */
@Slf4j @Slf4j
public class DingDingUtils { public class DingDingUtils {
public static final String atLabel = "@{0}";
/** /**
* 防止文本过长钉钉限流目前最大为4000 * 防止文本过长钉钉限流目前最大为4000
* *
@ -55,14 +59,13 @@ public class DingDingUtils {
return request; return request;
} }
private static String getAtText(List<String> ats, String text) { public static String getAtText(List<String> ats, String text) {
if(CollectionUtils.isEmpty(ats)){ if (CollectionUtils.isEmpty(ats)) {
return text; return text;
} }
for(String at: ats){ StringBuilder sb = new StringBuilder(text);
text = "@" + at; ats.forEach(at -> sb.append(MessageFormat.format(atLabel, at)));
} return sb.toString();
return text;
} }
/** /**

View File

@ -107,7 +107,7 @@ public class RetryTaskFailDeadLetterAlarmListener extends AbstractFlowControl im
retryDeadLetter.getSceneName(), retryDeadLetter.getSceneName(),
retryDeadLetter.getArgsStr(), retryDeadLetter.getArgsStr(),
DateUtils.format(retryDeadLetter.getCreateDt(), DateUtils.NORM_DATETIME_PATTERN)) DateUtils.format(retryDeadLetter.getCreateDt(), DateUtils.NORM_DATETIME_PATTERN))
.title("组:[{}] 场景:[{}] 环境重试任务失败进入死信队列", retryDeadLetter.getGroupName(), retryDeadLetter.getSceneName()) .title("{}环境 重试任务失败进入死信队列", EnvironmentUtils.getActiveProfile())
.notifyAttribute(notifyConfig.getNotifyAttribute()); .notifyAttribute(notifyConfig.getNotifyAttribute());
Alarm<AlarmContext> alarmType = easyRetryAlarmFactory.getAlarmType(notifyConfig.getNotifyType()); Alarm<AlarmContext> alarmType = easyRetryAlarmFactory.getAlarmType(notifyConfig.getNotifyType());
alarmType.asyncSendMessage(context); alarmType.asyncSendMessage(context);

View File

@ -98,7 +98,7 @@ public class RetryTaskFailMoreThresholdAlarmListener extends AbstractFlowControl
retryTask.getRetryCount(), retryTask.getRetryCount(),
retryTask.getArgsStr(), retryTask.getArgsStr(),
DateUtils.format(retryTask.getCreateDt(), DateUtils.NORM_DATETIME_PATTERN)) DateUtils.format(retryTask.getCreateDt(), DateUtils.NORM_DATETIME_PATTERN))
.title("组:[{}] 场景:[{}] 环境重试任务失败数量超过阈值", retryTask.getGroupName(), retryTask.getSceneName()) .title("{}环境 环境重试任务失败数量超过阈值", EnvironmentUtils.getActiveProfile())
.notifyAttribute(notifyConfig.getNotifyAttribute()); .notifyAttribute(notifyConfig.getNotifyAttribute());
Alarm<AlarmContext> alarmType = easyRetryAlarmFactory.getAlarmType(notifyConfig.getNotifyType()); Alarm<AlarmContext> alarmType = easyRetryAlarmFactory.getAlarmType(notifyConfig.getNotifyType());
alarmType.asyncSendMessage(context); alarmType.asyncSendMessage(context);

View File

@ -81,8 +81,8 @@ public class RetryErrorMoreThresholdAlarmSchedule extends AbstractSchedule imple
sceneConfig.getSceneName(), sceneConfig.getSceneName(),
DateUtils.format(now.minusMinutes(30), DateUtils.format(now.minusMinutes(30),
DateUtils.NORM_DATETIME_PATTERN), DateUtils.NORM_DATETIME_PATTERN),
DateUtils.toNowFormat(DateUtils.NORM_DATETIME_PATTERN), count) DateUtils.toNowFormat(DateUtils.NORM_DATETIME_PATTERN), count)
.title("组:[{}] 场景:[{}] 环境重试失败数据监控", sceneConfig.getGroupName(),sceneConfig.getSceneName()) .title("{}环境 场景重试失败数量超过阈值", EnvironmentUtils.getActiveProfile())
.notifyAttribute(notifyConfig.getNotifyAttribute()); .notifyAttribute(notifyConfig.getNotifyAttribute());
Alarm<AlarmContext> alarmType = easyRetryAlarmFactory.getAlarmType(notifyConfig.getNotifyType()); Alarm<AlarmContext> alarmType = easyRetryAlarmFactory.getAlarmType(notifyConfig.getNotifyType());
alarmType.asyncSendMessage(context); alarmType.asyncSendMessage(context);

View File

@ -79,7 +79,7 @@ public class RetryTaskMoreThresholdAlarmSchedule extends AbstractSchedule implem
sceneConfig.getSceneName(), sceneConfig.getSceneName(),
DateUtils.toNowFormat(DateUtils.NORM_DATETIME_PATTERN), DateUtils.toNowFormat(DateUtils.NORM_DATETIME_PATTERN),
count) count)
.title("组:[{}] 场景:[{}] 重试数据过多", sceneConfig.getGroupName(),sceneConfig.getSceneName()) .title("{}环境 场景重试数量超过阈值", EnvironmentUtils.getActiveProfile())
.notifyAttribute(notifyConfig.getNotifyAttribute()); .notifyAttribute(notifyConfig.getNotifyAttribute());
Alarm<AlarmContext> alarmType = easyRetryAlarmFactory.getAlarmType(notifyConfig.getNotifyType()); Alarm<AlarmContext> alarmType = easyRetryAlarmFactory.getAlarmType(notifyConfig.getNotifyType());
alarmType.asyncSendMessage(context); alarmType.asyncSendMessage(context);

View File

@ -163,14 +163,14 @@
]" /> ]" />
</a-form-item> </a-form-item>
<a-form-item v-if="this.notifyTypeValue === '1'"> <a-form-item v-if="this.notifyTypeValue === '1'">
<span slot="label">@负责人手机号&nbsp;<a :href="officialWebsite + '/pages/32e4a0/#被@负责人手机号是何物' +''" target="_blank"> <a-icon type="question-circle-o" /></a></span> <span slot="label">@人手机号&nbsp;<a :href="officialWebsite + '/pages/32e4a0/#被@人手机号是何物' +''" target="_blank"> <a-icon type="question-circle-o" /></a></span>
<a-input <a-input
placeholder="请输入被@负责人手机号" placeholder="请输入被@负责人手机号"
type="textarea" type="textarea"
v-if="this.notifyTypeValue === '1'" v-if="this.notifyTypeValue === '1'"
v-decorator="[ v-decorator="[
'ats', 'ats',
{rules: [{ required: true, message: '请输入被@负责人手机号', whitespace: true}]} {rules: [{ required: true, message: '请输入被@人手机号', whitespace: true}]}
]" /> ]" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item
@ -185,14 +185,14 @@
</a-form-item> </a-form-item>
<a-form-item <a-form-item
v-if="this.notifyTypeValue === '4'"> v-if="this.notifyTypeValue === '4'">
<span slot="label">@负责人用户id&nbsp;<a :href="officialWebsite + '/pages/32e4a0/#被@负责人用户id是何物' +''" target="_blank"> <a-icon type="question-circle-o" /></a></span> <span slot="label">@负责人用户id&nbsp;<a :href="officialWebsite + '/pages/32e4a0/#被@人open_id是何物' +''" target="_blank"> <a-icon type="question-circle-o" /></a></span>
<a-input <a-input
placeholder="请输入被@负责人用户id" placeholder="请输入被@人open_id"
type="textarea" type="textarea"
v-if="this.notifyTypeValue === '4'" v-if="this.notifyTypeValue === '4'"
v-decorator="[ v-decorator="[
'ats', 'ats',
{rules: [{ required: true, message: '请输入被@负责人用户id', whitespace: true}]} {rules: [{ required: true, message: '请输入被@人open_id', whitespace: true}]}
]" /> ]" />
</a-form-item> </a-form-item>
<a-form-item <a-form-item