Browse Source

Merge remote-tracking branch 'origin/dev' into dev

dev_shibei_match
wangchao 5 years ago
parent
commit
1e79e5e8a1
  1. 37
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/DingTalkTextMsg.java
  2. 151
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/filter/LogMsgSendFilter.java
  3. 185
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/DingdingMsgSender.java
  4. 12
      epmet-module/data-statistical/data-statistical-server/src/main/java/com/epmet/controller/DemoController.java
  5. 2
      epmet-module/data-statistical/data-statistical-server/src/main/resources/logback-spring.xml

37
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/dto/form/DingTalkTextMsg.java

@ -1,25 +1,32 @@
package com.epmet.commons.tools.dto.form;
import com.alibaba.fastjson.JSON;
import lombok.Data;
import org.springframework.util.CollectionUtils;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* desc: 钉钉文本消息参数 实体类
* date: 2019/2/20 11:00
/**
* desc: 钉钉文本消息参数 实体类
*
* @date: 2020/6/29 9:06
* @author: jianjun liu
* email:liujianjun@yunzongnet.com
* email:liujianjun@git.elinkit.com.cn
*/
public class DingTalkTextMsg {
public class DingTalkTextMsg implements Serializable {
private static final long serialVersionUID = -3611771312188821915L;
/**
* 消息接收者
*/
private String receiver;
private String webHook;
/**
* 密钥
*/
private String secret;
/**
* 发送内容
*/
@ -35,12 +42,12 @@ public class DingTalkTextMsg {
*/
private boolean isAtAll;
public String getReceiver() {
return receiver;
public String getWebHook() {
return webHook;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
public void setWebHook(String webHook) {
this.webHook = webHook;
}
public String getContent() {
@ -67,6 +74,14 @@ public class DingTalkTextMsg {
isAtAll = atAll;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public String getMsgContent() {
Map<String, Object> items = new HashMap<>();
items.put("msgtype", "text");

151
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/filter/LogMsgSendFilter.java

@ -6,8 +6,9 @@ import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.StackTraceElementProxy;
import ch.qos.logback.core.spi.FilterReply;
import com.epmet.commons.tools.utils.HttpClientManager;
import com.epmet.commons.tools.utils.Result;
import com.epmet.commons.tools.dto.form.DingTalkTextMsg;
import com.epmet.commons.tools.utils.DingdingMsgSender;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -20,78 +21,96 @@ import java.text.SimpleDateFormat;
* @author: jianjun liu
*/
public class LogMsgSendFilter extends LevelFilter {
private static final Logger logger = LoggerFactory.getLogger(LogMsgSendFilter.class);
@Override
public FilterReply decide(ILoggingEvent event) {
//如果日志级别等于设置的日志级别 则发送消息
if (event.getLevel().isGreaterOrEqual(Level.ERROR)) {
try {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("【日志告警】\n");
private static final Logger logger = LoggerFactory.getLogger(LogMsgSendFilter.class);
private DingdingMsgSender msgSender = new DingdingMsgSender();
private String webHook;
private String secret;
stringBuilder.append("\n");
@Override
public FilterReply decide(ILoggingEvent event) {
//如果日志级别等于设置的日志级别 则发送消息
if (event.getLevel().isGreaterOrEqual(Level.ERROR)) {
try {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("【日志告警】\n");
stringBuilder.append("告警级别:" + event.getLevel());
stringBuilder.append("\n");
stringBuilder.append("故障时间:" + formatLongTime2Str(event.getTimeStamp()));
stringBuilder.append("\n");
stringBuilder.append("TraceId:" + Thread.currentThread().getName());
stringBuilder.append("\n");
stringBuilder.append("告警信息:" + event.getFormattedMessage());
stringBuilder.append("\n");
stringBuilder.append("\n");
IThrowableProxy throwableProxy = event.getThrowableProxy();
//异常信息处理 暂时处理一级的5行数据
apendStackInfo(stringBuilder, throwableProxy);
stringBuilder.append("告警级别:" + event.getLevel());
stringBuilder.append("\n");
stringBuilder.append("故障时间:" + formatLongTime2Str(event.getTimeStamp()));
stringBuilder.append("\n");
stringBuilder.append("TraceId:" + Thread.currentThread().getName());
stringBuilder.append("\n");
stringBuilder.append("告警信息:" + event.getFormattedMessage());
stringBuilder.append("\n");
Result<String> flag = HttpClientManager.getInstance().sendAlarmMsg(stringBuilder.toString());
if (!flag.success()) {
logger.warn("msgSender.sendMsg fail,param:{}", stringBuilder.toString());
}
} catch (Exception e) {
logger.warn("decide exception", e);
}
}
//交给其他filter继续向下处理
return super.decide(event);
}
IThrowableProxy throwableProxy = event.getThrowableProxy();
//异常信息处理 暂时处理一级的5行数据
apendStackInfo(stringBuilder, throwableProxy);
DingTalkTextMsg msg = new DingTalkTextMsg();
msg.setContent(stringBuilder.toString());
if (StringUtils.isNotBlank(webHook)) {
msg.setWebHook(webHook);
}
if (StringUtils.isNotBlank(secret)) {
msg.setSecret(secret);
}
boolean flag = msgSender.sendMsgAsync(msg);
if (!flag) {
logger.warn("msgSender.sendMsg fail,param:{}", stringBuilder.toString());
}
} catch (Exception e) {
logger.warn("decide exception", e);
}
}
//交给其他filter继续向下处理
return super.decide(event);
}
private void apendStackInfo(StringBuilder stringBuilder, IThrowableProxy throwableProxy) {
int defaultRowLine = 5;
if (throwableProxy != null) {
stringBuilder.append("异常信息:")
.append(throwableProxy.getClassName())
.append(" : ")
.append(throwableProxy.getMessage())
.append("\n");
private void apendStackInfo(StringBuilder stringBuilder, IThrowableProxy throwableProxy) {
int defaultRowLine = 5;
if (throwableProxy != null) {
stringBuilder.append("异常信息:")
.append(throwableProxy.getClassName())
.append(" : ")
.append(throwableProxy.getMessage())
.append("\n");
StackTraceElementProxy[] stackTraceElementProxyArray = throwableProxy.getStackTraceElementProxyArray();
StackTraceElementProxy stackTraceElementProxy = null;
StackTraceElementProxy[] stackTraceElementProxyArray = throwableProxy.getStackTraceElementProxyArray();
StackTraceElementProxy stackTraceElementProxy = null;
if (stackTraceElementProxyArray.length < defaultRowLine) {
defaultRowLine = stackTraceElementProxyArray.length;
}
for (int i = 0; i < defaultRowLine; i++) {
stackTraceElementProxy = stackTraceElementProxyArray[i];
StackTraceElement stackTraceElement = stackTraceElementProxy.getStackTraceElement();
stringBuilder.append("\t\tat ");
stringBuilder.append(stackTraceElement.getClassName());
stringBuilder.append(".");
stringBuilder.append(stackTraceElement.getMethodName());
stringBuilder.append("(");
stringBuilder.append(stackTraceElement.getFileName());
stringBuilder.append(":");
stringBuilder.append(stackTraceElement.getLineNumber());
stringBuilder.append(")");
stringBuilder.append("\n");
}
}
}
if (stackTraceElementProxyArray.length < defaultRowLine) {
defaultRowLine = stackTraceElementProxyArray.length;
}
for (int i = 0; i < defaultRowLine; i++) {
stackTraceElementProxy = stackTraceElementProxyArray[i];
StackTraceElement stackTraceElement = stackTraceElementProxy.getStackTraceElement();
stringBuilder.append("\t\tat ");
stringBuilder.append(stackTraceElement.getClassName());
stringBuilder.append(".");
stringBuilder.append(stackTraceElement.getMethodName());
stringBuilder.append("(");
stringBuilder.append(stackTraceElement.getFileName());
stringBuilder.append(":");
stringBuilder.append(stackTraceElement.getLineNumber());
stringBuilder.append(")");
stringBuilder.append("\n");
}
}
}
private String formatLongTime2Str(long timestamp) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
return dateFormat.format(timestamp);
}
private String formatLongTime2Str(long timestamp) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
return dateFormat.format(timestamp);
}
public void setWebHook(String webHook) {
this.webHook = webHook;
}
public void setSecret(String secret) {
this.secret = secret;
}
}

185
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/utils/DingdingMsgSender.java

@ -0,0 +1,185 @@
package com.epmet.commons.tools.utils;
import com.alibaba.fastjson.JSON;
import com.epmet.commons.tools.dto.form.DingTalkTextMsg;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* desc: 发送消息工具类
*
* @date: 2020/6/29 8:43
* @author: jianjun liu
*/
@Component
public class DingdingMsgSender {
private final Logger logger = LoggerFactory.getLogger(DingdingMsgSender.class);
//如果不设置则为 开发环境机器人地址
private static final String webHook = "https://oapi.dingtalk.com/robot/send?access_token=90782b119f82a5b6bb8e0f819b6a77bbc2102b53aa2d7d2e24fa10b66d580b1c";
private static final String secret = "SEC080aac67ff78e79fdaba132aa51e3fb3f6060dec99492feaac82cabf9f8b6a19";
/**
* 默认10
*/
private static Integer maxQueueSize = 10;
/**
* 有序队列
*/
private ArrayBlockingQueue<DingTalkTextMsg> msgQueue = new ArrayBlockingQueue<>(maxQueueSize);
private volatile boolean running = false;
private Cache<String, AtomicInteger> limitCache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).maximumSize(1000).build();
public DingdingMsgSender() {
}
private void handleMsg() {
DingTalkTextMsg msg = null;
try {
//阻塞取元素
msg = msgQueue.take();
if (msg != null) {
AtomicInteger limitCount = limitCache.getIfPresent(msg.getWebHook());
if (limitCount == null) {
limitCount = new AtomicInteger(1);
limitCache.put(msg.getWebHook(), limitCount);
}
if (limitCount.intValue() > maxQueueSize) {
msgQueue.offer(msg);
Thread.sleep(1000);
} else {
sendPostByJSON(msg);
limitCount.addAndGet(1);
}
} else {
Thread.sleep(1000);
}
} catch (Exception e) {
logger.warn("handleMsg exception,serverUrl:" + msg.getWebHook() + ",msg:" + JSON.toJSONString(msg), e);
}
}
/**
* desc:异步发送消息
*
* @param messageParam
* @return
* @throws IOException
*/
public boolean sendMsgAsync(DingTalkTextMsg messageParam) {
if (!running) {
running = true;
getThread().start();
}
boolean flag = false;
int currentQueueSize = msgQueue.size();
//非阻塞 添加/删除元素
if (currentQueueSize < maxQueueSize) {
flag = msgQueue.offer(messageParam);
} else {
msgQueue.poll();
DingTalkTextMsg param = new DingTalkTextMsg();
param.setContent("待发送消息队列已满,当前队列个数" + msgQueue.size() + "\n" + "最新消息内容:" + JSON.toJSONString(messageParam));
param.setWebHook(messageParam.getWebHook());
sendPostByJSON(param);
}
return flag;
}
/**
* 同步发送报警
*
* @param messageParam
* @return
* @throws IOException
*/
public Result<String> sendMsgSync(DingTalkTextMsg messageParam) {
return sendPostByJSON(messageParam);
}
private Thread getThread() {
Thread sendMsgThread = new Thread("MsgSender-Thread") {
@Override
public void run() {
while (running) {
handleMsg();
}
}
};
return sendMsgThread;
}
@PreDestroy
public void destroy() {
running = false;
}
/**
* 发送POST 请求
*
* @param param 请求参数JSON格式
* @return
*/
private Result<String> sendPostByJSON(DingTalkTextMsg param) {
if (StringUtils.isBlank(param.getWebHook())) {
param.setWebHook(webHook);
}
if (StringUtils.isBlank(param.getSecret())) {
param.setSecret(secret);
}
Result<String> result = new Result<String>().error();
Long timestamp = System.currentTimeMillis();
try {
String stringToSign = timestamp + "\n" + param.getSecret();
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(param.getSecret().getBytes("UTF-8"), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
String url = param.getWebHook();
url = url.concat("&timestamp=" + timestamp + "&sign=" + sign);
String jsonStrParam = param.getMsgContent();
result = HttpClientManager.getInstance().sendPostByJSON(url, jsonStrParam);
} catch (Exception e) {
logger.warn("sendPostByJSON error", e);
}
return result;
}
public static void main(String[] args) {
for (int i = 0; i < 50; i++) {
DingTalkTextMsg dingTalkTextMsg = new DingTalkTextMsg();
dingTalkTextMsg.setWebHook("");
dingTalkTextMsg.setContent("测试消息" + i);
dingTalkTextMsg.setAtMobiles(Lists.newArrayList());
dingTalkTextMsg.setAtAll(false);
dingTalkTextMsg.setSecret("");
DingdingMsgSender msgSender = new DingdingMsgSender();
msgSender.sendMsgAsync(dingTalkTextMsg);
}
}
}

12
epmet-module/data-statistical/data-statistical-server/src/main/java/com/epmet/controller/DemoController.java

@ -2,20 +2,21 @@ package com.epmet.controller;
import com.epmet.dto.AgencySubTreeDto;
import com.epmet.service.StatsDemoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.List;
@RequestMapping("demo")
@RestController
@Slf4j
public class DemoController {
@Autowired
@ -24,6 +25,13 @@ public class DemoController {
@Autowired
private ExecutorService executorService;
@GetMapping("testAlarm")
public void testAlarm() {
for (int i = 0; i < 20; i++) {
log.error("测试消息"+i);
}
}
@GetMapping("testtx")
public void testTx() {
demoService.testTx();

2
epmet-module/data-statistical/data-statistical-server/src/main/resources/logback-spring.xml

@ -130,6 +130,8 @@
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
<webHook>https://oapi.dingtalk.com/robot/send?access_token=90782b119f82a5b6bb8e0f819b6a77bbc2102b53aa2d7d2e24fa10b66d580b1c</webHook>
<secret>SEC080aac67ff78e79fdaba132aa51e3fb3f6060dec99492feaac82cabf9f8b6a19</secret>
</filter>
</appender>

Loading…
Cancel
Save