feat: 1.4.0
1. 新增飞书告警
This commit is contained in:
parent
1d0e792eb0
commit
373c72e35d
@ -0,0 +1,16 @@
|
||||
package com.aizuda.easy.retry.common.core.alarm;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 飞书地址
|
||||
*
|
||||
* @author: www.byteblogs.com
|
||||
* @date : 2023-05-31 13:45
|
||||
* @since 1.4.0
|
||||
*/
|
||||
@Data
|
||||
public class LarkAttribute {
|
||||
|
||||
private String larkUrl;
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package com.aizuda.easy.retry.common.core.alarm.strategy;
|
||||
|
||||
import cn.hutool.http.ContentType;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.aizuda.easy.retry.common.core.alarm.AlarmContext;
|
||||
import com.aizuda.easy.retry.common.core.alarm.LarkAttribute;
|
||||
import com.aizuda.easy.retry.common.core.enums.AlarmTypeEnum;
|
||||
import com.aizuda.easy.retry.common.core.log.LogUtils;
|
||||
import com.aizuda.easy.retry.common.core.util.JsonUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 飞书通知
|
||||
*
|
||||
* @author: www.byteblogs.com
|
||||
* @date : 2021-11-25 09:20
|
||||
* @since 1.4.0
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class LarkAlarm extends AbstractAlarm<AlarmContext> {
|
||||
|
||||
@Override
|
||||
public Integer getAlarmType() {
|
||||
return AlarmTypeEnum.LARK.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSendMessage(AlarmContext context) {
|
||||
threadPoolExecutor.execute(() -> {
|
||||
syncSendMessage(context);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean syncSendMessage(AlarmContext context) {
|
||||
|
||||
LarkAttribute larkAttribute = JsonUtil.parseObject(context.getNotifyAttribute(), LarkAttribute.class);
|
||||
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("header", buildHeader(context.getTitle()));
|
||||
map.put("elements", buildElements(context.getText()));
|
||||
|
||||
LarkMessage builder = LarkMessage.builder()
|
||||
.msgType("interactive")
|
||||
.card(map).build();
|
||||
|
||||
try {
|
||||
HttpRequest post = HttpUtil.createPost(larkAttribute.getLarkUrl());
|
||||
HttpRequest request = post.body(JsonUtil.toJsonString(builder), ContentType.JSON.toString());
|
||||
HttpResponse execute = request.execute();
|
||||
LogUtils.debug(log, JsonUtil.toJsonString(execute));
|
||||
} catch (Exception e) {
|
||||
log.error("发送lark消息失败", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private List buildElements(final String text) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("tag", "markdown");
|
||||
map.put("content", text);
|
||||
return Collections.singletonList(map);
|
||||
}
|
||||
|
||||
private Map<String, Object> buildHeader(final String title) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("template", "red");
|
||||
|
||||
Map<String, String> titleMap = new HashMap<>();
|
||||
titleMap.put("content", title);
|
||||
titleMap.put("tag", "plain_text");
|
||||
|
||||
map.put("title", titleMap);
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean asyncSendMessage(List<AlarmContext> notifierElements) {
|
||||
|
||||
for (AlarmContext notifierElement : notifierElements) {
|
||||
asyncSendMessage(notifierElement);
|
||||
}
|
||||
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
private static class LarkMessage {
|
||||
|
||||
@JsonProperty("msg_type")
|
||||
private String msgType;
|
||||
|
||||
private Map<String, Object> card;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,11 @@ public enum AlarmTypeEnum {
|
||||
* 企业通知
|
||||
*/
|
||||
QI_YE_WECHAT(3),
|
||||
|
||||
/**
|
||||
* 飞书
|
||||
*/
|
||||
LARK(4),
|
||||
;
|
||||
|
||||
private final int value;
|
||||
|
@ -36,16 +36,16 @@ public class AlarmNotifyThreadSchedule {
|
||||
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private static String retryErrorMoreThresholdTextMessageFormatter =
|
||||
"<font face=\"微软雅黑\" color=#ff0000 size=4>{}环境 重试失败数据监控</font> </br>" +
|
||||
"> 名称:{} </br>" +
|
||||
"> 时间窗口:{} ~ {} </br>" +
|
||||
"<font face=\"微软雅黑\" color=#ff0000 size=4>{}环境 重试失败数据监控</font> \n" +
|
||||
"> 名称:{} \n" +
|
||||
"> 时间窗口:{} ~ {} \n" +
|
||||
"> **共计:{}** \n";
|
||||
|
||||
private static String retryTaskMoreThresholdTextMessageFormatter =
|
||||
"<font face=\"微软雅黑\" color=#ff0000 size=4>{}环境 重试数据监控</font> </br>" +
|
||||
"> 名称:{} </br>" +
|
||||
"> 时间:{} </br>" +
|
||||
"> **共计:{}** </br>";
|
||||
"<font face=\"微软雅黑\" color=#ff0000 size=4>{}环境 重试数据监控</font> \n" +
|
||||
"> 名称:{} \n" +
|
||||
"> 时间:{} \n" +
|
||||
"> **共计:{}** \n";
|
||||
|
||||
@Autowired
|
||||
private RetryDeadLetterMapper retryDeadLetterMapper;
|
||||
@ -60,8 +60,8 @@ public class AlarmNotifyThreadSchedule {
|
||||
/**
|
||||
* 监控重试表中数据总量是否到达阈值
|
||||
*/
|
||||
@Scheduled(cron = "0 0/10 * * * ?")
|
||||
@SchedulerLock(name = "retryTaskMoreThreshold", lockAtMostFor = "PT10M", lockAtLeastFor = "PT10M")
|
||||
@Scheduled(cron = "0 0/1 * * * ?")
|
||||
@SchedulerLock(name = "retryTaskMoreThreshold", lockAtMostFor = "PT1M", lockAtLeastFor = "PT1M")
|
||||
public void retryTaskMoreThreshold() {
|
||||
LogUtils.info(log, "retryTaskMoreThreshold time[{}] ip:[{}]", LocalDateTime.now(), HostUtils.getIp());
|
||||
|
||||
|
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 8.7 KiB |
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
<!DOCTYPE html><html lang="zh-cmn-Hans"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/logo.png"><title>Easy-Retry</title><style>.first-loading-wrp{display:flex;justify-content:center;align-items:center;flex-direction:column;min-height:420px;height:100%}.first-loading-wrp>h1{font-size:128px}.first-loading-wrp .loading-wrp{padding:98px;display:flex;justify-content:center;align-items:center}.dot{animation:antRotate 1.2s infinite linear;transform:rotate(45deg);position:relative;display:inline-block;font-size:32px;width:32px;height:32px;box-sizing:border-box}.dot i{width:14px;height:14px;position:absolute;display:block;background-color:#1890ff;border-radius:100%;transform:scale(.75);transform-origin:50% 50%;opacity:.3;animation:antSpinMove 1s infinite linear alternate}.dot i:nth-child(1){top:0;left:0}.dot i:nth-child(2){top:0;right:0;-webkit-animation-delay:.4s;animation-delay:.4s}.dot i:nth-child(3){right:0;bottom:0;-webkit-animation-delay:.8s;animation-delay:.8s}.dot i:nth-child(4){bottom:0;left:0;-webkit-animation-delay:1.2s;animation-delay:1.2s}@keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@-webkit-keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@keyframes antSpinMove{to{opacity:1}}@-webkit-keyframes antSpinMove{to{opacity:1}}</style><link href="/css/chunk-758b2aa4.1c9c785f.css" rel="prefetch"><link href="/css/chunk-77aaac2a.99cbbcce.css" rel="prefetch"><link href="/css/chunk-ff9025ec.cd4961ff.css" rel="prefetch"><link href="/css/user.6ccd4506.css" rel="prefetch"><link href="/js/chunk-2d0a4079.3bbb423d.js" rel="prefetch"><link href="/js/chunk-2d0b7230.fe38dce0.js" rel="prefetch"><link href="/js/chunk-2d0c8f97.72c6927b.js" rel="prefetch"><link href="/js/chunk-2d0d43f4.f5bb36b7.js" rel="prefetch"><link href="/js/chunk-2d0f085f.b8852e6c.js" rel="prefetch"><link href="/js/chunk-2d21a08f.6cb549d6.js" rel="prefetch"><link href="/js/chunk-2d228eef.955019b5.js" rel="prefetch"><link href="/js/chunk-40597980.5e57166b.js" rel="prefetch"><link href="/js/chunk-732da7b5.251276b0.js" rel="prefetch"><link href="/js/chunk-758b2aa4.b88de219.js" rel="prefetch"><link href="/js/chunk-77aaac2a.bb4621bb.js" rel="prefetch"><link href="/js/chunk-ff9025ec.a77618ce.js" rel="prefetch"><link href="/js/fail.fe1af659.js" rel="prefetch"><link href="/js/lang-zh-CN-account-settings.f8f25eaf.js" rel="prefetch"><link href="/js/lang-zh-CN-account.c724e71d.js" rel="prefetch"><link href="/js/lang-zh-CN-dashboard-analysis.d7cabd65.js" rel="prefetch"><link href="/js/lang-zh-CN-dashboard.5180154b.js" rel="prefetch"><link href="/js/lang-zh-CN-form-basicForm.ff3088ac.js" rel="prefetch"><link href="/js/lang-zh-CN-form.cc39e450.js" rel="prefetch"><link href="/js/lang-zh-CN-global.bf0df5c8.js" rel="prefetch"><link href="/js/lang-zh-CN-menu.25425a62.js" rel="prefetch"><link href="/js/lang-zh-CN-result-fail.232762aa.js" rel="prefetch"><link href="/js/lang-zh-CN-result-success.3519c60c.js" rel="prefetch"><link href="/js/lang-zh-CN-result.32c5cf1c.js" rel="prefetch"><link href="/js/lang-zh-CN-setting.8c2ce690.js" rel="prefetch"><link href="/js/lang-zh-CN-user.81513cba.js" rel="prefetch"><link href="/js/lang-zh-CN.3dfa92aa.js" rel="prefetch"><link href="/js/user.8401c9c6.js" rel="prefetch"><link href="/css/app.b0a9877f.css" rel="preload" as="style"><link href="/css/chunk-vendors.5be6e05a.css" rel="preload" as="style"><link href="/js/app.b84c86ee.js" rel="preload" as="script"><link href="/js/chunk-vendors.87c1e94d.js" rel="preload" as="script"><link href="/css/chunk-vendors.5be6e05a.css" rel="stylesheet"><link href="/css/app.b0a9877f.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"><div class="first-loading-wrp"><h2>Easy-Retry</h2><div class="loading-wrp"><span class="dot dot-spin"><i></i><i></i><i></i><i></i></span></div><div style="display: flex; justify-content: center; align-items: center;">分布式重试服务平台</div></div></div><script src="//cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script><script src="//cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script><script src="//cdn.jsdelivr.net/npm/vuex@3.1.1/dist/vuex.min.js"></script><script src="//cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.min.js"></script><script src="/js/chunk-vendors.87c1e94d.js"></script><script src="/js/app.b84c86ee.js"></script></body></html>
|
||||
<!DOCTYPE html><html lang="zh-cmn-Hans"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/logo.png"><title>Easy-Retry</title><style>.first-loading-wrp{display:flex;justify-content:center;align-items:center;flex-direction:column;min-height:420px;height:100%}.first-loading-wrp>h1{font-size:128px}.first-loading-wrp .loading-wrp{padding:98px;display:flex;justify-content:center;align-items:center}.dot{animation:antRotate 1.2s infinite linear;transform:rotate(45deg);position:relative;display:inline-block;font-size:32px;width:32px;height:32px;box-sizing:border-box}.dot i{width:14px;height:14px;position:absolute;display:block;background-color:#1890ff;border-radius:100%;transform:scale(.75);transform-origin:50% 50%;opacity:.3;animation:antSpinMove 1s infinite linear alternate}.dot i:nth-child(1){top:0;left:0}.dot i:nth-child(2){top:0;right:0;-webkit-animation-delay:.4s;animation-delay:.4s}.dot i:nth-child(3){right:0;bottom:0;-webkit-animation-delay:.8s;animation-delay:.8s}.dot i:nth-child(4){bottom:0;left:0;-webkit-animation-delay:1.2s;animation-delay:1.2s}@keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@-webkit-keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@keyframes antSpinMove{to{opacity:1}}@-webkit-keyframes antSpinMove{to{opacity:1}}</style><link href="/css/chunk-758b2aa4.1c9c785f.css" rel="prefetch"><link href="/css/chunk-77aaac2a.99cbbcce.css" rel="prefetch"><link href="/css/chunk-ff9025ec.cd4961ff.css" rel="prefetch"><link href="/css/user.6ccd4506.css" rel="prefetch"><link href="/js/chunk-2d0a4079.3fd83a06.js" rel="prefetch"><link href="/js/chunk-2d0b7230.c3459f7c.js" rel="prefetch"><link href="/js/chunk-2d0c8f97.d91a8ff0.js" rel="prefetch"><link href="/js/chunk-2d0d43f4.bcedfa8c.js" rel="prefetch"><link href="/js/chunk-2d0f085f.182cc3eb.js" rel="prefetch"><link href="/js/chunk-2d21a08f.00dcc26b.js" rel="prefetch"><link href="/js/chunk-2d228eef.b6c79dd3.js" rel="prefetch"><link href="/js/chunk-40597980.defad4c9.js" rel="prefetch"><link href="/js/chunk-732da7b5.8f5bea60.js" rel="prefetch"><link href="/js/chunk-758b2aa4.05d3a08d.js" rel="prefetch"><link href="/js/chunk-77aaac2a.355915ce.js" rel="prefetch"><link href="/js/chunk-ff9025ec.72b2b536.js" rel="prefetch"><link href="/js/fail.525733e9.js" rel="prefetch"><link href="/js/lang-zh-CN-account-settings.f8f25eaf.js" rel="prefetch"><link href="/js/lang-zh-CN-account.f7a734c3.js" rel="prefetch"><link href="/js/lang-zh-CN-dashboard-analysis.d7cabd65.js" rel="prefetch"><link href="/js/lang-zh-CN-dashboard.ffd6ecbd.js" rel="prefetch"><link href="/js/lang-zh-CN-form-basicForm.ff3088ac.js" rel="prefetch"><link href="/js/lang-zh-CN-form.39cd9999.js" rel="prefetch"><link href="/js/lang-zh-CN-global.bf0df5c8.js" rel="prefetch"><link href="/js/lang-zh-CN-menu.25425a62.js" rel="prefetch"><link href="/js/lang-zh-CN-result-fail.232762aa.js" rel="prefetch"><link href="/js/lang-zh-CN-result-success.3519c60c.js" rel="prefetch"><link href="/js/lang-zh-CN-result.b3df3bc6.js" rel="prefetch"><link href="/js/lang-zh-CN-setting.8c2ce690.js" rel="prefetch"><link href="/js/lang-zh-CN-user.81513cba.js" rel="prefetch"><link href="/js/lang-zh-CN.6ae67127.js" rel="prefetch"><link href="/js/user.7c451146.js" rel="prefetch"><link href="/css/app.37a20ada.css" rel="preload" as="style"><link href="/css/chunk-vendors.5be6e05a.css" rel="preload" as="style"><link href="/js/app.11cd2525.js" rel="preload" as="script"><link href="/js/chunk-vendors.b8c3b6d4.js" rel="preload" as="script"><link href="/css/chunk-vendors.5be6e05a.css" rel="stylesheet"><link href="/css/app.37a20ada.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"><div class="first-loading-wrp"><h2>Easy-Retry</h2><div class="loading-wrp"><span class="dot dot-spin"><i></i><i></i><i></i><i></i></span></div><div style="display: flex; justify-content: center; align-items: center;">分布式重试服务平台</div></div></div><script src="//cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script><script src="//cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script><script src="//cdn.jsdelivr.net/npm/vuex@3.1.1/dist/vuex.min.js"></script><script src="//cdn.jsdelivr.net/npm/axios@0.21.1/dist/axios.min.js"></script><script src="/js/chunk-vendors.b8c3b6d4.js"></script><script src="/js/app.11cd2525.js"></script></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -109,7 +109,7 @@
|
||||
<a-input
|
||||
placeholder="请输入飞书URL"
|
||||
v-decorator="[
|
||||
'feiShuUrl',
|
||||
'larkUrl',
|
||||
{rules: [{ required: true, message: '请输入飞书URL', whitespace: true}]}
|
||||
]" />
|
||||
</a-form-item>
|
||||
@ -385,7 +385,7 @@ export default {
|
||||
setTimeout(resolve, 1500)
|
||||
}).then(() => {
|
||||
const { form } = this
|
||||
const formData = pick(record.notifyAttribute, ['dingDingUrl', 'feiShuUrl', 'user', 'pass', 'host', 'port', 'from', 'tos'])
|
||||
const formData = pick(record.notifyAttribute, ['dingDingUrl', 'larkUrl', 'user', 'pass', 'host', 'port', 'from', 'tos'])
|
||||
console.log(formData)
|
||||
form.setFieldsValue(formData)
|
||||
})
|
||||
@ -422,7 +422,7 @@ export default {
|
||||
if (record.notifyType === '1') {
|
||||
s = '钉钉地址:' + text['dingDingUrl'] + ';'
|
||||
} else if (record.notifyType === '4') {
|
||||
s = '飞书地址:' + text['feiShuUrl'] + ';'
|
||||
s = '飞书地址:' + text['larkUrl'] + ';'
|
||||
}
|
||||
|
||||
return s
|
||||
|
Loading…
Reference in New Issue
Block a user