springboot项目编写发送异常日志到企微工具包

发布于:2024-09-18 ⋅ 阅读:(36) ⋅ 点赞:(0)

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