Commit f9465495 authored by tf's avatar tf

优化逻辑

parent 47f50c3c
......@@ -9,7 +9,7 @@
<!--<version>2.2.6.RELEASE</version>-->
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.quantgroup.vcc</groupId>
<groupId>cn.quantgroup.dinglog</groupId>
<artifactId>dinglog-spring-boot-started</artifactId>
<version>0.0.2-SNAPSHOT</version>
<name>dinglog-spring-boot-started</name>
......
package cn.quantgroup.vcc.dinglog.config;
package cn.quantgroup.dinglog.config;
import cn.quantgroup.vcc.dinglog.logback.DingTalkAppenderSync;
import cn.quantgroup.vcc.dinglog.properties.DingLogBackProperties;
import cn.quantgroup.vcc.dinglog.properties.WebHookSecurityProperties;
import cn.quantgroup.vcc.dinglog.service.WebHookServiceImpl;
import cn.quantgroup.dinglog.demo.DemoService;
import cn.quantgroup.dinglog.properties.DingTalkWebHookProperties;
import cn.quantgroup.dinglog.service.DingTalkSendMsgService;
import cn.quantgroup.dinglog.service.impl.DingTalkSendMsgServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
......@@ -16,17 +16,20 @@ import org.springframework.context.annotation.Configuration;
* @Created by tangfeng 2020-07-07 19:56
*/
@Configuration
@EnableConfigurationProperties(value = {WebHookSecurityProperties.class})
@ConditionalOnProperty(matchIfMissing = true)
public class WebHookSecurityConfig {
@EnableConfigurationProperties(value = {DingTalkWebHookProperties.class})
@ConditionalOnProperty(prefix = "dinglog.webhook.security",
name = "accessToken",
matchIfMissing= true)
public class DingTalkWebHookConfig {
@Autowired
private WebHookSecurityProperties webHookSecurityProperties;
private DingTalkWebHookProperties webHookSecurityProperties;
@Bean(name = "webHook")
public WebHookServiceImpl demoService(){
return new WebHookServiceImpl(webHookSecurityProperties);
@ConditionalOnMissingBean(DingTalkSendMsgService.class)
public DingTalkSendMsgService dingTalkSendMsgService(){
return new DingTalkSendMsgServiceImpl(webHookSecurityProperties);
}
......
package cn.quantgroup.vcc.dinglog.demo;
package cn.quantgroup.dinglog.demo;
import cn.quantgroup.vcc.dinglog.logback.DingTalkAppenderSync;
import cn.quantgroup.vcc.dinglog.properties.WebHookSecurityProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
......@@ -14,7 +12,7 @@ import org.springframework.context.annotation.Configuration;
* @Created by tangfeng 2020-05-06 16:40
*/
@Configuration
@EnableConfigurationProperties({DemoProperties.class, WebHookSecurityProperties.class})
@EnableConfigurationProperties({DemoProperties.class})
@ConditionalOnProperty(
prefix = "demo",
name = "isopen",
......@@ -27,13 +25,11 @@ import org.springframework.context.annotation.Configuration;
public class DemoConfig {
@Autowired
private DemoProperties demoProperties;
@Autowired
private WebHookSecurityProperties webHookSecurityProperties;
@Bean(name = "demo")
@ConditionalOnMissingBean(DemoService.class)
public DemoService demoService(){
return new DemoService(demoProperties,webHookSecurityProperties);
return new DemoService(demoProperties);
}
/*@Bean(name = "dintlog")
......
package cn.quantgroup.vcc.dinglog.demo;
package cn.quantgroup.dinglog.demo;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
......
package cn.quantgroup.vcc.dinglog.demo;
package cn.quantgroup.dinglog.demo;
import cn.quantgroup.vcc.dinglog.demo.DemoProperties;
import cn.quantgroup.vcc.dinglog.properties.WebHookSecurityProperties;
/**
* @Describe: 定义demo的函数实现
......@@ -13,7 +11,6 @@ public class DemoService {
* 配置的属性
*/
private DemoProperties demoProperties;
private WebHookSecurityProperties webHookSecurityProperties;
/**
* 构造器
......@@ -22,16 +19,11 @@ public class DemoService {
this.demoProperties = demoProperties;
}
public DemoService(DemoProperties demoProperties, WebHookSecurityProperties webHookSecurityProperties) {
this.webHookSecurityProperties = webHookSecurityProperties;
this.demoProperties = demoProperties;
}
/**
* 可注入实现的函数
*/
public String say() {
return demoProperties.getSayWhat() + "! " + demoProperties.getToWho()+"====="+ webHookSecurityProperties.getAccessToken();
return demoProperties.getSayWhat() + "! " + demoProperties.getToWho();
}
}
package cn.quantgroup.vcc.dinglog.enums;
package cn.quantgroup.dinglog.enums;
/**
* @Describe:
......
package cn.quantgroup.dinglog.logback;
/**
* @Describe:
* @Created by tangfeng 2020-12-16 10:25
*/
public class DingTalkLogbackParam {
private boolean sendMsg = false;
private boolean layoutLog = false;
private String warnLevel = "ERROR";
private String logExStackTracePackage = "quantgroup";
private String webHookAccessToken;
private String markMsg;
public boolean isSendMsg() {
return sendMsg;
}
public void setSendMsg(boolean sendMsg) {
this.sendMsg = sendMsg;
}
public String getWebHookAccessToken() {
return webHookAccessToken;
}
public void setWebHookAccessToken(String webHookAccessToken) {
this.webHookAccessToken = webHookAccessToken;
}
public String getMarkMsg() {
return markMsg;
}
public void setMarkMsg(String markMsg) {
this.markMsg = markMsg;
}
public String getWarnLevel() {
return warnLevel;
}
public void setWarnLevel(String warnLevel) {
this.warnLevel = warnLevel;
}
public boolean isLayoutLog() {
return layoutLog;
}
public void setLayoutLog(boolean layoutLog) {
this.layoutLog = layoutLog;
}
public String getLogExStackTracePackage() {
return logExStackTracePackage;
}
public void setLogExStackTracePackage(String logExStackTracePackage) {
this.logExStackTracePackage = logExStackTracePackage;
}
}
package cn.quantgroup.dinglog.logback;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.classic.spi.StackTraceElementProxy;
import ch.qos.logback.core.spi.ContextAwareBase;
import cn.quantgroup.dinglog.util.DingTalkSendMsgUtil;
import org.apache.commons.lang3.StringUtils;
/**
* @Describe:
* @Created by tangfeng 2020-12-18 15:31
*/
public class DingTalkLogbackSendMsg {
public static void sendMsg(ContextAwareBase base, PatternLayoutEncoder encoder, LoggingEvent event, String appenderName, DingTalkLogbackParam dingTalkLogbackParam) {
//dingTalk sdk 内部日志异常,直接过滤掉,避免出现error日志死循环发钉钉消息处理
if (event.getLoggerName().equalsIgnoreCase("topsdk")) {
return;
}
if (dingTalkLogbackParam == null) {
return;
}
boolean sendMsg = dingTalkLogbackParam.isSendMsg();
if (!sendMsg) {
return;
}
if (!event.getLevel().levelStr.equalsIgnoreCase(dingTalkLogbackParam.getWarnLevel())) {
return;
}
String accessToken = dingTalkLogbackParam.getWebHookAccessToken();
if (StringUtils.isEmpty(accessToken)) {
base.addInfo("No dingTalk accessToken for the appender named [" + appenderName + "].");
return;
}
try {
//按照格式化日志形式输出
if (dingTalkLogbackParam.isLayoutLog() && encoder.getLayout() != null) {
String layoutLog = encoder.getLayout().doLayout(event);
if (StringUtils.isNotEmpty(dingTalkLogbackParam.getMarkMsg())) {
layoutLog = dingTalkLogbackParam.getMarkMsg().concat("---").concat(layoutLog);
}
DingTalkSendMsgUtil.sendTextMsg(layoutLog, accessToken);
return;
}
//简易形式输出
String message = event.getFormattedMessage();
IThrowableProxy throwableProxy = event.getThrowableProxy();
StringBuffer sbExMsg = new StringBuffer();
if (throwableProxy != null) {
sbExMsg = sbExMsg.append(throwableProxy.getClassName());
String exMessage = throwableProxy.getMessage();
if (StringUtils.isNotEmpty(exMessage)) {
sbExMsg.append(": ").append(exMessage).append("\n");
}
StackTraceElementProxy[] stackTraceElementProxyArray = throwableProxy.getStackTraceElementProxyArray();
if (stackTraceElementProxyArray != null && stackTraceElementProxyArray.length > 0) {
for (int i = 0; i < stackTraceElementProxyArray.length; i++) {
StackTraceElementProxy st = stackTraceElementProxyArray[i];
if (StringUtils.isNotEmpty(dingTalkLogbackParam.getLogExStackTracePackage()) && st.toString().contains(dingTalkLogbackParam.getLogExStackTracePackage()) ) {
sbExMsg.append(st.toString()).append("\n");
}
}
}
message = message.concat(", ").concat(sbExMsg.toString());
}
if (StringUtils.isNotEmpty(dingTalkLogbackParam.getMarkMsg())) {
message = dingTalkLogbackParam.getMarkMsg().concat("---").concat(message);
}
DingTalkSendMsgUtil.sendTextMsg(message, accessToken);
} catch (Exception e) {
base.addInfo("ding talk logback send msg error:{}", e);
}
}
}
package cn.quantgroup.dinglog.logback.appender;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.AppenderBase;
import cn.quantgroup.dinglog.logback.DingTalkLogbackParam;
import cn.quantgroup.dinglog.logback.DingTalkLogbackSendMsg;
/**
* @Describe:
* @Created by tangfeng 2020-12-14 14:50
*/
public class DingTalkAppender extends AppenderBase<LoggingEvent> {
PatternLayoutEncoder encoder;
DingTalkLogbackParam dingTalkLogbackParam;
@Override
public void start() {
if (this.encoder == null) {
//name : logback.xml 中 appender 标签 配置的name值
addError("No encoder set for the appender named [" + name + "].");
return;
}
addInfo("DingTalkAppender start方法被调用");
super.start();
}
@Override
public void stop() {
//释放相关资源,如数据库连接,redis线程池等等
addInfo("DingTalkAppender stop方法被调用");
if (!isStarted()) {
return;
}
super.stop();
}
@Override
protected void append(LoggingEvent event) {
DingTalkLogbackSendMsg.sendMsg(this, encoder,event, name, dingTalkLogbackParam);
}
public PatternLayoutEncoder getEncoder() {
return encoder;
}
public void setEncoder(PatternLayoutEncoder encoder) {
this.encoder = encoder;
}
public DingTalkLogbackParam getDingTalkLogbackParam() {
return dingTalkLogbackParam;
}
public void setDingTalkLogbackParam(DingTalkLogbackParam dingTalkLogbackParam) {
this.dingTalkLogbackParam = dingTalkLogbackParam;
}
}
package cn.quantgroup.dinglog.logback.appender;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import cn.quantgroup.dinglog.logback.DingTalkLogbackParam;
import cn.quantgroup.dinglog.logback.DingTalkLogbackSendMsg;
/**
* @Describe:
* @Created by tangfeng 2020-12-14 14:50
*/
public class DingTalkAppenderUnSync extends UnsynchronizedAppenderBase<LoggingEvent> {
PatternLayoutEncoder encoder;
DingTalkLogbackParam dingTalkLogbackParam;
@Override
public void start() {
if (this.encoder == null) {
//name : logback.xml 中 appender 标签 配置的name值
addError("No encoder set for the appender named [" + name + "].");
return;
}
addInfo("DingTalkAppenderUnSync start方法被调用");
super.start();
}
@Override
public void stop() {
//释放相关资源,如数据库连接,redis线程池等等
addInfo("DingTalkAppenderUnSync stop方法被调用");
if (!isStarted()) {
return;
}
super.stop();
}
@Override
protected void append(LoggingEvent event) {
DingTalkLogbackSendMsg.sendMsg(this,encoder, event, name, dingTalkLogbackParam);
}
public PatternLayoutEncoder getEncoder() {
return encoder;
}
public void setEncoder(PatternLayoutEncoder encoder) {
this.encoder = encoder;
}
public DingTalkLogbackParam getDingTalkLogbackParam() {
return dingTalkLogbackParam;
}
public void setDingTalkLogbackParam(DingTalkLogbackParam dingTalkLogbackParam) {
this.dingTalkLogbackParam = dingTalkLogbackParam;
}
}
package cn.quantgroup.vcc.dinglog.properties;
package cn.quantgroup.dinglog.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
......@@ -10,14 +10,18 @@ import java.util.Map;
* @Created by tangfeng 2020-07-07 17:45
*/
@ConfigurationProperties(prefix = "dinglog.webhook.security")
public class WebHookSecurityProperties {
public class DingTalkWebHookProperties {
/**
* 业务关键词
*/
private String keyWords;
//private Map<String,String> appenderNameToken;
/**
* robot token
*/
private String accessToken;
/**
* 签名的秘钥
*/
......@@ -26,14 +30,7 @@ public class WebHookSecurityProperties {
* ip段
*/
private String ipSegments;
/**
* robot token
*/
private String accessToken;
/**
* robot send url
*/
private String url = "https://oapi.dingtalk.com/robot/send";
public String getKeyWords() {
return keyWords;
......@@ -67,30 +64,4 @@ public class WebHookSecurityProperties {
this.accessToken = accessToken;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
/*public Map<String, String> getAppenderNameToken() {
return appenderNameToken;
}
public void setAppenderNameToken(Map<String, String> appenderNameToken) {
this.appenderNameToken = appenderNameToken;
}*/
@Override
public String toString() {
return "WebHookSecurityProperties{" +
"keyWords='" + keyWords + '\'' +
", signSecret='" + signSecret + '\'' +
", ipSegments='" + ipSegments + '\'' +
", accessToken='" + accessToken + '\'' +
", url='" + url + '\'' +
'}';
}
}
package cn.quantgroup.dinglog.service;
/**
* @Describe:
* @Created by tangfeng 2020-07-07 19:58
*/
public interface DingTalkSendMsgService {
boolean sendTextMsg(String content);
boolean sendTextMsg(String content, String accessToken);
boolean sendTextMsg(String content, String accessToken, String keyWords);
}
package cn.quantgroup.dinglog.service.impl;
import cn.quantgroup.dinglog.properties.DingTalkWebHookProperties;
import cn.quantgroup.dinglog.service.DingTalkSendMsgService;
import cn.quantgroup.dinglog.util.DingTalkSendMsgUtil;
import org.springframework.util.Assert;
/**
* @Describe:
* @Created by tangfeng 2020-07-07 19:58
*/
public class DingTalkSendMsgServiceImpl implements DingTalkSendMsgService {
private DingTalkWebHookProperties dingTalkWebHookProperties;
@Override
public boolean sendTextMsg(String content) {
Assert.notNull(dingTalkWebHookProperties, DingTalkWebHookProperties.class.toString().concat("不能为空"));
return sendTextMsg(content, dingTalkWebHookProperties.getAccessToken(), dingTalkWebHookProperties.getKeyWords());
}
@Override
public boolean sendTextMsg(String content, String accessToken) {
return sendTextMsg(content, accessToken, null);
}
@Override
public boolean sendTextMsg(String content, String accessToken, String keyWords) {
return DingTalkSendMsgUtil.sendTextMsg(content, accessToken, keyWords);
}
public DingTalkSendMsgServiceImpl(DingTalkWebHookProperties dingTalkWebHookProperties) {
this.dingTalkWebHookProperties = dingTalkWebHookProperties;
}
public DingTalkSendMsgServiceImpl() {
}
}
package cn.quantgroup.dinglog.util;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
/**
* @Describe:
* @Created by tangfeng 2020-07-07 19:58
*/
public class DingTalkSendMsgUtil {
private static final String dingTalkWebHookDomain = "https://oapi.dingtalk.com/robot/send?access_token=";
/**
* 发送json串消息
*/
public static boolean sendTextMsg(String content, String accessToken) {
return sendTextMsg(content, accessToken, null);
}
public static boolean sendTextMsg(String content, String accessToken, String keyWords) {
Assert.notNull(content, "消息内容不能为空");
Assert.notNull(accessToken, "accessToken不能为空");
if (StringUtils.isNotEmpty(keyWords)) {
content = keyWords.concat(content);
}
try {
OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
text.setContent(content);
String tokenURL = dingTalkWebHookDomain.concat(accessToken);
DingTalkClient client = new DefaultDingTalkClient(tokenURL);
OapiRobotSendRequest request = new OapiRobotSendRequest();
request.setMsgtype("text");
request.setText(text);
OapiRobotSendResponse response = client.execute(request);
//System.out.println(JSONObject.toJSONString(response));
} catch (Exception e) {
System.out.println("========");
}
return true;
}
}
package cn.quantgroup.vcc.dinglog.util;
package cn.quantgroup.dinglog.util;
import org.apache.commons.codec.binary.Base64;
......
package cn.quantgroup.vcc.dinglog;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
/*@SpringBootApplication
@EnableConfigurationProperties
public class BootStrap {
public static void main(String[] args) {
SpringApplication.run(BootStrap.class, args);
}
}*/
package cn.quantgroup.vcc.dinglog.config;
import cn.quantgroup.vcc.dinglog.demo.DemoService;
import cn.quantgroup.vcc.dinglog.logback.DingTalkAppenderSync;
import cn.quantgroup.vcc.dinglog.properties.DingLogBackProperties;
import cn.quantgroup.vcc.dinglog.properties.WebHookSecurityProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Describe:
* @Created by tangfeng 2020-12-15 15:00
*/
@Configuration
@EnableConfigurationProperties({DingLogBackProperties.class})
@ConditionalOnProperty(
prefix = "dinglog.logback",
name = "isopen",
havingValue = "true",
matchIfMissing = true
)
public class DingLogBackConfig {
/*@Autowired
private DingLogBackProperties dingLogBackProperties;
@Autowired
private WebHookSecurityProperties webHookSecurityProperties;
@Bean(name = "dingTalkAppenderSync")
public DingTalkAppenderSync dingTalkAppenderSync(){
return new DingTalkAppenderSync(dingLogBackProperties,webHookSecurityProperties);
}*/
}
package cn.quantgroup.vcc.dinglog.logback;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Layout;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
/**
* @Describe:
* @Created by tangfeng 2020-12-14 14:50
*/
public class DingTalkAppenderAsync extends UnsynchronizedAppenderBase<ILoggingEvent> {
Layout<ILoggingEvent> layout;
//自定义配置
String printString;
public Layout<ILoggingEvent> getLayout() {
return layout;
}
public void setLayout(Layout<ILoggingEvent> layout) {
this.layout = layout;
}
public String getPrintString() {
return printString;
}
public void setPrintString(String printString) {
this.printString = printString;
}
@Override
public void start(){
/**
* 这里可以做些初始化判断 比如layout不能为null
*/
if(layout == null) {
addWarn("Layout was not defined");
}
/**
* 或者写入数据库 或者redis时 初始化连接等等
*/
super.start();
}
@Override
public void stop()
{
/**
* 释放相关资源,如数据库连接,redis线程池等等
*/
System.out.println("logback-stop方法被调用");
if(!isStarted()) {
return;
}
super.stop();
}
@Override
public void append(ILoggingEvent event) {
if (event == null || !isStarted()){
return;
}
/**
* 自定义日志输出的逻辑
* 比如 操作数据库 redis kafka
* 当然,我的本质目的是发钉钉消息
*/
/*System.out.print("获取输出值---"+event.getFormattedMessage());
System.out.println("格式化输出日志:"+printString + ":" + layout.doLayout(event));
System.out.println("============================================== MyLogbackAppender要发消息了");*/
//发钉钉消息: 具体处理逻辑,参考钉钉的文档,此处暂不实现
//后续计划会开发一个 dingtalk-log-springboot-start 包
try {
OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
text.setContent("这是一个测试");
//https://oapi.dingtalk.com/robot/send?access_token=
String accessToken = "{填入自己钉钉群自定义机器人的 webhook token}";
String tokenURL = "https://oapi.dingtalk.com/robot/send?access_token=".concat(accessToken);
DingTalkClient client = new DefaultDingTalkClient(tokenURL);
OapiRobotSendRequest request = new OapiRobotSendRequest();
request.setMsgtype("text");
request.setText(text);
//OapiRobotSendResponse response = client.execute(request);
} catch (Exception e) {
}
}
}
package cn.quantgroup.vcc.dinglog.logback;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.AppenderBase;
import cn.quantgroup.vcc.dinglog.demo.DemoProperties;
import cn.quantgroup.vcc.dinglog.properties.WebHookSecurityProperties;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import org.apache.commons.lang3.StringUtils;
/**
* @Describe:
* @Created by tangfeng 2020-12-14 14:50
*/
public class DingTalkAppenderSync extends AppenderBase<LoggingEvent> {
PatternLayoutEncoder encoder;
//WebHookSecurityProperties webHookSecurityProperties;
@Override
public void start() {
if (this.encoder == null) {
//name : logback.xml 中 appender 标签 配置的name值
addError("No encoder set for the appender named [" + name + "].");
return;
}
super.start();
}
@Override
public void stop() {
//释放相关资源,如数据库连接,redis线程池等等
System.out.println("stop方法被调用");
if (!isStarted()) {
return;
}
super.stop();
}
@Override
protected void append(LoggingEvent eventObject) {
Level level = eventObject.getLevel();
/**
* 指定只有 error 级别的日志,才发消息
* 后续可以根据配置指定,此处暂不实现
*/
//System.out.println("test2:" + JSONObject.toJSONString(webHookSecurityProperties));
String loggerName = eventObject.getLoggerName();
System.out.println("loggerName:" + loggerName+"=========appenderName"+name);
if (level.ERROR.levelInt == level.levelInt) {
//Map<String, String> appenderNameToken = webHookSecurityProperties.getAppenderNameToken();
String accessToken = null;
/*for (Map.Entry<String, String> entry : appenderNameToken.entrySet()) {
if (entry.getKey().equals(name)) {
accessToken = entry.getValue();
}
}*/
if (StringUtils.isEmpty(accessToken)) {
System.out.println("没有匹配的name和token");
return;
}
//System.out.println("DingTalkAppenderSync============================================== 要发钉钉消息了");
/**
* 发钉钉消息的逻辑,参看钉钉文档,暂不实现
* 后续计划会开发一个 dingtalk-log-springboot-start 包
*/
try {
OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
text.setContent("告警任务:验证日志输出同时发钉钉消息");
//https://oapi.dingtalk.com/robot/send?access_token=030bcf64f152dd8d53b5da9c3dd92a0bcb1c2269f41a3ba584b060339bcc6f74
//String accessToken = "{填入自己钉钉群自定义机器人的 webhook token}";
String tokenURL = "https://oapi.dingtalk.com/robot/send?access_token=".concat(accessToken);
DingTalkClient client = new DefaultDingTalkClient(tokenURL);
OapiRobotSendRequest request = new OapiRobotSendRequest();
request.setMsgtype("text");
request.setText(text);
OapiRobotSendResponse response = client.execute(request);
System.out.println(JSONObject.toJSONString(response));
} catch (Exception e) {
}
}
}
/*public DingTalkAppenderSync(PatternLayoutEncoder encoder) {
this.encoder = encoder;
}
public DingTalkAppenderSync(DingLogBackProperties dingLogBackProperties) {
this.dingLogBackProperties = dingLogBackProperties;
}
public DingTalkAppenderSync(WebHookSecurityProperties webHookSecurityProperties) {
this.webHookSecurityProperties = webHookSecurityProperties;
}
public DingTalkAppenderSync(PatternLayoutEncoder encoder, DingLogBackProperties dingLogBackProperties, WebHookSecurityProperties webHookSecurityProperties) {
this.encoder = encoder;
this.dingLogBackProperties = dingLogBackProperties;
this.webHookSecurityProperties = webHookSecurityProperties;
}*/
public PatternLayoutEncoder getEncoder() {
return encoder;
}
public void setEncoder(PatternLayoutEncoder encoder) {
this.encoder = encoder;
}
/*public DingTalkAppenderSync(WebHookSecurityProperties webHookSecurityProperties) {
this.webHookSecurityProperties = webHookSecurityProperties;
}
public WebHookSecurityProperties getWebHookSecurityProperties() {
return webHookSecurityProperties;
}
public void setWebHookSecurityProperties(WebHookSecurityProperties webHookSecurityProperties) {
this.webHookSecurityProperties = webHookSecurityProperties;
}*/
}
package cn.quantgroup.vcc.dinglog.mo;
import java.util.List;
/**
* @Describe:
* @Created by tangfeng 2020-07-09 13:57
*/
public class ContentActionCardMore {
/**
* title : 乔布斯 20 年前想打造一间苹果咖啡厅,而它正是 Apple Store 的前身
* text : ![screenshot](https://gw.alicdn.com/tfs/TB1ut3xxbsrBKNjSZFpXXcXhFXa-846-786.png) ### 乔布斯 20 年前想打造的苹果咖啡厅 Apple Store 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划
* btnOrientation : 0
* btns : [{"title":"内容不错","actionURL":"https://www.dingtalk.com/"},{"title":"不感兴趣","actionURL":"https://www.dingtalk.com/"}]
*/
/**
* 首屏会话透出的展示内容
*/
private String title;
/**
* markdown格式的消息
*/
private String text;
private String btnOrientation;
/**
* 按钮
*/
private List<BtnContent> btns;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getBtnOrientation() {
return btnOrientation;
}
public void setBtnOrientation(String btnOrientation) {
this.btnOrientation = btnOrientation;
}
public List<BtnContent> getBtns() {
return btns;
}
public void setBtns(List<BtnContent> btns) {
this.btns = btns;
}
public static class BtnContent {
/**
* title : 内容不错
* actionURL : https://www.dingtalk.com/
*/
/**
* 按钮标题
*/
private String title;
/**
* 按钮跳转URL
*/
private String actionURL;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getActionURL() {
return actionURL;
}
public void setActionURL(String actionURL) {
this.actionURL = actionURL;
}
}
}
package cn.quantgroup.vcc.dinglog.mo;
/**
* @Describe:
* @Created by tangfeng 2020-07-09 13:57
*/
public class ContentActionCardSingle {
/**
* title : 乔布斯 20 年前想打造一间苹果咖啡厅,而它正是 Apple Store 的前身
* text(markdown ) :
* "![screenshot](https://gw.alicdn.com/tfs/TB1ut3xxbsrBKNjSZFpXXcXhFXa-846-786.png)
* ### 乔布斯 20 年前想打造的苹果咖啡厅
* Apple Store 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划",
* "btnOrientation": "0",
* "singleTitle" : "阅读全文",
* "singleURL" : "https://www.dingtalk.com/"
*/
/**
* 首屏会话透出的展示内容
*/
private String title;
/**
* markdown格式的消息
*/
private String text;
private String btnOrientation;
private String singleTitle;
private String singleURL;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getBtnOrientation() {
return btnOrientation;
}
public void setBtnOrientation(String btnOrientation) {
this.btnOrientation = btnOrientation;
}
public String getSingleTitle() {
return singleTitle;
}
public void setSingleTitle(String singleTitle) {
this.singleTitle = singleTitle;
}
public String getSingleURL() {
return singleURL;
}
public void setSingleURL(String singleURL) {
this.singleURL = singleURL;
}
}
package cn.quantgroup.vcc.dinglog.mo;
/**
* @Describe:
* @Created by tangfeng 2020-07-09 13:53
*/
public class ContentLink {
/**
* text : 这个即将发布的新版本,创始人xx称它为红树林。而在此之前,每当面临重大升级,产品经理们都会取一个应景的代号,这一次,为什么是红树林
* title : 时代的火车向前开
* picUrl :
* messageUrl : https://www.dingtalk.com/s?__biz=MzA4NjMwMTA2Ng==&mid=2650316842&idx=1&sn=60da3ea2b29f1dcc43a7c8e4a7c97a16&scene=2&srcid=09189AnRJEdIiWVaKltFzNTw&from=timeline&isappinstalled=0&key=&ascene=2&uin=&devicetype=android-23&version=26031933&nettype=WIFI
*/
private String text;
private String title;
private String picUrl;
private String messageUrl;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPicUrl() {
return picUrl;
}
public void setPicUrl(String picUrl) {
this.picUrl = picUrl;
}
public String getMessageUrl() {
return messageUrl;
}
public void setMessageUrl(String messageUrl) {
this.messageUrl = messageUrl;
}
}
package cn.quantgroup.vcc.dinglog.mo;
/**
* @Describe:
* @Created by tangfeng 2020-07-09 13:56
*/
public class ContentMarkDown {
/**
* title : 杭州天气
* text : #### 杭州天气 @150XXXXXXXX
> 9度,西北风1级,空气良89,相对温度73%
> ![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png)
> ###### 10点20分发布 [天气](https://www.dingtalk.com)
*/
private String title;
private String text;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
package cn.quantgroup.vcc.dinglog.mo;
/**
* @Describe:
* @Created by tangfeng 2020-07-09 10:13
*/
public class ContentText extends MsgBase {
/**
* "我就是我, 是不一样的烟火@156xxxx8827"
*/
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
package cn.quantgroup.vcc.dinglog.mo;
import java.util.List;
/**
* @Describe:
* @Created by tangfeng 2020-07-09 10:13
*/
public class MsgAt {
/**
* 发送消息@的人手机号
*/
private List<String> atMobiles;
/**
* 是否@ 所有人
*/
private boolean isAtAll;
public List<String> getAtMobiles() {
return atMobiles;
}
public void setAtMobiles(List<String> atMobiles) {
this.atMobiles = atMobiles;
}
public boolean isAtAll() {
return isAtAll;
}
public void setAtAll(boolean atAll) {
isAtAll = atAll;
}
}
package cn.quantgroup.vcc.dinglog.mo;
/**
* @Describe:
* @Created by tangfeng 2020-07-09 10:12
*/
public class MsgBase {
private String msgType;
public String getMsgType() {
return msgType;
}
public void setMsgType(String msgType) {
this.msgType = msgType;
}
}
package cn.quantgroup.vcc.dinglog.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @Describe:
* @Created by tangfeng 2020-12-15 14:56
*/
@ConfigurationProperties(prefix = "dinglog.logback")
public class DingLogBackProperties {
private String accessToken;
private String appenderName;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getAppenderName() {
return appenderName;
}
public void setAppenderName(String appenderName) {
this.appenderName = appenderName;
}
}
package cn.quantgroup.vcc.dinglog.service;
import cn.quantgroup.vcc.dinglog.properties.WebHookSecurityProperties;
import cn.quantgroup.vcc.dinglog.util.HttpClientUitl;
import cn.quantgroup.vcc.dinglog.util.HttpUtil;
import cn.quantgroup.vcc.dinglog.util.WebHookSignUtil;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.nio.file.WatchEvent;
/**
* @Describe:
* @Created by tangfeng 2020-07-07 19:58
*/
public class WebHookServiceImpl {
Logger log = LoggerFactory.getLogger(WebHookServiceImpl.class);
private WebHookSecurityProperties webHookSecurityProperties;
public WebHookServiceImpl() {
}
public WebHookServiceImpl(WebHookSecurityProperties webHookSecurityProperties) {
this.webHookSecurityProperties = webHookSecurityProperties;
}
/**
* 发送json串消息
*/
public boolean sendDingMsg(String json) throws Exception{
try {
String sendUrl = getSendUrl();
//String s = HttpUtil.doPost(sendUrl,null);
String s = HttpClientUitl.doGet("http://talos-vcc.liangkebang.net/ex/login/getVccToken?phone=17346526631&systemKey=vcc&loginFrom=159860");
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("发出的消息内容是:" + json+ "________"+ JSONObject.toJSONString(webHookSecurityProperties));
log.info("json:{},webHookProperties:{}",json, webHookSecurityProperties.toString());
return true;
}
private String getSendUrl()throws Exception{
checkWebHookPreoperties();
String url = webHookSecurityProperties.getUrl().concat("?access_token=").concat(webHookSecurityProperties.getAccessToken());
long timeStamp = System.currentTimeMillis();
String signPath = null;
if (!StringUtils.isEmpty(webHookSecurityProperties.getSignSecret())) {
String sign = WebHookSignUtil.sign(timeStamp, webHookSecurityProperties.getSignSecret());
signPath = String.format("&timestamp=%s&sign=%s", timeStamp, sign);
}
if (!StringUtils.isEmpty(signPath)) {
url = url.concat(signPath);
}
return url;
}
private void checkWebHookPreoperties(){
Assert.notNull(webHookSecurityProperties.getAccessToken(),"accessToken is null");
}
}
package cn.quantgroup.vcc.dinglog.util;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
/**
* @Describe:
* @Created by tangfeng 2020-07-07 17:01
*/
public class HttpUtil {
public static String doGet(String url) throws Exception {
HttpGet httpGet = new HttpGet(url);
return execute(httpGet);
}
public static String doPost(String url, Map<String, String> param) throws Exception {
HttpPost httpPost = new HttpPost(url);
ArrayList<BasicNameValuePair> arrayList = new ArrayList<BasicNameValuePair>();
Set<String> keySet = param.keySet();
for (String key : keySet) {
arrayList.add(new BasicNameValuePair(key, param.get(key)));
}
httpPost.setEntity(new UrlEncodedFormEntity(arrayList));
return execute(httpPost);
}
private static String execute(HttpRequestBase request) throws IOException, ClientProtocolException {
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(request);
if (200 == response.getStatusLine().getStatusCode()) {
return EntityUtils.toString(response.getEntity(), Charset.forName("utf-8"));
} else {
System.out.println(EntityUtils.toString(response.getEntity(), Charset.forName("utf-8")));
}
return "";
}
}
#-------starter自动装配,多个以逗号隔开---------
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.quantgroup.vcc.dinglog.demo.DemoConfig
cn.quantgroup.dinglog.demo.DemoConfig,\
cn.quantgroup.dinglog.config.DingTalkWebHookConfig
package cn.quantgroup.vcc.dinglog;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class BootStrapTests {
@Test
void contextLoads() {
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment