Spring Boot Admin 集成自定義監控告警
前言
Spring Boot Admin 是一個社區項目,可以用來監控和管理 Spring Boot 應用並且提供 UI,詳細可以參考 官方文檔。
Spring Boot Admin 本身提供監控告警功能,但是默認只提供了 Hipchat、Slack 等國外流行的通訊軟件的集成,雖然也有郵件通知,不過考慮到使用體檢決定二次開發增加 釘釘 通知。
本文基於 Spring Boot Admin 目前最新版 1.5.7。
准備工作
- Spring Boot Admin Server,參考文檔 http://codecentric.github.io/spring-boot-admin/1.5.7/#getting-started
- 釘釘自定義機器人,參考文檔 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) + "\n >" + 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();
}
}
大概解釋下此配置類的主要作用:
- 當配置了
spring.boot.admin.notify.dingtalk.webhook-token
的時候此配置類生效。 - 將
spring.boot.admin.notify.dingtalk
下的配置注入到DingTalkNotifier
生成的 Bean 中。 - 指定了此配置配生效的時間以及 Bean 生效的條件。
關鍵在於類和 Bean 上的幾個注解,但這不是本文重點不展開說了。
增加相關配置
spring:
boot:
admin:
notify:
dingtalk:
enabled: true
webhook-token: https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxx
然后當項目狀態改變的時候就可以在釘釘收到消息了。