Java中的SkyWalking監(jiān)控告警詳解
SkyWalking監(jiān)控告警
SkyWalking在6.x版本中新增了告警功能,其核心在于config/alarm-settings.yaml文件中,該文件分為rules和webhooks兩部分。
rules用于定義告警的條件,webhook則用于定于告警觸發(fā)時(shí),需要通知哪些服務(wù)。
告警規(guī)則配置項(xiàng)的說明:
- **Rule name:**規(guī)則名稱,也是在告警信息中顯示的唯一名稱。必須以_rule結(jié)尾,前綴可自定義
- **Metrics name:**度量名稱,取值為oal腳本中的度量名,目前只支持long、double和int類型。詳見 Official OAL script
- **Include names:**該規(guī)則作用于哪些實(shí)體名稱,比如服務(wù)名,終端名(可選,默認(rèn)為全部)
- **Exclude names:**該規(guī)則作不用于哪些實(shí)體名稱,比如服務(wù)名,終端名(可選,默認(rèn)為空)
- **Threshold:**閾值
- OP: 操作符,目前支持 >、<、=
- **Period:**多久告警規(guī)則需要被核實(shí)一下。這是一個(gè)時(shí)間窗口,與后端部署環(huán)境時(shí)間相匹配
- **Count:**在一個(gè)Period窗口中,如果values超過Threshold值(按op),達(dá)到Count值,需要發(fā)送警報(bào)
- **Silence period:**在時(shí)間N中觸發(fā)報(bào)警后,在TN -> TN + period這個(gè)階段不告警。 默認(rèn)情況下,它和Period一樣,這意味著相同的告警(在同一個(gè)Metrics name擁有相同的Id)在同一個(gè)Period內(nèi)只會(huì)觸發(fā)一次
- **message:**告警消息
webhook會(huì)在觸發(fā)告警時(shí),向配置的地址發(fā)送http POST請(qǐng)求,并將Content-Type為application/json,也就是說會(huì)發(fā)送json格式的POST請(qǐng)求。
webhooks發(fā)送的字段包含
- **scopeId、scope
- **name:**目標(biāo) Scope 的實(shí)體名稱
- **id0:**Scope 實(shí)體的 ID
- **id1:**保留字段,目前暫未使用
- **ruleName:**告警規(guī)則名稱
- **alarmMessage:**告警消息內(nèi)容
- **startTime:**告警時(shí)間,格式為時(shí)間戳
- **tags:**alarm-settings.yml中配置的tags
具體字段類型可以參考官方定義的AlarmMessage
由于郵件系統(tǒng)之前的通訊方式都是基于MQ進(jìn)行的,所以需要定義一個(gè)Controller,用于接收Skywalking的請(qǐng)求,官方給出的請(qǐng)求數(shù)據(jù)示例為
[{ "scopeId": 1, "scope": "SERVICE", "name": "serviceA", "id0": "12", "id1": "", "ruleName": "service_resp_time_rule", "alarmMessage": "alarmMessage xxxx", "startTime": 1560524171000, "tags": [{ "key": "level", "value": "WARNING" }] }, { "scopeId": 1, "scope": "SERVICE", "name": "serviceB", "id0": "23", "id1": "", "ruleName": "service_resp_time_rule", "alarmMessage": "alarmMessage yyy", "startTime": 1560524171000, "tags": [{ "key": "level", "value": "CRITICAL" }] }]
所以可以定義接口為
@PostMapping("/skywalking/alarm") public void alarm(@RequestBody List<SkyWalkingAlarmMessage> alarmList) { ...... ...... }
接收到數(shù)據(jù)之后,如果不為空,就可以組裝郵件發(fā)送給配置的相關(guān)開發(fā)或運(yùn)維人員。
定義SkyWalking郵件的相關(guān)配置
@Data @RefreshScope @Configuration @ConfigurationProperties(prefix = "alarm") public class AlarmMailConfig { private AlarmMailInfo skyWalking; @Data public static class AlarmMailInfo{ /** * 發(fā)件昵稱 */ private String nickName; /** * 收件地址 */ private List<String> toAddress; /** * 是否轉(zhuǎn)義告警字段 */ private boolean translateField = true; } }
定義告警字段的中文映射
enum Mapping{ scopeId("scopeId"), scope("scope"), name("目標(biāo)Scope的實(shí)體名稱"), id0("Scope實(shí)體的ID"), id1("id1"), ruleName("警告規(guī)則名稱"), alarmMessage("告警消息內(nèi)容"), startTime("告警時(shí)間"), tags("tags") ; private String fieldName; Mapping(String fieldName) { this.fieldName = fieldName; } private static final Map<String,String> cacheMap = Arrays.stream(Mapping.values()).collect(Collectors.toMap(Enum::name, e->e.fieldName)); }
定義SkyWalking的處理Controller
@Slf4j @RestController public class AlarmMailController { // 時(shí)間格式化pattern public static final String TIME_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS"; // 發(fā)送郵件Service @Autowired private SendMailService sendMailService; // 告警郵件配置 @Autowired private AlarmMailConfig alarmMailConfig; // 通過反射獲取請(qǐng)求字段的字段名 private final List<String> skyWalkingAlarmMessageFieldName = ReflectUtils.getAllNoStaticFieldList(SkyWalkingAlarmMessage.class).stream().map(Field::getName) .collect(Collectors.toList()); @PostMapping("/skywalking/alarm") public void alarm(@RequestBody List<SkyWalkingAlarmMessage> alarmList) { log.info("接收到skywalking監(jiān)控調(diào)用"); if (CollectionUtil.isEmpty(alarmList)) { log.info("監(jiān)控調(diào)用為空"); return; } SendMailRequest sendMailRequest = fillSkyWalkingMailRequest(alarmList); sendMailService.sendCustomizeMail(sendMailRequest); } private SendMailRequest fillSkyWalkingMailRequest(List<SkyWalkingAlarmMessage> alarmList) { SendMailRequest sendMailRequest = new SendMailRequest(); // 設(shè)置主題 sendMailRequest.setSubject("SkyWalking監(jiān)控郵件"); // 定義請(qǐng)求的系統(tǒng) sendMailRequest.setSystemMark("SkyWalking"); sendMailRequest.setRequestTime(LocalDateTime.now()); AlarmMailConfig.AlarmMailInfo skyWalkingConfig = alarmMailConfig.getSkyWalking(); // 發(fā)件人昵稱 sendMailRequest.setSenderNickname(skyWalkingConfig.getNickName()); // 收件人地址 sendMailRequest.setToAddress(skyWalkingConfig.getToAddress()); // 郵件主題是否為html格式 sendMailRequest.setHtmlText(true); // 添加默認(rèn)的免責(zé)聲明 sendMailRequest.setAddDefaultDisclaimer(true); // 生成郵件正文 String mailBody = fillSkyWalkingAlarmMessage(alarmList); sendMailRequest.setContentText(mailBody); return sendMailRequest; } private String fillSkyWalkingAlarmMessage(List<SkyWalkingAlarmMessage> alarmList) { AlarmMailConfig.AlarmMailInfo skyWalkingConfig = alarmMailConfig.getSkyWalking(); String mailBody = alarmList.stream().map(message -> skyWalkingAlarmMessageFieldName.stream().map(field -> { Object value; // 如果參數(shù)是startTime if (StringUtils.equals(field, "startTime")) { Long startTime = message.getStartTime(); // 如果為空 if (startTime == null) { // 展示數(shù)據(jù)為空 value = StringUtils.EMPTY; } else { // 否則進(jìn)行格式化便于展示 value = DateUtils.format(DateUtils.getDate(startTime), TIME_PATTERN); } // 如果是tags字段 } else if (StringUtils.equals(field, "tags")) { List<SkyWalkingAlarmMessage.Tag> tags = message.getTags(); if (CollectionUtil.isEmpty(tags)) { value = StringUtils.EMPTY; } else { // 進(jìn)行拼接 value = tags.stream().map(v -> v.getKey() + ":" + v.getValue()) .collect(Collectors.joining("; ", "[", "]")); } } else { // 直接獲取屬性值 value = ReflectUtils.getFieldValue(message, field); } // 是否需要翻譯告警字段 boolean translateField = skyWalkingConfig.isTranslateField(); if (translateField){ // 拼接翻譯字段的和對(duì)應(yīng)的值 return SkyWalkingAlarmMessage.getFieldName(f) + ":" + value; }else { // 拼接字段和對(duì)應(yīng)的值 return f + ":" + value; } }).collect(Collectors.joining(" "))).collect(Collectors.joining(" <HR> ")); return mailBody; } }
到此這篇關(guān)于Java中的SkyWalking監(jiān)控告警詳解的文章就介紹到這了,更多相關(guān)SkyWalking監(jiān)控告警內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中使用MyBatis-Plus詳細(xì)步驟
MyBatis-Plus是MyBatis的增強(qiáng)工具,簡化了MyBatis的使用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2025-01-01打開.properties中文顯示unicode編碼問題以及解決
這篇文章主要介紹了打開.properties中文顯示unicode編碼問題以及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01Springboot集成Mybatis-plus、ClickHouse實(shí)現(xiàn)增加數(shù)據(jù)、查詢數(shù)據(jù)功能
本文給大家講解Springboot + mybatis-plus 集成ClickHouse,實(shí)現(xiàn)增加數(shù)據(jù)、查詢數(shù)據(jù)功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-08-08關(guān)于SpringSecurity簡介以及和Shiro的區(qū)別
這篇文章主要介紹了關(guān)于SpringSecurity簡介以及和Shiro的區(qū)別,在Java應(yīng)用安全領(lǐng)域,Spring Security會(huì)成為被首先推崇的解決方案,就像我們看到服務(wù)器就會(huì)聯(lián)想到Linux一樣順理成章,需要的朋友可以參考下2023-07-07