Optimized alarm notification capabilities (#435)

pull/436/head
小马哥 2 years ago committed by GitHub
parent d42ee68be4
commit 89fcf99fa9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,82 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.common.toolkit;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
/**
* Singleton object container.
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class Singleton {
private static final ConcurrentHashMap<String, Object> SINGLE_OBJECT_POOL = new ConcurrentHashMap();
/**
* Get a singleton object by key.
*
* @param key
* @param <T>
* @return
*/
public static <T> T get(String key) {
Object result = SINGLE_OBJECT_POOL.get(key);
return result == null ? null : (T) result;
}
/**
* Get a singleton object by key.
*
* <p> When empty, build a singleton object through supplier and put it into the container.
*
* @param key
* @param supplier
* @param <T>
* @return
*/
public static <T> T get(String key, Supplier<T> supplier) {
Object result = SINGLE_OBJECT_POOL.get(key);
if (result == null && (result = supplier.get()) != null) {
SINGLE_OBJECT_POOL.put(key, result);
}
return result != null ? (T) result : null;
}
/**
* Object into container.
*
* @param value
*/
public static void put(Object value) {
put(value.getClass().getName(), value);
}
/**
* Object into container.
*
* @param key
* @param value
*/
public static void put(String key, Object value) {
SINGLE_OBJECT_POOL.put(key, value);
}
}

@ -17,6 +17,7 @@
package cn.hippo4j.message.platform;
import cn.hippo4j.common.toolkit.Singleton;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.message.dto.NotifyConfigDTO;
import cn.hippo4j.message.enums.NotifyPlatformEnum;
@ -54,13 +55,15 @@ public class DingSendMessageHandler extends AbstractRobotSendMessageHandler {
@Override
protected RobotMessageActualContent buildMessageActualContent() {
String dingAlarmTxtKey = "message/robot/dynamic-thread-pool/ding-alarm.txt";
String dingConfigTxtKey = "message/robot/dynamic-thread-pool/ding-config.txt";
RobotMessageActualContent robotMessageActualContent = RobotMessageActualContent.builder()
.receiveSeparator(", @")
.changeSeparator(" -> ")
.replaceTxt(DING_ALARM_TIMOUT_REPLACE_TXT)
.traceReplaceTxt(DING_ALARM_TIMOUT_TRACE_REPLACE_TXT)
.alarmMessageContent(FileUtil.readUtf8String("message/robot/dynamic-thread-pool/ding-alarm.txt"))
.configMessageContent(FileUtil.readUtf8String("message/robot/dynamic-thread-pool/ding-config.txt"))
.alarmMessageContent(Singleton.get(dingAlarmTxtKey, () -> FileUtil.readUtf8String(dingAlarmTxtKey)))
.configMessageContent(Singleton.get(dingConfigTxtKey, () -> FileUtil.readUtf8String(dingConfigTxtKey)))
.build();
return robotMessageActualContent;
}

@ -17,6 +17,7 @@
package cn.hippo4j.message.platform;
import cn.hippo4j.common.toolkit.Singleton;
import cn.hippo4j.message.dto.NotifyConfigDTO;
import cn.hippo4j.message.enums.NotifyPlatformEnum;
import cn.hippo4j.message.enums.NotifyTypeEnum;
@ -25,6 +26,7 @@ import cn.hippo4j.message.request.AlarmNotifyRequest;
import cn.hippo4j.message.request.ChangeParameterNotifyRequest;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import lombok.AllArgsConstructor;
@ -53,20 +55,25 @@ public class LarkSendMessageHandler implements SendMessageHandler<AlarmNotifyReq
@SneakyThrows
public void sendAlarmMessage(NotifyConfigDTO notifyConfig, AlarmNotifyRequest alarmNotifyRequest) {
String afterReceives = getReceives(notifyConfig.getReceives());
String larkAlarmTxt;
String larkAlarmTimoutReplaceTxt;
String larkAlarmTxtKey = "message/robot/dynamic-thread-pool/lark-alarm.json";
String larkAlarmTxt = Singleton.get(larkAlarmTxtKey, () -> FileUtil.readUtf8String(larkAlarmTxtKey));
String larkAlarmTimoutReplaceJsonKey = "message/robot/dynamic-thread-pool/lark-alarm-timeout-replace.json";
String larkAlarmTimoutReplaceJson = Singleton.get(larkAlarmTimoutReplaceJsonKey, () -> FileUtil.readUtf8String(larkAlarmTimoutReplaceJsonKey));
if (Objects.equals(alarmNotifyRequest.getNotifyTypeEnum(), NotifyTypeEnum.TIMEOUT)) {
String executeTimeoutTrace = alarmNotifyRequest.getExecuteTimeoutTrace();
String larkAlarmTimoutTraceReplaceJsonKey = "message/robot/dynamic-thread-pool/lark-alarm-trace-replace.json";
String larkAlarmTimoutTraceReplaceJson = Singleton.get(larkAlarmTimoutTraceReplaceJsonKey, () -> FileUtil.readUtf8String(larkAlarmTimoutTraceReplaceJsonKey));
if (StringUtil.isNotBlank(executeTimeoutTrace)) {
String larkAlarmTimoutTraceReplaceTxt = String.format(LARK_ALARM_TIMOUT_TRACE_REPLACE_TXT, executeTimeoutTrace);
larkAlarmTimoutReplaceTxt = StrUtil.replace(LARK_ALARM_TIMOUT_REPLACE_TXT, LARK_ALARM_TIMOUT_TRACE_REPLACE_TXT, larkAlarmTimoutTraceReplaceTxt);
String larkAlarmTimoutTraceReplaceTxt = String.format(larkAlarmTimoutTraceReplaceJson, executeTimeoutTrace);
larkAlarmTimoutReplaceTxt = StrUtil.replace(larkAlarmTimoutReplaceJson, larkAlarmTimoutTraceReplaceJson, larkAlarmTimoutTraceReplaceTxt);
} else {
larkAlarmTimoutReplaceTxt = StrUtil.replace(LARK_ALARM_TIMOUT_REPLACE_TXT, LARK_ALARM_TIMOUT_TRACE_REPLACE_TXT, "");
larkAlarmTimoutReplaceTxt = StrUtil.replace(larkAlarmTimoutReplaceJson, larkAlarmTimoutTraceReplaceJson, "");
}
larkAlarmTimoutReplaceTxt = String.format(larkAlarmTimoutReplaceTxt, alarmNotifyRequest.getExecuteTime(), alarmNotifyRequest.getExecuteTimeOut());
larkAlarmTxt = StrUtil.replace(LARK_ALARM_JSON_STR, LARK_ALARM_TIMOUT_REPLACE_TXT, larkAlarmTimoutReplaceTxt);
larkAlarmTxt = StrUtil.replace(larkAlarmTxt, larkAlarmTimoutReplaceJson, larkAlarmTimoutReplaceTxt);
} else {
larkAlarmTxt = StrUtil.replace(LARK_ALARM_JSON_STR, LARK_ALARM_TIMOUT_REPLACE_TXT, "");
larkAlarmTxt = StrUtil.replace(larkAlarmTxt, larkAlarmTimoutReplaceJson, "");
}
String text = String.format(larkAlarmTxt,
@ -118,7 +125,8 @@ public class LarkSendMessageHandler implements SendMessageHandler<AlarmNotifyReq
public void sendChangeMessage(NotifyConfigDTO notifyConfig, ChangeParameterNotifyRequest changeParameterNotifyRequest) {
String threadPoolId = changeParameterNotifyRequest.getThreadPoolId();
String afterReceives = getReceives(notifyConfig.getReceives());
String larkNoticeJson = LARK_NOTICE_JSON_STR;
String larkNoticeJsonKey = "message/robot/dynamic-thread-pool/lark-config.json";
String larkNoticeJson = Singleton.get(larkNoticeJsonKey, () -> FileUtil.readUtf8String(larkNoticeJsonKey));
String text = String.format(larkNoticeJson,
// 环境
changeParameterNotifyRequest.getActive(),

@ -18,6 +18,7 @@
package cn.hippo4j.message.platform;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.Singleton;
import cn.hippo4j.message.enums.NotifyPlatformEnum;
import cn.hippo4j.message.platform.base.AbstractRobotSendMessageHandler;
import cn.hippo4j.message.platform.base.RobotMessageActualContent;
@ -43,13 +44,15 @@ public class WeChatSendMessageHandler extends AbstractRobotSendMessageHandler {
@Override
protected RobotMessageActualContent buildMessageActualContent() {
String weChatAlarmTxtKet = "message/robot/dynamic-thread-pool/wechat-alarm.txt";
String weChatConfigTxtKet = "message/robot/dynamic-thread-pool/wechat-alarm.txt";
RobotMessageActualContent robotMessageActualContent = RobotMessageActualContent.builder()
.receiveSeparator("><@")
.changeSeparator(" ➲ ")
.replaceTxt(WE_CHAT_ALARM_TIMOUT_REPLACE_TXT)
.traceReplaceTxt(WE_CHAT_ALARM_TIMOUT_TRACE_REPLACE_TXT)
.alarmMessageContent(FileUtil.readUtf8String("message/robot/dynamic-thread-pool/wechat-alarm.txt"))
.configMessageContent(FileUtil.readUtf8String("message/robot/dynamic-thread-pool/wechat-config.txt"))
.alarmMessageContent(Singleton.get(weChatAlarmTxtKet, () -> FileUtil.readUtf8String(weChatAlarmTxtKet)))
.configMessageContent(Singleton.get(weChatConfigTxtKet, () -> FileUtil.readUtf8String(weChatConfigTxtKet)))
.build();
return robotMessageActualContent;
}

@ -0,0 +1,30 @@
{
"fields": [
{
"is_short": true,
"text": {
"content": "** 任务执行时间:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 超时时间:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 链路信息:** %s",
"tag": "lark_md"
}
}
],
"tag": "div"
},
{
"tag": "hr"
},

@ -0,0 +1,8 @@
{
"is_short": true,
"text": {
"content": "** 链路信息:** %s",
"tag": "lark_md"
}
}

@ -1,3 +1,206 @@
{
"name": "123"
"msg_type": "interactive",
"card": {
"config": {
"wide_screen_mode": true
},
"header": {
"template": "red",
"title": {
"content": "[🔥警报] %s 动态线程池运行告警(%s",
"tag": "plain_text"
}
},
"elements": [
{
"fields": [
{
"is_short": true,
"text": {
"content": "** 线程池ID** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 应用名称:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 应用实例:** %s",
"tag": "lark_md"
}
}
],
"tag": "div"
},
{
"tag": "hr"
},
{
"fields": [
{
"is_short": true,
"text": {
"content": "** 核心线程数:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 最大线程数:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 当前线程数:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 活跃线程数:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 同存最大线程数:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 线程池任务总量:** %s",
"tag": "lark_md"
}
}
],
"tag": "div"
},
{
"tag": "hr"
},
{
"fields": [
{
"is_short": true,
"text": {
"content": "** 队列类型:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 队列容量:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 队列元素个数:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 队列剩余个数:** %s",
"tag": "lark_md"
}
}
],
"tag": "div"
},
{
"tag": "hr"
},
{
"fields": [
{
"is_short": true,
"text": {
"content": "** 任务执行时间:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 超时时间:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 链路信息:** %s",
"tag": "lark_md"
}
}
],
"tag": "div"
},
{
"tag": "hr"
},
{
"fields": [
{
"is_short": true,
"text": {
"content": "** 拒绝策略:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 拒绝策略执行次数:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** OWNER** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 播报时间: ** %s",
"tag": "lark_md"
}
}
],
"tag": "div"
},
{
"tag": "hr"
},
{
"tag": "note",
"elements": [
{
"tag": "plain_text",
"content": "提示: %s 分钟内此线程池不会重复告警(可配置)"
}
]
}
]
}
}

@ -0,0 +1,156 @@
{
"msg_type": "interactive",
"card": {
"config": {
"wide_screen_mode": true
},
"header": {
"template": "greed",
"title": {
"content": "[通知] %s 动态线程池参数变更",
"tag": "plain_text"
}
},
"elements": [
{
"fields": [
{
"is_short": true,
"text": {
"content": "** 线程池ID** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 应用名称:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 应用实例:** %s",
"tag": "lark_md"
}
}
],
"tag": "div"
},
{
"tag": "hr"
},
{
"fields": [
{
"is_short": true,
"text": {
"content": "** 核心线程数:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 最大线程数:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 核心线程超时:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 线程存活时间:** %s",
"tag": "lark_md"
}
}
],
"tag": "div"
},
{
"tag": "hr"
},
{
"fields": [
{
"is_short": true,
"text": {
"content": "** 队列类型:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 队列容量:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 执行超时时间:** %s",
"tag": "lark_md"
}
}
],
"tag": "div"
},
{
"tag": "hr"
},
{
"fields": [
{
"is_short": true,
"text": {
"content": "** AGO 拒绝策略:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** NOW 拒绝策略:** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** OWNER** %s",
"tag": "lark_md"
}
},
{
"is_short": true,
"text": {
"content": "** 播报时间: ** %s",
"tag": "lark_md"
}
}
],
"tag": "div"
},
{
"tag": "hr"
},
{
"tag": "note",
"elements": [
{
"tag": "plain_text",
"content": "提示:动态线程池配置变更实时通知(无限制)"
}
]
}
]
}
}
Loading…
Cancel
Save