开发企业微信消息通知、报警推送功能.

pull/12/head
chen.ma 3 years ago
parent 72d10b65df
commit c6756d7ddc

@ -17,5 +17,10 @@ public enum NotifyPlatformEnum {
*
*/
LARK,
;
/**
*
*/
WECHAT
}

@ -0,0 +1,60 @@
package cn.hippo4j.starter.alarm.wechat;
/**
* Ding alarm constants.
*
* @author chen.ma
* @date 2021/11/26 20:03
*/
public class WeChatAlarmConstants {
/**
* Url
*/
public static final String WE_CHAT_SERVER_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=";
/**
* 线
*/
public static final String WE_CHAT_ALARM_TXT =
"### <font color='#FF0000'>[警报] </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" +
"> 队列类型:%s \n" +
"> 队列容量:%s \n" +
"> 队列元素个数:%s \n" +
"> 队列剩余个数:%s \n" +
"> 拒绝策略:%s \n" +
"> 拒绝策略执行次数:%s \n" +
"> 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 / SECONDS \n" +
"> 队列类型:%s \n" +
"> 队列容量:%s \n" +
"> AGO 拒绝策略:%s \n" +
"> NOW 拒绝策略:%s \n" +
"> OWNER**@%s** \n" +
"> 提示:动态线程池配置变更实时通知(无限制) \n\n" +
"**播报时间:%s**";
}

@ -0,0 +1,36 @@
package cn.hippo4j.starter.alarm.wechat;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* WeChat req dto.
*
* @author chen.ma
* @date 2021/11/26 20:15
*/
@Data
@Accessors(chain = true)
public class WeChatReqDTO {
/**
* msgType
*/
private String msgtype;
/**
* markdown
*/
private Markdown markdown;
@Data
public static class Markdown {
/**
* content
*/
private String content;
}
}

@ -0,0 +1,162 @@
package cn.hippo4j.starter.alarm.wechat;
import cn.hippo4j.common.model.InstanceInfo;
import cn.hippo4j.common.model.PoolParameterInfo;
import cn.hippo4j.starter.alarm.NotifyDTO;
import cn.hippo4j.starter.alarm.NotifyPlatformEnum;
import cn.hippo4j.starter.alarm.SendMessageHandler;
import cn.hippo4j.starter.core.DynamicThreadPoolExecutor;
import cn.hippo4j.starter.core.GlobalThreadPoolManage;
import cn.hippo4j.starter.toolkit.thread.QueueTypeEnum;
import cn.hippo4j.starter.toolkit.thread.RejectedTypeEnum;
import cn.hippo4j.starter.wrapper.DynamicThreadPoolWrapper;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Joiner;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import static cn.hippo4j.starter.alarm.wechat.WeChatAlarmConstants.*;
/**
* WeChat send message handler.
*
* @author chen.ma
* @date 2021/11/26 20:06
*/
@Slf4j
@AllArgsConstructor
public class WeChatSendMessageHandler implements SendMessageHandler {
private final String active;
private final InstanceInfo instanceInfo;
@Override
public String getType() {
return NotifyPlatformEnum.WECHAT.name();
}
@Override
public void sendAlarmMessage(NotifyDTO notifyConfig, DynamicThreadPoolExecutor pool) {
List<String> receives = StrUtil.split(notifyConfig.getReceives(), ',');
String afterReceives = Joiner.on(", @").join(receives);
BlockingQueue<Runnable> queue = pool.getQueue();
String text = String.format(
WE_CHAT_ALARM_TXT,
// 环境
active.toUpperCase(),
// 线程池ID
pool.getThreadPoolId(),
// 应用名称
instanceInfo.getAppName(),
// 实例信息
instanceInfo.getIdentify(),
// 报警类型
notifyConfig.getTypeEnum(),
// 核心线程数
pool.getCorePoolSize(),
// 最大线程数
pool.getMaximumPoolSize(),
// 当前线程数
pool.getPoolSize(),
// 活跃线程数
pool.getActiveCount(),
// 最大任务数
pool.getLargestPoolSize(),
// 线程池任务总量
pool.getCompletedTaskCount(),
// 队列类型名称
queue.getClass().getSimpleName(),
// 队列容量
queue.size() + queue.remainingCapacity(),
// 队列元素个数
queue.size(),
// 队列剩余个数
queue.remainingCapacity(),
// 拒绝策略名称
pool.getRejectedExecutionHandler().getClass().getSimpleName(),
// 拒绝策略次数
pool.getRejectCount(),
// 告警手机号
afterReceives,
// 报警频率
notifyConfig.getInterval(),
// 当前时间
DateUtil.now()
);
execute(notifyConfig, text);
}
@Override
public void sendChangeMessage(NotifyDTO notifyConfig, PoolParameterInfo parameter) {
String threadPoolId = parameter.getTpId();
DynamicThreadPoolWrapper poolWrap = GlobalThreadPoolManage.getExecutorService(threadPoolId);
if (poolWrap == null) {
log.warn("Thread pool is empty when sending change notification, threadPoolId :: {}", threadPoolId);
return;
}
List<String> receives = StrUtil.split(notifyConfig.getReceives(), ',');
String afterReceives = Joiner.on(", @").join(receives);
ThreadPoolExecutor customPool = poolWrap.getExecutor();
String text = String.format(
WE_CHAT_NOTICE_TXT,
// 环境
active.toUpperCase(),
// 线程池名称
threadPoolId,
// 应用名称
instanceInfo.getAppName(),
// 实例信息
instanceInfo.getIdentify(),
// 核心线程数
customPool.getCorePoolSize() + " ➲ " + parameter.getCoreSize(),
// 最大线程数
customPool.getMaximumPoolSize() + " ➲ " + parameter.getMaxSize(),
// 线程存活时间
customPool.getKeepAliveTime(TimeUnit.SECONDS) + " ➲ " + parameter.getKeepAliveTime(),
// 阻塞队列
QueueTypeEnum.getBlockingQueueNameByType(parameter.getQueueType()),
// 阻塞队列容量
(customPool.getQueue().size() + customPool.getQueue().remainingCapacity()) + " ➲ " + parameter.getCapacity(),
// 拒绝策略
customPool.getRejectedExecutionHandler().getClass().getSimpleName(),
RejectedTypeEnum.getRejectedNameByType(parameter.getRejectedType()),
// 告警手机号
afterReceives,
// 当前时间
DateUtil.now()
);
execute(notifyConfig, text);
}
private void execute(NotifyDTO notifyConfig, String text) {
String serverUrl = WE_CHAT_SERVER_URL + notifyConfig.getSecretKey();
try {
WeChatReqDTO weChatReq = new WeChatReqDTO();
weChatReq.setMsgtype("markdown");
WeChatReqDTO.Markdown markdown = new WeChatReqDTO.Markdown();
markdown.setContent(text);
weChatReq.setMarkdown(markdown);
HttpRequest.post(serverUrl).body(JSON.toJSONString(weChatReq)).execute();
} catch (Exception ex) {
log.error("WeChat failed to send message", ex);
}
}
}

@ -2,7 +2,9 @@ package cn.hippo4j.starter.config;
import cn.hippo4j.common.model.InstanceInfo;
import cn.hippo4j.starter.alarm.*;
import cn.hippo4j.starter.alarm.ding.DingSendMessageHandler;
import cn.hippo4j.starter.alarm.lark.LarkSendMessageHandler;
import cn.hippo4j.starter.alarm.wechat.WeChatSendMessageHandler;
import cn.hippo4j.starter.remote.HttpAgent;
import lombok.AllArgsConstructor;
import org.apache.logging.log4j.util.Strings;
@ -45,6 +47,12 @@ public class MessageAlarmConfig {
return new LarkSendMessageHandler(active, instanceInfo);
}
@Bean
public SendMessageHandler weChatSendMessageHandler() {
String active = environment.getProperty("spring.profiles.active", Strings.EMPTY);
return new WeChatSendMessageHandler(active, instanceInfo);
}
@Bean
public AlarmControlHandler alarmControlHandler() {
return new AlarmControlHandler();

Loading…
Cancel
Save