1.创建基础Bean
public final class ThreadFactory implements java.util.concurrent.ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
public ThreadFactory(String groupFlag, String functionName) {
SecurityManager s = System.getSecurityManager();
this.group = s != null ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
this.namePrefix = this.buildPrefix(groupFlag, functionName, poolNumber);
}
private String buildPrefix(String vendorFlag, String functionName, final AtomicInteger poolNumber) {
StringBuffer sb = (new StringBuffer("pool-")).append(poolNumber.getAndIncrement()).append("-thread-");
String connChar = "-";
if (null != vendorFlag && !"".equals(vendorFlag)) {
sb.append(vendorFlag).append(connChar);
}
if (null != functionName && !"".equals(functionName)) {
sb.append(functionName).append(connChar);
}
return sb.toString();
}
public Thread newThread(Runnable r) {
String threadName = this.namePrefix + this.threadNumber.getAndIncrement();
Thread t = new Thread(this.group, r, threadName, 0L);
if (t.isDaemon()) {
t.setDaemon(false);
}
if (t.getPriority() != 5) {
t.setPriority(5);
}
return t;
}
}
public class QiWeiMarkDownMessage<T> {
private String msgtype;
private T markdown;
public QiWeiMarkDownMessage() {
}
public String getMsgtype() {
return this.msgtype;
}
public T getMarkdown() {
return this.markdown;
}
public void setMsgtype(final String msgtype) {
this.msgtype = msgtype;
}
public void setMarkdown(final T markdown) {
this.markdown = markdown;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof QiWeiMarkDownMessage)) {
return false;
} else {
QiWeiMarkDownMessage<?> other = (QiWeiMarkDownMessage)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$msgtype = this.getMsgtype();
Object other$msgtype = other.getMsgtype();
if (this$msgtype == null) {
if (other$msgtype != null) {
return false;
}
} else if (!this$msgtype.equals(other$msgtype)) {
return false;
}
Object this$markdown = this.getMarkdown();
Object other$markdown = other.getMarkdown();
if (this$markdown == null) {
if (other$markdown != null) {
return false;
}
} else if (!this$markdown.equals(other$markdown)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(final Object other) {
return other instanceof QiWeiMarkDownMessage;
}
public int hashCode() {
int result = 1;
Object $msgtype = this.getMsgtype();
result = result * 59 + ($msgtype == null ? 43 : $msgtype.hashCode());
Object $markdown = this.getMarkdown();
result = result * 59 + ($markdown == null ? 43 : $markdown.hashCode());
return result;
}
public String toString() {
return "QiWeiMarkDownMessage(msgtype=" + this.getMsgtype() + ", markdown=" + this.getMarkdown() + ")";
}
}
public class QiWeiMessageContext {
private String content;
private String mentioned_list;
private String mentioned_mobile_list;
public QiWeiMessageContext() {
}
public String getContent() {
return this.content;
}
public String getMentioned_list() {
return this.mentioned_list;
}
public String getMentioned_mobile_list() {
return this.mentioned_mobile_list;
}
public void setContent(final String content) {
this.content = content;
}
public void setMentioned_list(final String mentioned_list) {
this.mentioned_list = mentioned_list;
}
public void setMentioned_mobile_list(final String mentioned_mobile_list) {
this.mentioned_mobile_list = mentioned_mobile_list;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof QiWeiMessageContext)) {
return false;
} else {
QiWeiMessageContext other = (QiWeiMessageContext)o;
if (!other.canEqual(this)) {
return false;
} else {
label47: {
Object this$content = this.getContent();
Object other$content = other.getContent();
if (this$content == null) {
if (other$content == null) {
break label47;
}
} else if (this$content.equals(other$content)) {
break label47;
}
return false;
}
Object this$mentioned_list = this.getMentioned_list();
Object other$mentioned_list = other.getMentioned_list();
if (this$mentioned_list == null) {
if (other$mentioned_list != null) {
return false;
}
} else if (!this$mentioned_list.equals(other$mentioned_list)) {
return false;
}
Object this$mentioned_mobile_list = this.getMentioned_mobile_list();
Object other$mentioned_mobile_list = other.getMentioned_mobile_list();
if (this$mentioned_mobile_list == null) {
if (other$mentioned_mobile_list != null) {
return false;
}
} else if (!this$mentioned_mobile_list.equals(other$mentioned_mobile_list)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(final Object other) {
return other instanceof QiWeiMessageContext;
}
public int hashCode() {
int result = 1;
Object $content = this.getContent();
result = result * 59 + ($content == null ? 43 : $content.hashCode());
Object $mentioned_list = this.getMentioned_list();
result = result * 59 + ($mentioned_list == null ? 43 : $mentioned_list.hashCode());
Object $mentioned_mobile_list = this.getMentioned_mobile_list();
result = result * 59 + ($mentioned_mobile_list == null ? 43 : $mentioned_mobile_list.hashCode());
return result;
}
public String toString() {
return "QiWeiMessageContext(content=" + this.getContent() + ", mentioned_list=" + this.getMentioned_list() + ", mentioned_mobile_list=" + this.getMentioned_mobile_list() + ")";
}
}
public class MachineUtils {
public MachineUtils() {
}
public static String getHostIpFromDockerContainer() {
String ip = null;
try {
Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces();
while(networkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface)networkInterfaces.nextElement();
if (!"docker0".equals(networkInterface.getDisplayName()) && !"lo".equals(networkInterface.getDisplayName())) {
Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
StringJoiner ipJoiner = new StringJoiner("/", "(", ")");
while(inetAddresses.hasMoreElements()) {
InetAddress inetAddress = (InetAddress)inetAddresses.nextElement();
ipJoiner.add(inetAddress.getHostAddress());
}
ip = ipJoiner.toString();
break;
}
}
} catch (Exception var6) {
System.out.println("获取容器ip信息失败:" + var6);
ip = "未获取到容器对应宿主机ip信息";
}
return ip;
}
public static MachineUtils.Machine getMachineInfo() {
MachineUtils.Machine machine = new MachineUtils.Machine();
try {
InetAddress address = getLocalHostLANAddress();
String ip = address.getHostAddress();
String hostName = address.getHostName();
machine.ip = ip;
machine.hostName = hostName;
} catch (Exception var4) {
machine.hostName = "localhost";
machine.ip = "127.0.0.1";
}
return machine;
}
private static InetAddress getLocalHostLANAddress() throws UnknownHostException {
try {
InetAddress candidateAddress = null;
Enumeration ifaces = NetworkInterface.getNetworkInterfaces();
while(ifaces.hasMoreElements()) {
NetworkInterface iface = (NetworkInterface)ifaces.nextElement();
Enumeration inetAddrs = iface.getInetAddresses();
while(inetAddrs.hasMoreElements()) {
InetAddress inetAddr = (InetAddress)inetAddrs.nextElement();
if (!inetAddr.isLoopbackAddress()) {
if (inetAddr.isSiteLocalAddress()) {
return inetAddr;
}
if (candidateAddress == null) {
candidateAddress = inetAddr;
}
}
}
}
if (candidateAddress != null) {
return candidateAddress;
} else {
InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
if (jdkSuppliedAddress == null) {
throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
} else {
return jdkSuppliedAddress;
}
}
} catch (Exception var5) {
UnknownHostException unknownHostException = new UnknownHostException("Failed to determine LAN address: " + var5);
unknownHostException.initCause(var5);
throw unknownHostException;
}
}
public static class Machine {
public String ip = "";
public String hostName = "";
public Machine() {
}
}
}
public class ThrowableUtils {
public ThrowableUtils() {
}
public static String getThrowableStackTrace(Throwable t) {
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw, true));
String result = sw.getBuffer().toString();
return result.length() > 3700 ? result.substring(0, 3700) + "\n..." : result;
}
}
public class OKHttpUtil {
private static final Logger log = LoggerFactory.getLogger(OKHttpUtil.class);
private static volatile OkHttpClient okHttpClient = null;
private static volatile Semaphore semaphore = null;
private static final String CONTENT_TYPE = "Content-Type";
private OKHttpUtil() {
if (okHttpClient == null) {
Class var1 = OKHttpUtil.class;
synchronized(OKHttpUtil.class) {
if (okHttpClient == null) {
TrustManager[] trustManagers = buildTrustManagers();
okHttpClient = (new Builder()).connectTimeout(15L, TimeUnit.SECONDS).writeTimeout(20L, TimeUnit.SECONDS).readTimeout(20L, TimeUnit.SECONDS).sslSocketFactory(createSSLSocketFactory(trustManagers), (X509TrustManager)trustManagers[0]).hostnameVerifier((hostName, session) -> {
return true;
}).retryOnConnectionFailure(true).build();
}
}
}
}
public static OKHttpUtil builder() {
return new OKHttpUtil();
}
private static Semaphore getSemaphoreInstance() {
Class var0 = OKHttpUtil.class;
synchronized(OKHttpUtil.class) {
if (semaphore == null) {
semaphore = new Semaphore(0);
}
}
return semaphore;
}
private static okhttp3.Request.Builder addHeaders(Map<String, Object> headerMap, okhttp3.Request.Builder builder) {
if (headerMap != null && !headerMap.isEmpty()) {
headerMap.forEach((key, value) -> {
builder.addHeader(key, String.valueOf(value));
});
}
return builder;
}
private RequestBody setRequestBody(Map<String, Object> bodyParams, Map<String, Object> headerMap) throws Exception {
if (headerMap != null && headerMap.containsKey("Content-Type")) {
String contentType = String.valueOf(headerMap.get("Content-Type"));
if ("application/x-www-form-urlencoded".equals(contentType)) {
Map<String, String> strBodyParamMap = new HashMap();
if (bodyParams != null && !bodyParams.isEmpty()) {
bodyParams.forEach((key, value) -> {
if (value != null) {
strBodyParamMap.put(key, (String)value);
}
});
}
return this.buildRequestBodyByMap(strBodyParamMap);
} else {
throw new RuntimeException("未知请求类型");
}
} else {
throw new Exception("请求头信息配置中无 Content-Type配置,请先配置");
}
}
private RequestBody buildRequestBodyByMap(Map<String, String> bodyParams) {
RequestBody body = null;
okhttp3.FormBody.Builder formEncodingBuilder = new okhttp3.FormBody.Builder();
if (bodyParams != null) {
Iterator<String> iterator = bodyParams.keySet().iterator();
String key = "";
while(iterator.hasNext()) {
key = (String)iterator.next();
formEncodingBuilder.add(key, (String)bodyParams.get(key));
log.info("okClient post表单提交请求参数:{},请求值:{} ", key, bodyParams.get(key));
}
}
body = formEncodingBuilder.build();
return body;
}
public String get(String url, Map<String, Object> headerMap) {
String responseStr = null;
try {
okhttp3.Request.Builder builder = (new okhttp3.Request.Builder()).get().url(url);
addHeaders(headerMap, builder);
Request request = builder.build();
Response response = okHttpClient.newCall(request).execute();
responseStr = response.body().string();
} catch (Exception var7) {
log.error("httpUtil 请求出错:{}", var7.getMessage(), var7);
}
return responseStr;
}
public String postByJson(String url, String body, Map<String, Object> headerMap) {
String responseStr = null;
try {
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), body);
okhttp3.Request.Builder requestBuilder = (new okhttp3.Request.Builder()).post(requestBody).url(url);
addHeaders(headerMap, requestBuilder);
Request request = requestBuilder.build();
Call call = okHttpClient.newCall(request);
Response response = call.execute();
responseStr = response.body().string();
} catch (Exception var10) {
log.error("httpUtil 请求出错:{}", var10.getMessage(), var10);
}
return responseStr;
}
public String postByForm(String url, Map<String, Object> bodyMap, Map<String, Object> headerMap) {
String responseStr = null;
try {
RequestBody body = this.setRequestBody(bodyMap, headerMap);
okhttp3.Request.Builder requestBuilder = (new okhttp3.Request.Builder()).post(body).url(url);
addHeaders(headerMap, requestBuilder);
Request request = requestBuilder.build();
Call call = okHttpClient.newCall(request);
Response response = call.execute();
responseStr = response.body().string();
} catch (Exception var10) {
log.error("httpUtil 请求出错:{}", var10.getMessage(), var10);
}
return responseStr;
}
public void postJsonAsync(String url, String json, final OKHttpUtil.MyNetCall myNetCall) throws IOException {
RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder();
Request request = requestBuilder.post(body).url(url).build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
public void onFailure(Call call, IOException e) {
myNetCall.failed(call, e);
}
public void onResponse(Call call, Response response) throws IOException {
myNetCall.success(call, response);
OKHttpUtil.getSemaphoreInstance().release();
}
});
try {
getSemaphoreInstance().acquire();
} catch (InterruptedException var9) {
var9.printStackTrace();
}
}
private static SSLSocketFactory createSSLSocketFactory(TrustManager[] trustAllCerts) {
SSLSocketFactory ssfFactory = null;
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init((KeyManager[])null, trustAllCerts, new SecureRandom());
ssfFactory = sc.getSocketFactory();
} catch (Exception var3) {
var3.printStackTrace();
}
return ssfFactory;
}
private static TrustManager[] buildTrustManagers() {
return new TrustManager[]{new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}};
}
public interface MyNetCall {
void success(Call call, Response response) throws IOException;
void failed(Call call, IOException e);
}
}
public final class ThreadPoolFactory {
private static final Logger LOGGER = LoggerFactory.getLogger(ThreadPoolFactory.class);
private static int SEND_MESSAGE_CORESIZE = 1;
private static int SEND_MESSAGE_MAXSIZE = 1;
private static int SEND_MESSAGE_KEEPALIVE = 120;
private static int SEND_MESSAGE_QUEUESIZE = 120;
public static ExecutorService createExecutorService(int coreNum, int maxNum) {
return new ThreadPoolExecutor(coreNum, maxNum, (long)SEND_MESSAGE_KEEPALIVE, TimeUnit.SECONDS, new ArrayBlockingQueue(SEND_MESSAGE_QUEUESIZE), new ThreadFactory("robotMessage", "SendErrorMessage"), new DiscardOldestPolicy());
}
private ThreadPoolFactory() {
}
static class MonitorRejectedExecutionHandler implements RejectedExecutionHandler {
MonitorRejectedExecutionHandler() {
}
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
if (!executor.isShutdown()) {
try {
executor.getQueue().put(r);
} catch (InterruptedException var4) {
ThreadPoolFactory.LOGGER.error("When task queue is full, some bad things happened! Message is {}", var4);
}
}
}
}
}
public abstract class AbstraceSendErrorMsgAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
private String appName;
private String messageChannel;
private String env;
private String sendEnabled;
public AbstraceSendErrorMsgAppender() {
}
public void append(ILoggingEvent event) {
if (event.getLevel() == Level.ERROR && "true".equals(this.sendEnabled)) {
try {
String userLogeErrorMessage = event.getFormattedMessage();
String stackTraceInfo = "";
IThrowableProxy proxy = event.getThrowableProxy();
if (null != proxy) {
Throwable t = ((ThrowableProxy)proxy).getThrowable();
stackTraceInfo = ThrowableUtils.getThrowableStackTrace(t);
}
String ip = MachineUtils.getHostIpFromDockerContainer();
if (stackTraceInfo.contains("OmsException") || stackTraceInfo.contains("WmsException") || stackTraceInfo.contains("BmsException")) {
return;
}
LocalDateTime dateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
String mesText = "服务名称:<font color=\"warning\">[" + this.appName + "]</font>,发生错误异常\n>ip:[" + ip + "]\n>环境信息:[" + this.env + "]\n>异常信息:[" + userLogeErrorMessage + "]\n>time:[" + dateTime.format(formatter) + "]\n堆栈信息:[\n" + stackTraceInfo + "]";
this.sendAlarmMessage("markdown", mesText);
} catch (Exception var9) {
System.out.println(String.format("日志报警异常,异常原因:{} last=%s", var9.getMessage()));
}
}
}
public String getAppName() {
return this.appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getMessageChannel() {
return this.messageChannel;
}
public void setMessageChannel(String messageChannel) {
this.messageChannel = messageChannel;
}
public String getEnv() {
return this.env;
}
public void setEnv(String env) {
this.env = env;
}
public String getSendEnabled() {
return this.sendEnabled;
}
public void setSendEnabled(String sendEnabled) {
this.sendEnabled = sendEnabled;
}
protected abstract void sendAlarmMessage(String messageType, String messageContent);
}
public class SendQiWeiAlarmErrorMessageAppender extends AbstraceSendErrorMsgAppender {
private static final Logger log = LoggerFactory.getLogger(SendQiWeiAlarmErrorMessageAppender.class);
private String webhookUrl;
private AlarmService alarmService;
public SendQiWeiAlarmErrorMessageAppender() {
}
protected void sendAlarmMessage(String messageType, String messageContent) {
Assert.hasText(this.webhookUrl, "机器人webHook地址不能为空");
if (null == this.alarmService) {
synchronized(this) {
if (null == this.alarmService) {
this.alarmService = new WechatAlarmServiceImpl(this.webhookUrl);
}
}
}
this.alarmService.alarmHandler(messageType, messageContent);
}
public String getWebhookUrl() {
return this.webhookUrl;
}
public void setWebhookUrl(String webhookUrl) {
this.webhookUrl = webhookUrl;
}
}
2.创建配置类
@ConfigurationProperties(
prefix = "message.robot"
)
public class RobotMessageAlarmMessageProperties {
private String enable;
public RobotMessageAlarmMessageProperties() {
}
public String getEnable() {
return this.enable;
}
public void setEnable(final String enable) {
this.enable = enable;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof RobotMessageAlarmMessageProperties)) {
return false;
} else {
RobotMessageAlarmMessageProperties other = (RobotMessageAlarmMessageProperties)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$enable = this.getEnable();
Object other$enable = other.getEnable();
if (this$enable == null) {
if (other$enable != null) {
return false;
}
} else if (!this$enable.equals(other$enable)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(final Object other) {
return other instanceof RobotMessageAlarmMessageProperties;
}
public int hashCode() {
int result = 1;
Object $enable = this.getEnable();
result = result * 59 + ($enable == null ? 43 : $enable.hashCode());
return result;
}
public String toString() {
return "RobotMessageAlarmMessageProperties(enable=" + this.getEnable() + ")";
}
}
@Configuration
@ConditionalOnProperty(
prefix = "message.robot",
name = {"enable"},
havingValue = "true",
matchIfMissing = false
)
@ConditionalOnClass(
name = {"ch.qos.logback.classic.LoggerContext"}
)
@EnableConfigurationProperties({RobotMessageAlarmMessageProperties.class})
@ComponentScan({"com.xrtframework.logback.alarm"})
public class LogbackAlarmAutoConfiguration {
private final RobotMessageAlarmMessageProperties robotMessageAlarmMessageProperties;
public LogbackAlarmAutoConfiguration(RobotMessageAlarmMessageProperties robotMessageAlarmMessageProperties) {
this.robotMessageAlarmMessageProperties = robotMessageAlarmMessageProperties;
}
}
public interface AlarmService {
void alarmHandler(String messageType, String messageContent);
}
public class WechatAlarmServiceImpl implements AlarmService {
private static final Logger log = LoggerFactory.getLogger(WechatAlarmServiceImpl.class);
private String webhookUrl;
private ExecutorService executorService;
private static final int coreThreadNum = 3;
private static final int maxThreadNum = 10;
private RateLimiter rateLimiter;
private static final Double rateLimiterPermitsPerSecond = 0.2857D;
public WechatAlarmServiceImpl(String webhookUrl) {
this.webhookUrl = webhookUrl;
this.executorService = ThreadPoolFactory.createExecutorService(3, 10);
this.rateLimiter = RateLimiter.create(rateLimiterPermitsPerSecond);
}
public void alarmHandler(String messageType, String messageContent) {
try {
this.rateLimiter.acquire();
this.executorService.execute(() -> {
QiWeiMessageContext qiWeiMessage = new QiWeiMessageContext();
qiWeiMessage.setContent(messageContent);
qiWeiMessage.setMentioned_list("@all");
QiWeiMarkDownMessage<QiWeiMessageContext> qiWeiMessageContextQiWeiMarkDownMessage = new QiWeiMarkDownMessage();
qiWeiMessageContextQiWeiMarkDownMessage.setMsgtype(messageType);
qiWeiMessageContextQiWeiMarkDownMessage.setMarkdown(qiWeiMessage);
if (log.isDebugEnabled()) {
log.debug("【企业微信机器人告警】消息请求入参:{}", JSON.toJSONString(qiWeiMessageContextQiWeiMarkDownMessage));
}
String response = OKHttpUtil.builder().postByJson(this.webhookUrl, JSON.toJSONString(qiWeiMessageContextQiWeiMarkDownMessage), (Map)null);
if (log.isDebugEnabled()) {
log.debug("【企业微信机器人告警】消息请出参:{}", response);
}
});
} catch (Exception var4) {
System.out.println(String.format("send wechat error last=%s", var4.getMessage()));
}
}
}
pom.properties
version=1.0-SNAPSHOT
groupId=com.xxframework
artifactId=xxframe-logback-alarm
spring-configuration-metadata.json
{
"groups": [
{
"name": "message.robot",
"type": "com.xxframework.logback.alarm.config.RobotMessageAlarmMessageProperties",
"sourceType": "com.xxframework.logback.alarm.config.RobotMessageAlarmMessageProperties"
}
],
"properties": [
{
"name": "message.robot.enable",
"type": "java.lang.String",
"sourceType": "com.xxframework.logback.alarm.config.RobotMessageAlarmMessageProperties"
}
],
"hints": []
}
3.pom依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--用来解决未配置spring boot 配置注解处理器IDEA告警-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.xrtframework</groupId>
<artifactId>xrtframe-common-util</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- <build>-->
<!-- <plugins>-->
<!-- <plugin>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
<!-- </plugin>-->
<!-- </plugins>-->
<!-- -->
<!-- </build>-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</build>
4.主工程引入工具包 pom依赖
<dependency>
<groupId>com.xxframework</groupId>
<artifactId>xxframe-logback-alarm</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--micrometer桥接prometheus-->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
5.主工程logback-spring.xml引入配置
<!--添加的内容-->
<springProperty scope="context" name="robotMessageChannel" source="message.robot.channel" defaultValue="QI_WEI"/>
<springProperty scope="context" name="robotMessageEnv" source="message.robot.env" defaultValue=""/>
<springProperty scope="context" name="robotMessageWebHookUrl" source="message.robot.webhookUrl" defaultValue=""/>
<!--添加的内容-->
<appender name="sendErrorMsg" class="com.xrtframework.logback.alarm.core.SendQiWeiAlarmErrorMessageAppender">
<!--使用该组件的应用名称 -->
<appName>${springAppName}</appName>
<messageChannel>${robotMessageChannel}</messageChannel>
<env>${robotMessageEnv}</env>
<webhookUrl>${robotMessageWebHookUrl}</webhookUrl>
</appender>
6.nacos配置
#应用日志监控
message.robot.sendEnabled=true
message.robot.channel=QI_WEI
message.robot.env=测试环境
message.robot.webhookUrl=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=XXX