• Spring Boot Admin 集成自定义监控告警


    Spring Boot Admin 集成自定义监控告警

    前言

    Spring Boot Admin 是一个社区项目,可以用来监控和管理 Spring Boot 应用并且提供 UI,详细可以参考 官方文档

    Spring Boot Admin 本身提供监控告警功能,但是默认只提供了 Hipchat、Slack 等国外流行的通讯软件的集成,虽然也有邮件通知,不过考虑到使用体检决定二次开发增加 钉钉 通知。

    本文基于 Spring Boot Admin 目前最新版 1.5.7。

    准备工作

    1. Spring Boot Admin Server,参考文档 http://codecentric.github.io/spring-boot-admin/1.5.7/#getting-started
    2. 钉钉自定义机器人,参考文档 https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq

    参考自带通知源码

    由于官方文档上并没有增加自定义通知相关的文档,所以我们参考一下 Slack 通知源码 SlackNotifier.java

    源码比较长就不全部贴了,看一下关键部分:

    public class SlackNotifier extends AbstractStatusChangeNotifier
    
    protected void doNotify(ClientApplicationEvent event) throws Exception {
        this.restTemplate.postForEntity(this.webhookUrl, this.createMessage(event), Void.class);
    }
    

    可以看到流程还是比较简单的,继承 AbstractStatusChangeNotifier 类,实现了 doNotify 方法,当应用状态改变的时候会回调 doNotify 方法。

    实现钉钉通知

    DingTalkNotifier.java

    public class DingTalkNotifier extends AbstractStatusChangeNotifier {
        private final SpelExpressionParser parser = new SpelExpressionParser();
        private RestTemplate restTemplate = new RestTemplate();
        private String webhookToken;
        private String atMobiles;
        private String msgtype = "markdown";
        private String title = "服务告警";
        private Expression message;
    
        public DingTalkNotifier() {
            this.message = this.parser.parseExpression("**#{application.name}** (#{application.id}) is **#{to.status}**", ParserContext.TEMPLATE_EXPRESSION);
        }
    
        @Override
        protected void doNotify(ClientApplicationEvent event) {
            this.restTemplate.postForEntity(this.webhookToken, this.createMessage(event), Void.class);
        }
    
        private HttpEntity<Map<String, Object>> createMessage(ClientApplicationEvent event) {
            Map<String, Object> messageJson = new HashMap<>();
            HashMap<String, String> params = new HashMap<>();
            params.put("text", this.getMessage(event));
            params.put("title", this.title);
            messageJson.put("dinggroup", this.dingGroup);
            messageJson.put("atMobiles", this.atMobiles);
            messageJson.put("msgtype", this.msgtype);
            messageJson.put(this.msgtype, params);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
            return new HttpEntity<>(messageJson, headers);
        }
    
        private String getAtMobilesString(String s) {
            StringBuilder atMobiles = new StringBuilder();
            String[] mobiles = s.split(",");
            for (String mobile : mobiles) {
                atMobiles.append("@").append(mobile);
            }
            return atMobiles.toString();
        }
    
        private String getMessage(ClientApplicationEvent event) {
            return this.atMobiles == null ? this.message.getValue(event, String.class) : this.message.getValue(event, String.class) + "
     >" + this.getAtMobilesString(this.atMobiles);
        }
    
        public void setRestTemplate(RestTemplate restTemplate) {
            this.restTemplate = restTemplate;
        }
    
        public String getWebhookToken() {
            return webhookToken;
        }
    
        public void setWebhookToken(String webhookToken) {
            this.webhookToken = webhookToken;
        }
    
        public String getAtMobiles() {
            return atMobiles;
        }
    
        public void setAtMobiles(String atMobiles) {
            this.atMobiles = atMobiles;
        }
    
        public String getMsgtype() {
            return msgtype;
        }
    
        public void setMsgtype(String msgtype) {
            this.msgtype = msgtype;
        }
    
        public Expression getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = this.parser.parseExpression(message, ParserContext.TEMPLATE_EXPRESSION);
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    }
    

    代码逻辑也比较简单就不一一解释了。

    增加钉钉通知自动配置

    DingTalkNotifierConfiguration.java

    @Configuration
    @ConditionalOnProperty(
            prefix = "spring.boot.admin.notify.dingtalk",
            name = {"webhook-token"}
    )
    @AutoConfigureBefore({NotifierConfiguration.NotifierListenerConfiguration.class, NotifierConfiguration.CompositeNotifierConfiguration.class})
    public class DingTalkNotifierConfiguration {
        public DingTalkNotifierConfiguration() {
        }
    
        @Bean
        @ConditionalOnMissingBean
        @ConfigurationProperties(prefix = "spring.boot.admin.notify.dingtalk")
        public DingTalkNotifier dingTalkNotifier() {
            return new DingTalkNotifier();
        }
    
    }
    
    

    大概解释下此配置类的主要作用:

    1. 当配置了 spring.boot.admin.notify.dingtalk.webhook-token 的时候此配置类生效。
    2. spring.boot.admin.notify.dingtalk 下的配置注入到 DingTalkNotifier 生成的 Bean 中。
    3. 指定了此配置配生效的时间以及 Bean 生效的条件。

    关键在于类和 Bean 上的几个注解,但这不是本文重点不展开说了。

    增加相关配置

    spring:
      boot:
        admin:
          notify:
            dingtalk:
              enabled: true
              webhook-token: https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxx
    
    

    然后当项目状态改变的时候就可以在钉钉收到消息了。

  • 相关阅读:
    [读书笔记]SQLSERVER企业级平台管理实践读书笔记--从等待事件判断性能瓶颈
    Docker machine学习
    不同数据库连接字符串的网站
    Windows 可以操纵linux内文件,与本地一致的工具
    OpenSSH 安全漏洞(CVE-2021-28041)修复(升级OpenSSH至最新版本(8.6p1))
    PostgreSQL
    firewalld添加/删除服务service,端口port
    PostgreSQL 序列操作
    PostgreSQL/pgsql 为表添加列/ 判断列存不存在再添加列
    Windows10中Power Shell(x64)出现“无法加载 PSReadline 模块。控制台在未使用 PSReadline 的情况下运行。”的解决办法
  • 原文地址:https://www.cnblogs.com/bbling/p/9060308.html
Copyright © 2020-2023  润新知