美文网首页Spring boot
sentry告警之webhook

sentry告警之webhook

作者: 天草二十六_简村人 | 来源:发表于2021-08-31 20:20 被阅读0次

    一、背景

    sentry告警支持自定义插件,但是最新的版本(21.8.0)默认只集成了webhook,没有了企业微信,更无法支持钉钉。所以我们要实现其他的告警方式,比如短信、电话等其他方式,可以接收它的回调字段以扩展多种消息通知方式。

    二、sentry的设置

    1、增加告警渠道

    step-1.png step-2.png step3.png

    2、新增告警规则

    step-1.png step-2.png

    到这里,sentry的设置就已完成。
    接下来就是要实现webhook,接收并解析回调信息,然后调用企业微信、SMS等渠道发送给对应的用户。

    三、webhoook实现

    1、回调字段

    可以自己写一个post的urimapping,将其完整打印,详见下面的java示例代码。


    第一层.png
    event明细.png
        @PostMapping("/api/msg/callback")
        @ResponseBody
        public String notify(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String requestResultJson = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
            if (log.isInfoEnabled()) {
                log.info("回调报文内容是:{}", requestResultJson);
            }
            Map<String, Object> resultMap = JSON.parseObject(requestResultJson, HashMap.class);
    
           // 自定义的扩展字段,也就是写在?后面的字段
           String group = request.getParameter("group");
        }
    
    

    2、拼接消息内容

    2.1、接口

    public interface SentryWebhookService {
        String APPLICATION_ID = "operation";
    
        String DEFAULT_GROUP = "trade";
    
        String MSG_SUBJECT = "sentry报警";
    
        String MSG_TEMPLATE = "**${projectName}** --- ${environment}环境下出现<font color=\"warning\">告警</font>,需要及时跟进!! \n" +
                "> 版 本  : **${release}** \n" +
                "> \n" +
                "> 时 间  : <font color=\"info\">${timestamp}</font> \n" +
                "> \n" +
                "> URL   : **${culprit}** \n" +
                "> \n" +
                "> Log类  : **${logger}** \n" +
                "> \n" +
                "> 详 情 :[${message}](${url}) \n " +
                "> \n" +
                "> [如无法点击,请复制网址: `${url}]`\n";
    
        /**
         * 解析sentry回调信息
         *
         * @param sentryAlertsRequest
         * @return
         */
        Map<String, String> parseNotify(String sentryAlertsRequest);
    }
    

    2.2、实现类

    @Slf4j
    @Service
    public class SentryWebhookServiceImpl implements SentryWebhookService {
    
        @Override
        public Map<String, String> parseNotify(String sentryAlertsRequest) {
            JSONObject jsonObject = JSON.parseObject(sentryAlertsRequest);
    
            Map<String, String> paramMap = Maps.newHashMap();
            paramMap.put("projectName", jsonObject.getString("project_name"));
            paramMap.put("level", jsonObject.getString("level"));
            paramMap.put("culprit", jsonObject.getString("culprit"));
            paramMap.put("message", jsonObject.getString("message"));
            paramMap.put("logger", jsonObject.getString("logger"));
            paramMap.put("url", jsonObject.getString("url"));
    
            // 解析event中的时间戳,环境以及版本号
            JSONObject eventObject = jsonObject.getJSONObject("event");
    
            BigDecimal timestamp = new BigDecimal(eventObject.getString("timestamp"));
            paramMap.put("timestamp", String.valueOf(DateUtils.ofEpochSecond(timestamp.longValue())));
    
            paramMap.put("environment", eventObject.getString("environment"));
            paramMap.put("release", eventObject.getString("release"));
    
            return paramMap;
        }
    
    }
    

    2.3、工具类

    @Slf4j
    public class MessageTemplateUtil {
    
        public static String parseTemplate(String content, Map<String, String> paramMap) {
            try {
                for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                    String regex = "\\$\\{" + entry.getKey() + "\\}";
    
                    Pattern pattern = Pattern.compile(regex);
    
                    Matcher matcher = pattern.matcher(content);
    
                    content = matcher.replaceAll(entry.getValue());
                }
            } catch (Exception e) {
                log.error("解析消息模板出现异常, content={}, paramMap={}", content, JSON.toJSON(paramMap), e);
            }
            return content;
        }
    }
    
    

    2.4、spring mvc

    @Slf4j
    @Api(value = "sentry回调", tags = "sentry回调")
    @RestController
    public class SentryCallbackFacade {
        @Autowired
        private MessageService messageService;
    
        @Autowired
        private SentryWebhookService sentryWebhookService;
    
        @PostMapping(value = "/api/sentry/notify")
        public ResponseEntity<?> sentryNotify(HttpServletRequest request, HttpServletResponse response)
                throws Exception {
            // 回调内容,调试阶段,你通过log.info()打印输出
            String sentryAlertsRequestJson = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
            log.debug(sentryAlertsRequestJson);
            // 从回调字段里抽取消息内容需要的字段 
            Map<String, String> paramMap = sentryWebhookService.parseNotify(sentryAlertsRequestJson);
            // 接收消息的群组
            String group = request.getParameter("group");
            // 拼接消息内容
            final String payload = MessageTemplateUtil.parseTemplate(SentryWebhookService.MSG_TEMPLATE, paramMap);
            // 发送消息
            messageService.deliverMessage();
    
            return ResponseEntity.noContent().build();
        }
    
    }
    

    3、调用消息渠道

    可以是短信、企业微信等渠道,具体不在本文的介绍中。
    对应上面的messageService.deliverMessage()

    相关文章

      网友评论

        本文标题:sentry告警之webhook

        本文链接:https://www.haomeiwen.com/subject/shzziltx.html