11. 告警机制
11.2.3 WebHook 实践
这里搞一个接口,接受告警信息,实践一下,将 yml 文件中的 urls 该成 对应接口:
yml
hooks:
webhook:
default:
is-default: true
urls:
- http://127.0.0.1:8084/alarm/handler
创建对应的alarm-service 服务:
AlarmMessage 类:对应之前文章中告警信息的内容,用作参数接收
java
package com.example.alarm.entity;
import lombok.Data;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Data
public class AlarmMessage {
private int scopeId;
private String scope;
private String name;
private String id0;
private String id1;
private String ruleName;
private String alarmMessage;
private List<Tag> tags;
private long startTime;
private transient int period;
private Set<String> hooks = new HashSet<>();
private String expression;
@Data
public static class Tag{
private String key;
private String value;
}
}
AlarmController 类:定义 webhook 中的目的接口
java
package com.example.alarm.controller;
import com.example.alarm.entity.AlarmMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Slf4j
@RequestMapping("/alarm")
@RestController
public class AlarmController {
@RequestMapping("/handler")
public String handler(@RequestBody List<AlarmMessage> alarmMessages){
log.info("收到报警, alarmMessages:{}", alarmMessages);
return "接收报警成功";
}
}
触发告警后:
cmd
17:03:35.622 INFO 15104 --- [nio-8084-exec-1]
c.example.alarm.controller.AlarmController :
收到报警, alarmMessages:[AlarmMessage(scopeId=6, scope=ENDPOINT_RELATION, name=User in User to GET:/order/query/9 in order-service, id0=VXNlcg==.0_VXNlcg==, id1=b3JkZXItc2VydmljZQ==.1_R0VUOi9vcmRlci9xdWVyeS85, ruleName=endpoint_relation_resp_time_rule, alarmMessage=Response time of endpoint relation User in User to GET:/order/query/9 in order-service is more than 1000ms in 2 minutes of last 10 minutes, tags=[], startTime=1765443815049, period=0, hooks=[webhook.default], expression=sum(endpoint_relation_resp_time > 1000) >= 2)]
11.2.4 接入邮箱
11.2.4.1 引入依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
11.2.4.2 添加配置文件
yml
spring:
mail:
host: smtp.qq.com #需要在设置中开启 smtp
username: #发件⼈的邮箱
password: #邮箱的授权码, 并⾮个⼈密码
default-encoding: UTF-8 #字符集编码, 默认 UTF-8
port: 587
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
"personal": "程序告警系统"
"subject": "告警通知"
11.2.4.3 Mail 工具类 及 Mail引入程序
java
package com.bite.alarm.mail;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class Mail {
@Autowired //获取 .yml 文件中的配置信息
private MailProperties mailProperties;
@Autowired
private JavaMailSender javaMailSender;
public void send(String to, String content) {
try {
// 创建⼀个邮件消息
MimeMessage message = javaMailSender.createMimeMessage();
// 创建 MimeMessageHelper
MimeMessageHelper helper = new MimeMessageHelper(message, false);
//发件人邮箱,姓名
helper.setFrom(mailProperties.getUsername(), mailProperties.getProperties().getOrDefault("personal",mailProperties.getUsername()));
// 收件⼈邮箱
helper.setTo(to);
// 邮件标题
helper.setSubject(mailProperties.getProperties().getOrDefault("subject","告警通知"));
// 邮件正⽂,第⼆个参数表⽰是否是HTML正⽂
helper.setText(content,true);
// 发送
javaMailSender.send(message);
} catch (Exception e) {
log.error("邮件发送失败,e: ",e);
}
}
}
MailProperties 是 spring-boot-starter-mail 中的一个工具类,用于读取配置文件中的相关信息
java
package com.bite.alarm.controller;
import com.bite.alarm.entity.AlarmMessage;
import com.bite.alarm.mail.Mail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Slf4j
@RequestMapping("/alarm")
@RestController
public class AlarmController {
@Autowired
private Mail mail;
@RequestMapping("/handler")
public String handler(@RequestBody List<AlarmMessage> alarmMessages){
log.info("收到报警, alarmMessages:{}", alarmMessages);
mail.send("收件人邮箱",buildContent(alarmMessages));
return "接收报警成功";
}
private String buildContent(List<AlarmMessage> alarmMessages) {
StringBuilder content = new StringBuilder();
content.append("收到报警, 报警信息如下: <br/>");
for (AlarmMessage alarmMessage : alarmMessages) {
content.append("scopeId:").append(alarmMessage.getScopeId()).append("<br/>");
content.append("scope:").append(alarmMessage.getScope()).append("<br/>");
content.append("name:").append(alarmMessage.getName()).append("<br/>");
content.append("id0:").append(alarmMessage.getId0()).append("<br/>");
content.append("id1:").append(alarmMessage.getId1()).append("<br/>");
content.append("ruleName:").append(alarmMessage.getRuleName()).append("<br/>");
content.append("alarmMessage:").append(alarmMessage.getAlarmMessage()).append("<br/>");
content.append("tags:").append(alarmMessage.getTags()).append("<br/>");
content.append("startTime:").append(alarmMessage.getStartTime()).append("<br/>");
content.append("period:").append(alarmMessage.getPeriod()).append("<br/>");
content.append("hooks:").append(alarmMessage.getHooks()).append("<br/>");
content.append("expression:").append(alarmMessage.getExpression()).append("<br/>");
}
return content.toString();
}
// @RequestMapping("/handler")
// public String handler(@RequestBody List<AlarmMessage> alarmMessages){
// log.info("收到报警, alarmMessages:{}", alarmMessages);
// return "接收报警成功";
// }
}
收到告警通知如下:

11.2.5 接入飞书
向飞书发送告警信息(让人也可是其他,具体参考:官网链接 )
11.2.5.1 注册飞书
注册好后,在通讯录中创建群组

进入群组,右上角设置添加机器人

选择自定义机器人

保存webhook链接,已经签名(可以不勾选签名校验)

接着修改 skywalking 中webhook的配置:
yml
hooks:
feishu:
default:
is-default: true
text-template: |
{
"msg_type":"text",
"content": {
"text": "Apache SkyWalking Alarm: \n %s."
}
}
webhooks:
- url: #你的飞书的webhook 地址
secret: #签名校验码,之前没有勾选,则不用该字段
重启,skywalking 进行测试,结果如下:
