前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Grafana 告警接入飞书通知

Grafana 告警接入飞书通知

作者头像
阿提说说
发布2023-01-14 09:21:50
3.5K0
发布2023-01-14 09:21:50
举报
文章被收录于专栏:Java技术进阶Java技术进阶

Grafana 系列文章,版本:OOS v9.3.1

  1. Grafana 的介绍和安装
  2. Grafana监控大屏配置参数介绍(一)
  3. Grafana监控大屏配置参数介绍(二)
  4. Grafana监控大屏可视化图表
  5. Grafana 查询数据和转换数据
  6. Grafana 告警模块介绍
  7. Grafana 告警接入飞书通知

前言

我们已经知道Grafana 已经支持了钉钉、邮件等告警,钉钉能够打入Grafana 跟阿里重视开源也有关系,在Grafana的GitHub上,很早也有人提过这样的PR。

他们希望Grafana能够集成飞书,但被Grafana团队拒绝了,原因是:当时飞书通知的需求不够强烈。

不过没事,没有原生集成,我们还可以使用万能的webHook,通过中转服务内部转换参数后再发送到飞书。

创建告警规则

为了测试,数据源使用Grafana 的Test DB,新创建一个规则。

从Random Walk 类型的图表中查询数据,当数据最大值大于10的时候,发生告警,每1分钟评估一次,如果持续2分钟都符合告警条件,将生成一条告警。

这里表示告警关联的大屏和图表面板,还有一个描述字段

配置WebHook通知

这里为了测试,只填写一个接收地址,没有鉴权,外网环境必须要加鉴权

另外由于Grafana 使用Docker 部署,中转服务部署在本地物理机,如果填127.0.0.1,Docker 内部是无法访问到的,需要填物理机的局域网IP

配置告警策略

最后需要配置一个告警的策略,这边为了测试,时间都配的比较短,Mute timings 是不告警时间配置,可以不设。

部署中转服务

如下这段是中转服务接收到的webHook告警内容。

代码语言:javascript
复制
{
	"receiver": "feishu",
	"status": "resolved",
	"alerts": [{
		"status": "resolved",
		"labels": {
			"alertname": "Simple dummy streaming example",
			"grafana_folder": "test"
		},
		"annotations": {
			"description": "测试大屏告警"
		},
		"startsAt": "2023-01-12T14:46:00Z",
		"endsAt": "2023-01-12T15:07:00Z",
		"generatorURL": "http://localhost:3000/alerting/grafana/zgbSUF24z/view?orgId=1",
		"fingerprint": "09b095c0ac5a31bc",
		"silenceURL": "http://localhost:3000/alerting/silence/new?alertmanager=grafana\u0026matcher=alertname%3DSimple+dummy+streaming+example\u0026matcher=grafana_folder%3Dtest",
		"dashboardURL": "http://localhost:3000/d/TXSTREZ?orgId=1",
		"panelURL": "http://localhost:3000/d/TXSTREZ?orgId=1\u0026viewPanel=2",
		"values": null,
		"valueString": ""
	}],
	"groupLabels": {
		"alertname": "Simple dummy streaming example"
	},
	"commonLabels": {
		"alertname": "Simple dummy streaming example",
		"grafana_folder": "test"
	},
	"commonAnnotations": {
		"description": "测试大屏告警"
	},
	"externalURL": "http://localhost:3000/",
	"version": "1",
	"groupKey": "{}/{}:{alertname=\"Simple dummy streaming example\"}",
	"truncatedAlerts": 0,
	"orgId": 1,
	"title": "[RESOLVED] Simple dummy streaming example (test)",
	"state": "ok",
	"message": "**Resolved**\n\nValue: [no value]\nLabels:\n - alertname = Simple dummy streaming example\n - grafana_folder = test\nAnnotations:\n - description = 测试大屏告警\nSource: http://localhost:3000/alerting/grafana/zgbSUF24z/view?orgId=1\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana\u0026matcher=alertname%3DSimple+dummy+streaming+example\u0026matcher=grafana_folder%3Dtest\nDashboard: http://localhost:3000/d/TXSTREZ?orgId=1\nPanel: http://localhost:3000/d/TXSTREZ?orgId=1\u0026viewPanel=2\n"
}

上面的字段也很好理解,我们将上面的字段解析封装成飞书的通知格式就可以往飞书发送通知了。

我们根据之前的代码,简单调整封装一下。

AlarmMessage.java 告警接口

代码语言:javascript
复制
public interface AlarmMessage {

    /**
     * 发送文本告警
     * @param content
     */
    void sendData(String content);
}

FeiShuNotifier.java 飞书发送告警代码

代码语言:javascript
复制
@Service
public class FeiShuNotifier implements AlarmMessage {

	private static final String DEFAULT_MESSAGE = " 告警标题:#{title} \n 告警描述:#{description} \n 面板URL:#{panelUrl} \n 发生时间:#{startTime}";

	private final SpelExpressionParser parser = new SpelExpressionParser();

	@Value("${feishu.webhook-url}")
	private String webhookUrl;

	@Value("${feishu.secret}")
	private String secret;

	private Expression message = parser.parseExpression(DEFAULT_MESSAGE, ParserContext.TEMPLATE_EXPRESSION);

	private RestTemplate restTemplate = new RestTemplate();

	@Override
	public void sendData(String content) {
		Map<String, Object> message = createMessage(getText(content));
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_JSON);
		restTemplate.postForEntity(webhookUrl, new HttpEntity<>(message, headers), Void.class);
	}


	/**
	 * 构建通知报文
	 * @param content
	 * @return
	 */
	protected Map<String, Object> createMessage(String content) {
		Map<String, Object> messageJson = new HashMap<>();
		messageJson.put("msg_type", "text");

		Map<String, Object> text = new HashMap<>();
		text.put("text", content);
		messageJson.put("content", text);
		Long timestamp = System.currentTimeMillis() / 1000;
		messageJson.put("timestamp", timestamp);
		messageJson.put("sign", getSign(timestamp));

		return messageJson;
	}

	/**
	 * 构建文本内容
	 * @param body
	 * @return
	 */
	private String getText(String body) {
		JSONObject json = JSON.parseObject(body);
		Map<String, Object> root = new HashMap<>();
		root.put("title", json.getString("title"));
		root.put("description", json.getJSONObject("commonAnnotations").getString("description"));
		JSONObject alertObject = json.getJSONArray("alerts").getJSONObject(0);
		root.put("panelUrl", alertObject.getString("panelURL"));
		root.put("startTime", DateUtil.parseUTC(alertObject.getString("startsAt")).toString(TimeZone.getDefault()));
		StandardEvaluationContext context = new StandardEvaluationContext(root);
		context.addPropertyAccessor(new MapAccessor());
		return message.getValue(context, String.class);
	}

	private String getSign(Long timestamp) {
		try {
			String stringToSign = timestamp + "\n" + secret;
			Mac mac = Mac.getInstance("HmacSHA256");
			mac.init(new SecretKeySpec(stringToSign.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
			byte[] signData = mac.doFinal(new byte[]{});
			return new String(Base64.encodeBase64(signData, false));
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
		return "";
	}

}

webhook 接口代码

代码语言:javascript
复制
@RestController
public class WebhookController {

    @Resource
    private FeiShuNotifier feiShuNotifier;

    @RequestMapping("/webhook/receive")
    public void receive(@RequestBody String message) {
        feiShuNotifier.sendData(message);
    }
}

下面为飞书接收到的告警:

另外如果还需要接入企业微信等其他聊天工具,可以使用开源的PrometheusAlert,使用方案见其GitHub。 https://github.com/feiyu563/PrometheusAlert 作者其他文章:

  1. Spring Boot Admin 参考指南
  2. SpringBoot Admin服务离线、不显示健康信息的问题
  3. Spring Boot Admin2 @EnableAdminServer的加载
  4. Spring Boot Admin2 AdminServerAutoConfiguration详解
  5. Spring Boot Admin2 实例状态监控详解
  6. Spring Boot Admin2 自定义JVM监控通知
  7. Spring Boot Admin2 自定义异常监控
  8. Spring Boot Admin 监控指标接入Grafana可视化
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 创建告警规则
  • 配置WebHook通知
  • 配置告警策略
  • 部署中转服务
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档