Merge pull request #409 from mabaiwan/develop

hippo4j message notification and alarm abstraction refactoring (#373)
pull/411/head
小马哥 2 years ago committed by GitHub
commit e2a7756981
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -50,6 +50,15 @@
</dependencies> </dependencies>
<build> <build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.txt</include>
<include>**/*.json</include>
</includes>
</resource>
</resources>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>

@ -20,17 +20,14 @@ package cn.hippo4j.message.platform;
import cn.hippo4j.common.toolkit.StringUtil; import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.message.dto.NotifyConfigDTO; import cn.hippo4j.message.dto.NotifyConfigDTO;
import cn.hippo4j.message.enums.NotifyPlatformEnum; import cn.hippo4j.message.enums.NotifyPlatformEnum;
import cn.hippo4j.message.enums.NotifyTypeEnum; import cn.hippo4j.message.platform.base.AbstractRobotSendMessageHandler;
import cn.hippo4j.message.platform.base.RobotMessageActualContent;
import cn.hippo4j.message.platform.base.RobotMessageExecuteDTO;
import cn.hippo4j.message.platform.constant.DingAlarmConstants; import cn.hippo4j.message.platform.constant.DingAlarmConstants;
import cn.hippo4j.message.request.AlarmNotifyRequest; import cn.hutool.core.io.FileUtil;
import cn.hippo4j.message.request.ChangeParameterNotifyRequest;
import cn.hippo4j.message.service.SendMessageHandler;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.dingtalk.api.DefaultDingTalkClient; import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient; import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest; import com.dingtalk.api.request.OapiRobotSendRequest;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.taobao.api.ApiException; import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -40,7 +37,6 @@ import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import static cn.hippo4j.message.platform.constant.DingAlarmConstants.*; import static cn.hippo4j.message.platform.constant.DingAlarmConstants.*;
@ -49,7 +45,7 @@ import static cn.hippo4j.message.platform.constant.DingAlarmConstants.*;
* Send ding notification message. * Send ding notification message.
*/ */
@Slf4j @Slf4j
public class DingSendMessageHandler implements SendMessageHandler<AlarmNotifyRequest, ChangeParameterNotifyRequest> { public class DingSendMessageHandler extends AbstractRobotSendMessageHandler {
@Override @Override
public String getType() { public String getType() {
@ -57,114 +53,21 @@ public class DingSendMessageHandler implements SendMessageHandler<AlarmNotifyReq
} }
@Override @Override
public void sendAlarmMessage(NotifyConfigDTO notifyConfig, AlarmNotifyRequest alarmNotifyRequest) { protected RobotMessageActualContent buildMessageActualContent() {
String[] receives = notifyConfig.getReceives().split(","); RobotMessageActualContent robotMessageActualContent = RobotMessageActualContent.builder()
String afterReceives = Joiner.on(", @").join(receives); .receiveSeparator(", @")
String dingAlarmTxt; .changeSeparator(" -> ")
String dingAlarmTimoutReplaceTxt; .replaceTxt(DING_ALARM_TIMOUT_REPLACE_TXT)
if (Objects.equals(alarmNotifyRequest.getNotifyTypeEnum(), NotifyTypeEnum.TIMEOUT)) { .traceReplaceTxt(DING_ALARM_TIMOUT_TRACE_REPLACE_TXT)
String executeTimeoutTrace = alarmNotifyRequest.getExecuteTimeoutTrace(); .alarmMessageContent(FileUtil.readUtf8String("message/robot/dynamic-thread-pool/ding-alarm.txt"))
if (StringUtil.isNotBlank(executeTimeoutTrace)) { .configMessageContent(FileUtil.readUtf8String("message/robot/dynamic-thread-pool/ding-config.txt"))
String dingAlarmTimoutTraceReplaceTxt = String.format(DING_ALARM_TIMOUT_TRACE_REPLACE_TXT, executeTimeoutTrace); .build();
dingAlarmTimoutReplaceTxt = StrUtil.replace(DING_ALARM_TIMOUT_REPLACE_TXT, DING_ALARM_TIMOUT_TRACE_REPLACE_TXT, dingAlarmTimoutTraceReplaceTxt); return robotMessageActualContent;
} else {
dingAlarmTimoutReplaceTxt = StrUtil.replace(DING_ALARM_TIMOUT_REPLACE_TXT, DING_ALARM_TIMOUT_TRACE_REPLACE_TXT, "");
}
dingAlarmTimoutReplaceTxt = String.format(dingAlarmTimoutReplaceTxt, alarmNotifyRequest.getExecuteTime(), alarmNotifyRequest.getExecuteTimeOut());
dingAlarmTxt = StrUtil.replace(DING_ALARM_TXT, DING_ALARM_TIMOUT_REPLACE_TXT, dingAlarmTimoutReplaceTxt);
} else {
dingAlarmTxt = StrUtil.replace(DING_ALARM_TXT, DING_ALARM_TIMOUT_REPLACE_TXT, "");
}
String[] strings = alarmNotifyRequest.getIdentify().split("_");
String text = String.format(
dingAlarmTxt,
// 环境
alarmNotifyRequest.getActive(),
// 报警类型
alarmNotifyRequest.getNotifyTypeEnum(),
// 线程池ID
alarmNotifyRequest.getThreadPoolId(),
// 应用名称
alarmNotifyRequest.getAppName(),
// Host
strings[0],
// 实例ID
strings[1],
// 核心线程数
alarmNotifyRequest.getCorePoolSize(),
// 最大线程数
alarmNotifyRequest.getMaximumPoolSize(),
// 当前线程数
alarmNotifyRequest.getPoolSize(),
// 活跃线程数
alarmNotifyRequest.getActiveCount(),
// 最大任务数
alarmNotifyRequest.getLargestPoolSize(),
// 线程池任务总量
alarmNotifyRequest.getCompletedTaskCount(),
// 队列类型名称
alarmNotifyRequest.getQueueName(),
// 队列容量
alarmNotifyRequest.getCapacity(),
// 队列元素个数
alarmNotifyRequest.getQueueSize(),
// 队列剩余个数
alarmNotifyRequest.getRemainingCapacity(),
// 拒绝策略名称
alarmNotifyRequest.getRejectedExecutionHandlerName(),
// 拒绝策略次数
alarmNotifyRequest.getRejectCountNum(),
// 告警手机号
afterReceives,
// 报警频率
notifyConfig.getInterval(),
// 当前时间
DateUtil.now());
execute(notifyConfig, DingAlarmConstants.DING_ALARM_TITLE, text, Lists.newArrayList(receives));
} }
@Override @Override
public void sendChangeMessage(NotifyConfigDTO notifyConfig, ChangeParameterNotifyRequest changeParameterNotifyRequest) { protected void execute(RobotMessageExecuteDTO robotMessageExecuteDTO) {
String threadPoolId = changeParameterNotifyRequest.getThreadPoolId(); NotifyConfigDTO notifyConfig = robotMessageExecuteDTO.getNotifyConfig();
String[] receives = notifyConfig.getReceives().split(",");
String afterReceives = Joiner.on(", @").join(receives);
String text = String.format(
DING_NOTICE_TXT,
// 环境
changeParameterNotifyRequest.getActive(),
// 线程池名称
threadPoolId,
// 应用名称
changeParameterNotifyRequest.getAppName(),
// 实例信息
changeParameterNotifyRequest.getIdentify(),
// 核心线程数
changeParameterNotifyRequest.getBeforeCorePoolSize() + " ➲ " + changeParameterNotifyRequest.getNowCorePoolSize(),
// 最大线程数
changeParameterNotifyRequest.getBeforeMaximumPoolSize() + " ➲ " + changeParameterNotifyRequest.getNowMaximumPoolSize(),
// 核心线程超时
changeParameterNotifyRequest.getBeforeAllowsCoreThreadTimeOut() + " ➲ " + changeParameterNotifyRequest.getNowAllowsCoreThreadTimeOut(),
// 线程存活时间
changeParameterNotifyRequest.getBeforeKeepAliveTime() + " ➲ " + changeParameterNotifyRequest.getNowKeepAliveTime(),
// 执行超时时间
changeParameterNotifyRequest.getBeforeExecuteTimeOut() + " ➲ " + changeParameterNotifyRequest.getNowExecuteTimeOut(),
// 阻塞队列
changeParameterNotifyRequest.getBlockingQueueName(),
// 阻塞队列容量
changeParameterNotifyRequest.getBeforeQueueCapacity() + " ➲ " + changeParameterNotifyRequest.getNowQueueCapacity(),
// 拒绝策略
changeParameterNotifyRequest.getBeforeRejectedName(),
changeParameterNotifyRequest.getNowRejectedName(),
// 告警手机号
afterReceives,
// 当前时间
DateUtil.now());
execute(notifyConfig, DingAlarmConstants.DING_NOTICE_TITLE, text, Lists.newArrayList(receives));
}
private void execute(NotifyConfigDTO notifyConfig, String title, String text, List<String> mobiles) {
String serverUrl = DingAlarmConstants.DING_ROBOT_SERVER_URL + notifyConfig.getSecretKey(); String serverUrl = DingAlarmConstants.DING_ROBOT_SERVER_URL + notifyConfig.getSecretKey();
String secret = notifyConfig.getSecret(); String secret = notifyConfig.getSecret();
if (StringUtil.isNotBlank(secret)) { if (StringUtil.isNotBlank(secret)) {
@ -184,10 +87,10 @@ public class DingSendMessageHandler implements SendMessageHandler<AlarmNotifyReq
OapiRobotSendRequest request = new OapiRobotSendRequest(); OapiRobotSendRequest request = new OapiRobotSendRequest();
request.setMsgtype("markdown"); request.setMsgtype("markdown");
OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown(); OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
markdown.setTitle(title); markdown.setTitle(Objects.equals(notifyConfig.getType(), "CONFIG") ? DING_NOTICE_TITLE : DING_ALARM_TITLE);
markdown.setText(text); markdown.setText(robotMessageExecuteDTO.getText());
OapiRobotSendRequest.At at = new OapiRobotSendRequest.At(); OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
at.setAtMobiles(mobiles); at.setAtMobiles(Lists.newArrayList(notifyConfig.getReceives().split(",")));
request.setAt(at); request.setAt(at);
request.setMarkdown(markdown); request.setMarkdown(markdown);
try { try {

@ -18,30 +18,23 @@
package cn.hippo4j.message.platform; package cn.hippo4j.message.platform;
import cn.hippo4j.common.toolkit.JSONUtil; import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.message.dto.NotifyConfigDTO;
import cn.hippo4j.message.enums.NotifyPlatformEnum; import cn.hippo4j.message.enums.NotifyPlatformEnum;
import cn.hippo4j.message.enums.NotifyTypeEnum; import cn.hippo4j.message.platform.base.AbstractRobotSendMessageHandler;
import cn.hippo4j.message.service.SendMessageHandler; import cn.hippo4j.message.platform.base.RobotMessageActualContent;
import cn.hippo4j.message.request.AlarmNotifyRequest; import cn.hippo4j.message.platform.base.RobotMessageExecuteDTO;
import cn.hippo4j.message.request.ChangeParameterNotifyRequest; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpRequest;
import com.google.common.base.Joiner;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.util.Objects;
import static cn.hippo4j.message.platform.constant.WeChatAlarmConstants.*; import static cn.hippo4j.message.platform.constant.WeChatAlarmConstants.*;
/** /**
* WeChat send message handler. * WeChat send message handler.
*/ */
@Slf4j @Slf4j
public class WeChatSendMessageHandler implements SendMessageHandler<AlarmNotifyRequest, ChangeParameterNotifyRequest> { public class WeChatSendMessageHandler extends AbstractRobotSendMessageHandler {
@Override @Override
public String getType() { public String getType() {
@ -49,122 +42,26 @@ public class WeChatSendMessageHandler implements SendMessageHandler<AlarmNotifyR
} }
@Override @Override
public void sendAlarmMessage(NotifyConfigDTO notifyConfig, AlarmNotifyRequest alarmNotifyRequest) { protected RobotMessageActualContent buildMessageActualContent() {
String[] receives = notifyConfig.getReceives().split(","); RobotMessageActualContent robotMessageActualContent = RobotMessageActualContent.builder()
String afterReceives = Joiner.on("><@").join(receives); .receiveSeparator("><@")
String weChatAlarmTxt; .changeSeparator(" ➲ ")
String weChatAlarmTimoutReplaceTxt; .replaceTxt(WE_CHAT_ALARM_TIMOUT_REPLACE_TXT)
if (Objects.equals(alarmNotifyRequest.getNotifyTypeEnum(), NotifyTypeEnum.TIMEOUT)) { .traceReplaceTxt(WE_CHAT_ALARM_TIMOUT_TRACE_REPLACE_TXT)
String executeTimeoutTrace = alarmNotifyRequest.getExecuteTimeoutTrace(); .alarmMessageContent(FileUtil.readUtf8String("message/robot/dynamic-thread-pool/wechat-alarm.txt"))
if (StringUtil.isNotBlank(executeTimeoutTrace)) { .configMessageContent(FileUtil.readUtf8String("message/robot/dynamic-thread-pool/wechat-config.txt"))
String weChatAlarmTimoutTraceReplaceTxt = String.format(WE_CHAT_ALARM_TIMOUT_TRACE_REPLACE_TXT, executeTimeoutTrace); .build();
weChatAlarmTimoutReplaceTxt = StrUtil.replace(WE_CHAT_ALARM_TIMOUT_REPLACE_TXT, WE_CHAT_ALARM_TIMOUT_TRACE_REPLACE_TXT, weChatAlarmTimoutTraceReplaceTxt); return robotMessageActualContent;
} else {
weChatAlarmTimoutReplaceTxt = StrUtil.replace(WE_CHAT_ALARM_TIMOUT_REPLACE_TXT, WE_CHAT_ALARM_TIMOUT_TRACE_REPLACE_TXT, "");
}
weChatAlarmTimoutReplaceTxt = String.format(weChatAlarmTimoutReplaceTxt, alarmNotifyRequest.getExecuteTime(), alarmNotifyRequest.getExecuteTimeOut());
weChatAlarmTxt = StrUtil.replace(WE_CHAT_ALARM_TXT, WE_CHAT_ALARM_TIMOUT_REPLACE_TXT, weChatAlarmTimoutReplaceTxt);
} else {
weChatAlarmTxt = StrUtil.replace(WE_CHAT_ALARM_TXT, WE_CHAT_ALARM_TIMOUT_REPLACE_TXT, "");
}
String text = String.format(
weChatAlarmTxt,
// 环境
alarmNotifyRequest.getActive(),
// 报警类型
alarmNotifyRequest.getNotifyTypeEnum(),
// 线程池ID
alarmNotifyRequest.getThreadPoolId(),
// 应用名称
alarmNotifyRequest.getAppName(),
// 实例信息
alarmNotifyRequest.getIdentify(),
// 核心线程数
alarmNotifyRequest.getCorePoolSize(),
// 最大线程数
alarmNotifyRequest.getMaximumPoolSize(),
// 当前线程数
alarmNotifyRequest.getPoolSize(),
// 活跃线程数
alarmNotifyRequest.getActiveCount(),
// 最大任务数
alarmNotifyRequest.getLargestPoolSize(),
// 线程池任务总量
alarmNotifyRequest.getCompletedTaskCount(),
// 队列类型名称
alarmNotifyRequest.getQueueName(),
// 队列容量
alarmNotifyRequest.getCapacity(),
// 队列元素个数
alarmNotifyRequest.getQueueSize(),
// 队列剩余个数
alarmNotifyRequest.getRemainingCapacity(),
// 拒绝策略名称
alarmNotifyRequest.getRejectedExecutionHandlerName(),
// 拒绝策略次数
alarmNotifyRequest.getRejectCountNum(),
// 告警手机号
afterReceives,
// 报警频率
notifyConfig.getInterval(),
// 当前时间
DateUtil.now());
execute(notifyConfig.getSecretKey(), text);
} }
@Override @Override
public void sendChangeMessage(NotifyConfigDTO notifyConfig, ChangeParameterNotifyRequest changeParameterNotifyRequest) { protected void execute(RobotMessageExecuteDTO robotMessageExecuteDTO) {
String threadPoolId = changeParameterNotifyRequest.getThreadPoolId(); String serverUrl = WE_CHAT_SERVER_URL + robotMessageExecuteDTO.getNotifyConfig().getSecretKey();
String[] receives = notifyConfig.getReceives().split(",");
String afterReceives = Joiner.on("><@").join(receives);
String text = String.format(
WE_CHAT_NOTICE_TXT,
// 环境
changeParameterNotifyRequest.getActive(),
// 线程池名称
threadPoolId,
// 应用名称
changeParameterNotifyRequest.getAppName(),
// 实例信息
changeParameterNotifyRequest.getIdentify(),
// 核心线程数
changeParameterNotifyRequest.getBeforeCorePoolSize() + " ➲ " + changeParameterNotifyRequest.getNowCorePoolSize(),
// 最大线程数
changeParameterNotifyRequest.getBeforeMaximumPoolSize() + " ➲ " + changeParameterNotifyRequest.getNowMaximumPoolSize(),
// 核心线程超时
changeParameterNotifyRequest.getBeforeAllowsCoreThreadTimeOut() + " ➲ " + changeParameterNotifyRequest.getNowAllowsCoreThreadTimeOut(),
// 线程存活时间
changeParameterNotifyRequest.getBeforeKeepAliveTime() + " ➲ " + changeParameterNotifyRequest.getNowKeepAliveTime(),
// 执行超时时间
changeParameterNotifyRequest.getBeforeExecuteTimeOut() + " ➲ " + changeParameterNotifyRequest.getNowExecuteTimeOut(),
// 阻塞队列
changeParameterNotifyRequest.getBlockingQueueName(),
// 阻塞队列容量
changeParameterNotifyRequest.getBeforeQueueCapacity() + " ➲ " + changeParameterNotifyRequest.getNowQueueCapacity(),
// 拒绝策略
changeParameterNotifyRequest.getBeforeRejectedName(),
changeParameterNotifyRequest.getNowRejectedName(),
// 告警手机号
afterReceives,
// 当前时间
DateUtil.now());
execute(notifyConfig.getSecretKey(), text);
}
/**
* Execute.
*
* @param secretKey
* @param text
*/
private void execute(String secretKey, String text) {
String serverUrl = WE_CHAT_SERVER_URL + secretKey;
try { try {
WeChatReqDTO weChatReq = new WeChatReqDTO(); WeChatReqDTO weChatReq = new WeChatReqDTO();
weChatReq.setMsgtype("markdown"); weChatReq.setMsgtype("markdown");
Markdown markdown = new Markdown(); Markdown markdown = new Markdown();
markdown.setContent(text); markdown.setContent(robotMessageExecuteDTO.getText());
weChatReq.setMarkdown(markdown); weChatReq.setMarkdown(markdown);
HttpRequest.post(serverUrl).body(JSONUtil.toJSONString(weChatReq)).execute(); HttpRequest.post(serverUrl).body(JSONUtil.toJSONString(weChatReq)).execute();
} catch (Exception ex) { } catch (Exception ex) {

@ -0,0 +1,164 @@
/*
* 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.message.platform.base;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.message.dto.NotifyConfigDTO;
import cn.hippo4j.message.enums.NotifyTypeEnum;
import cn.hippo4j.message.request.AlarmNotifyRequest;
import cn.hippo4j.message.request.ChangeParameterNotifyRequest;
import cn.hippo4j.message.service.SendMessageHandler;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.base.Joiner;
import java.util.Objects;
/**
* Abstract robot send message handler.
*/
public abstract class AbstractRobotSendMessageHandler implements SendMessageHandler<AlarmNotifyRequest, ChangeParameterNotifyRequest> {
/**
* Build message actual content.
*
* @return
*/
protected abstract RobotMessageActualContent buildMessageActualContent();
/**
* Execute.
*
* @param robotMessageExecuteDTO
*/
protected abstract void execute(RobotMessageExecuteDTO robotMessageExecuteDTO);
/**
* Send alarm message.
*
* @param notifyConfig
* @param alarmNotifyRequest
*/
public void sendAlarmMessage(NotifyConfigDTO notifyConfig, AlarmNotifyRequest alarmNotifyRequest) {
RobotMessageActualContent robotMessageActualContent = buildMessageActualContent();
String replaceTxt = robotMessageActualContent.getReplaceTxt();
String traceReplaceTxt = robotMessageActualContent.getTraceReplaceTxt();
String alarmContentTxt = robotMessageActualContent.getAlarmMessageContent();
String alarmTimoutReplaceTxt;
if (Objects.equals(alarmNotifyRequest.getNotifyTypeEnum(), NotifyTypeEnum.TIMEOUT)) {
String executeTimeoutTrace = alarmNotifyRequest.getExecuteTimeoutTrace();
if (StringUtil.isNotBlank(executeTimeoutTrace)) {
String alarmTimoutTraceReplaceTxt = String.format(traceReplaceTxt, executeTimeoutTrace);
alarmTimoutReplaceTxt = StrUtil.replace(replaceTxt, traceReplaceTxt, alarmTimoutTraceReplaceTxt);
} else {
alarmTimoutReplaceTxt = StrUtil.replace(replaceTxt, traceReplaceTxt, "");
}
replaceTxt = String.format(alarmTimoutReplaceTxt, alarmNotifyRequest.getExecuteTime(), alarmNotifyRequest.getExecuteTimeOut());
} else {
replaceTxt = "";
}
alarmContentTxt = StrUtil.replace(alarmContentTxt, "${timout-content}", replaceTxt);
String text = String.format(
alarmContentTxt,
// 环境
alarmNotifyRequest.getActive(),
// 报警类型
alarmNotifyRequest.getNotifyTypeEnum(),
// 线程池ID
alarmNotifyRequest.getThreadPoolId(),
// 应用名称
alarmNotifyRequest.getAppName(),
// 实例信息
alarmNotifyRequest.getIdentify(),
// 核心线程数
alarmNotifyRequest.getCorePoolSize(),
// 最大线程数
alarmNotifyRequest.getMaximumPoolSize(),
// 当前线程数
alarmNotifyRequest.getPoolSize(),
// 活跃线程数
alarmNotifyRequest.getActiveCount(),
// 最大任务数
alarmNotifyRequest.getLargestPoolSize(),
// 线程池任务总量
alarmNotifyRequest.getCompletedTaskCount(),
// 队列类型名称
alarmNotifyRequest.getQueueName(),
// 队列容量
alarmNotifyRequest.getCapacity(),
// 队列元素个数
alarmNotifyRequest.getQueueSize(),
// 队列剩余个数
alarmNotifyRequest.getRemainingCapacity(),
// 拒绝策略名称
alarmNotifyRequest.getRejectedExecutionHandlerName(),
// 拒绝策略次数
alarmNotifyRequest.getRejectCountNum(),
// 告警手机号
Joiner.on(robotMessageActualContent.getReceiveSeparator()).join(notifyConfig.getReceives().split(",")),
// 报警频率
notifyConfig.getInterval(),
// 当前时间
DateUtil.now());
execute(RobotMessageExecuteDTO.builder().text(text).notifyConfig(notifyConfig).build());
}
/**
* Send change message.
*
* @param notifyConfig
* @param changeParameterNotifyRequest
*/
public void sendChangeMessage(NotifyConfigDTO notifyConfig, ChangeParameterNotifyRequest changeParameterNotifyRequest) {
RobotMessageActualContent robotMessageActualContent = buildMessageActualContent();
String threadPoolId = changeParameterNotifyRequest.getThreadPoolId();
String changeSeparator = robotMessageActualContent.getChangeSeparator();
String text = String.format(
robotMessageActualContent.getConfigMessageContent(),
// 环境
changeParameterNotifyRequest.getActive(),
// 线程池名称
threadPoolId,
// 应用名称
changeParameterNotifyRequest.getAppName(),
// 实例信息
changeParameterNotifyRequest.getIdentify(),
// 核心线程数
changeParameterNotifyRequest.getBeforeCorePoolSize() + changeSeparator + changeParameterNotifyRequest.getNowCorePoolSize(),
// 最大线程数
changeParameterNotifyRequest.getBeforeMaximumPoolSize() + changeSeparator + changeParameterNotifyRequest.getNowMaximumPoolSize(),
// 核心线程超时
changeParameterNotifyRequest.getBeforeAllowsCoreThreadTimeOut() + changeSeparator + changeParameterNotifyRequest.getNowAllowsCoreThreadTimeOut(),
// 线程存活时间
changeParameterNotifyRequest.getBeforeKeepAliveTime() + changeSeparator + changeParameterNotifyRequest.getNowKeepAliveTime(),
// 执行超时时间
changeParameterNotifyRequest.getBeforeExecuteTimeOut() + changeSeparator + changeParameterNotifyRequest.getNowExecuteTimeOut(),
// 阻塞队列
changeParameterNotifyRequest.getBlockingQueueName(),
// 阻塞队列容量
changeParameterNotifyRequest.getBeforeQueueCapacity() + changeSeparator + changeParameterNotifyRequest.getNowQueueCapacity(),
// 拒绝策略
changeParameterNotifyRequest.getBeforeRejectedName(),
changeParameterNotifyRequest.getNowRejectedName(),
// 告警手机号
Joiner.on(robotMessageActualContent.getReceiveSeparator()).join(notifyConfig.getReceives().split(",")),
// 当前时间
DateUtil.now());
execute(RobotMessageExecuteDTO.builder().text(text).notifyConfig(notifyConfig).build());
}
}

@ -0,0 +1,63 @@
/*
* 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.message.platform.base;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Robot message actual content.
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RobotMessageActualContent {
/**
* Alarm message content
*/
private String alarmMessageContent;
/**
* Config message content
*/
private String configMessageContent;
/**
* Replace txt
*/
private String replaceTxt;
/**
* Trace replace txt
*/
private String traceReplaceTxt;
/**
* Receive separator
*/
private String receiveSeparator;
/**
* Change separator
*/
private String changeSeparator;
}

@ -0,0 +1,44 @@
/*
* 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.message.platform.base;
import cn.hippo4j.message.dto.NotifyConfigDTO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Robot message execute DTO.
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RobotMessageExecuteDTO {
/**
* Text
*/
private String text;
/**
* Notify config
*/
private NotifyConfigDTO notifyConfig;
}

@ -40,14 +40,14 @@ public class DingAlarmConstants {
/** /**
* Trace * Trace
*/ */
public static final String DING_ALARM_TIMOUT_TRACE_REPLACE_TXT = "<font color=#708090 size=2>链路信息:%s</font> \n\n"; public static final String DING_ALARM_TIMOUT_TRACE_REPLACE_TXT = "<font color=#708090 size=2>链路信息:%s</font> \n\n ";
/** /**
* *
*/ */
public static final String DING_ALARM_TIMOUT_REPLACE_TXT = public static final String DING_ALARM_TIMOUT_REPLACE_TXT =
"<font color=#708090 size=2>任务执行时间:%d / ms </font> \n\n" + "<font color=#708090 size=2>任务执行时间:%d / ms </font> \n\n " +
"<font color=#708090 size=2>超时时间:%d / ms</font> \n\n" + "<font color=#708090 size=2>超时时间:%d / ms</font> \n\n " +
DING_ALARM_TIMOUT_TRACE_REPLACE_TXT + DING_ALARM_TIMOUT_TRACE_REPLACE_TXT +
" --- \n\n "; " --- \n\n ";
@ -60,7 +60,6 @@ public class DingAlarmConstants {
"<font color=#708090 size=2>线程池ID%s</font> \n\n " + "<font color=#708090 size=2>线程池ID%s</font> \n\n " +
"<font color=#708090 size=2>应用名称:%s</font> \n\n " + "<font color=#708090 size=2>应用名称:%s</font> \n\n " +
"<font color=#778899 size=2>应用实例:%s</font> \n\n " + "<font color=#778899 size=2>应用实例:%s</font> \n\n " +
"<font color=#778899 size=2>实例标识:%s</font> \n\n " +
" --- \n\n " + " --- \n\n " +
"<font color=#708090 size=2>核心线程数:%d</font> \n\n " + "<font color=#708090 size=2>核心线程数:%d</font> \n\n " +
"<font color=#708090 size=2>最大线程数:%d</font> \n\n " + "<font color=#708090 size=2>最大线程数:%d</font> \n\n " +

@ -30,59 +30,13 @@ public class WeChatAlarmConstants {
/** /**
* Trace * Trace
*/ */
public static final String WE_CHAT_ALARM_TIMOUT_TRACE_REPLACE_TXT = "> 链路信息:%s \n"; public static final String WE_CHAT_ALARM_TIMOUT_TRACE_REPLACE_TXT = "\n> 链路信息:%s ";
/** /**
* *
*/ */
public static final String WE_CHAT_ALARM_TIMOUT_REPLACE_TXT = public static final String WE_CHAT_ALARM_TIMOUT_REPLACE_TXT =
"> 任务执行时间:%s / ms \n" + "\n> 任务执行时间:%s / ms \n" +
"> 超时时间:%s / ms \n" + "> 超时时间:%s / ms " +
WE_CHAT_ALARM_TIMOUT_TRACE_REPLACE_TXT; WE_CHAT_ALARM_TIMOUT_TRACE_REPLACE_TXT;
/**
* 线
*/
public static final String WE_CHAT_ALARM_TXT =
"### <font color='#FF0000'>[警报] </font>%s - 动态线程池运行告警(%s \n" +
"> 线程池ID<font color=\"warning\">%s</font> \n" +
"> 应用名称:<font color=\"warning\">%s</font> \n" +
"> 应用实例:%s \n" +
"> 核心线程数:%s \n" +
"> 最大线程数:%s \n" +
"> 当前线程数:%s \n" +
"> 活跃线程数:%s \n" +
"> 同存最大线程数:%s \n" +
"> 线程池任务总量:%s \n" +
"> 队列类型:%s \n" +
"> 队列容量:%s \n" +
"> 队列元素个数:%s \n" +
"> 队列剩余个数:%s \n" +
"> 拒绝策略:%s \n" +
"> 拒绝策略执行次数:<font color='#FF0000'>%s</font> \n" +
WE_CHAT_ALARM_TIMOUT_REPLACE_TXT +
"> OWNER<@%s> \n" +
"> 提示:%d 分钟内此线程池不会重复告警(可配置) \n\n" +
"**播报时间:%s**";
/**
* 线
*/
public static final String WE_CHAT_NOTICE_TXT =
"### <font color=\"info\">[通知] </font>%s - 动态线程池参数变更 \n" +
"> 线程池ID<font color=\"warning\">%s</font> \n" +
"> 应用名称:<font color=\"warning\">%s</font> \n" +
"> 应用实例:%s \n" +
"> 核心线程数:%s \n" +
"> 最大线程数:%s \n" +
"> 核心线程超时:%s \n" +
"> 线程存活时间:%s \n" +
"> 执行超时时间:%s \n" +
"> 队列类型:%s \n" +
"> 队列容量:%s \n" +
"> AGO 拒绝策略:%s \n" +
"> NOW 拒绝策略:%s \n" +
"> OWNER<@%s> \n" +
"> 提示:动态线程池配置变更实时通知(无限制) \n\n" +
"**播报时间:%s**";
} }

@ -0,0 +1,49 @@
**<font color=#FF0000>[警报] </font>%s - 动态线程池运行告警(%s**
---
<font color=#708090 size=2>线程池ID%s</font>
<font color=#708090 size=2>应用名称:%s</font>
<font color=#778899 size=2>应用实例:%s</font>
---
<font color=#708090 size=2>核心线程数:%d</font>
<font color=#708090 size=2>最大线程数:%d</font>
<font color=#708090 size=2>当前线程数:%d</font>
<font color=#708090 size=2>活跃线程数:%d</font>
<font color=#708090 size=2>同存最大线程数:%d</font>
<font color=#708090 size=2>线程池任务总量:%d</font>
---
<font color=#708090 size=2>队列类型:%s</font>
<font color=#708090 size=2>队列容量:%d</font>
<font color=#708090 size=2>队列元素个数:%d</font>
<font color=#708090 size=2>队列剩余个数:%d</font>
---
${timout-content}
<font color=#708090 size=2>拒绝策略:%s</font>
<font color=#708090 size=2>拒绝策略执行次数:</font><font color=#FF0000 size=2>%d</font>
<font color=#708090 size=2>OWNER@%s</font>
<font color=#708090 size=2>提示:%d 分钟内此线程池不会重复告警(可配置)</font>
---
**播报时间:%s**

@ -0,0 +1,41 @@
**<font color=#2a9d8f>[通知] </font>%s - 动态线程池参数变更**
---
<font color=#708090 size=2>线程池ID%s</font>
<font color=#708090 size=2>应用名称:%s</font>
<font color=#778899 size=2>应用实例:%s</font>
---
<font color=#708090 size=2>核心线程数:%s</font>
<font color=#708090 size=2>最大线程数:%s</font>
<font color=#708090 size=2>核心线程超时:%s</font>
<font color=#708090 size=2>线程存活时间:%s</font>
<font color=#708090 size=2>执行超时时间:%s</font>
---
<font color=#708090 size=2>队列类型:%s</font>
<font color=#708090 size=2>队列容量:%s</font>
<font color=#708090 size=2>AGO 拒绝策略:%s</font>
<font color=#708090 size=2>NOW 拒绝策略:%s</font>
---
<font color=#708090 size=2>提示:动态线程池配置变更实时通知(无限制)</font>
<font color=#708090 size=2>OWNER@%s</font>
---
**播报时间:%s**

@ -0,0 +1,21 @@
### <font color='#FF0000'>[警报] </font>%s - 动态线程池运行告警(%s
> 线程池ID<font color='warning'>%s</font>
> 应用名称:<font color='warning'>%s</font>
> 应用实例:%s
> 核心线程数:%s
> 最大线程数:%s
> 当前线程数:%s
> 活跃线程数:%s
> 同存最大线程数:%s
> 线程池任务总量:%s
> 队列类型:%s
> 队列容量:%s
> 队列元素个数:%s
> 队列剩余个数:%s
> 拒绝策略:%s
> 拒绝策略执行次数:<font color='#FF0000'>%s</font> ${timout-content}
> OWNER<@%s>
> 提示:%d 分钟内此线程池不会重复告警(可配置)
**播报时间:%s**

@ -0,0 +1,17 @@
### <font color='info'>[通知] </font>%s - 动态线程池参数变更
> 线程池ID<font color='warning'>%s</font>
> 应用名称:<font color='warning'>%s</font>
> 应用实例:%s
> 核心线程数:%s
> 最大线程数:%s
> 核心线程超时:%s
> 线程存活时间:%s
> 执行超时时间:%s
> 队列类型:%s
> 队列容量:%s
> AGO 拒绝策略:%s
> NOW 拒绝策略:%s
> OWNER<@%s>
> 提示:动态线程池配置变更实时通知(无限制)
**播报时间:%s**
Loading…
Cancel
Save