Prometheus告警声音

前言

前一篇Prometheus告警大屏中,我们使用grafanaprometheus-alertmanager-datasource插件实现告警大屏,告警大屏展示告警信息并以不同的颜色区分告警级别。

这里我们在告警大屏的基础上,再实现告警声音。

本以为grafana本有就有集成告警声音的功能,但是研究了一番,并没有找到相关功能,社区也有不少人有相关需求,但是官方并没有要加这个功能的意向。

自己动手撸一个:

Github: alertmanager-sound

  • 基于python,使用request模块调用Alertmanager api,获取告警信息并播放告警声音。
  • windows下运行。

安装

下载安装windowspython

打开命令行提示符,cd进入python安装路径(Administrator登录用户名,每个人的电脑可能不一样),然后安装requests模块

1
2
cd C:\Users\Administrator\AppData\Local\Programs\Python\Python37-32
pip install requests

最后双击运行alertmanager-sound.py

窗口可以最小化,但不能关闭。

1
2
3
4
5
6
7
8
9
==========================================
2019-10-17 15:14:03 发现普通告警,播放声音
warning: anxi Ceph状态: HEALTH_WARN
warning: sichuan Ceph状态: HEALTH_WARN

==========================================
2019-10-17 15:14:35 Everything is OK

距离下一次检查还有15秒

文件说明

告警声音文件

alert.wav

配置文件

config.ini

1
2
3
4
5
6
7
8
#alertmanager api地址
api = http://192.168.100.1:9093/api/v2/alerts?silenced=false

#0普通告警不做任何处理,1普通告警也播放告警声音
warn = 1

#检查时间间隔
sleep = 30

主程序

alertmanager-sound.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# -*- coding: UTF-8 -*-
import time
import winsound
import requests,json
from time import strftime, localtime
import configparser

def count_down(t=30):
for x in range(t,-1,-1):
mystr = "距离下一次检查还有" + str(x) + "秒"
print(mystr,end = "")
print("\b" * (len(mystr)*2),end = "",flush=True)
time.sleep(1)

def main():
cf = configparser.ConfigParser()
cf.read("config.ini", encoding='UTF-8')
api = cf.get('config', 'api') #alertmanager api地址
warn = cf.getint('config', 'warn') #0普通告警不做任何处理,1普通告警也播放告警声音
sleep = cf.getint('config', 'sleep') #检查时间间隔

warn_num = 0
critical_num = 0
message = ""
title = " Everything is OK"
r = requests.get(api).json()
for alert in r:
if alert["labels"]["severity"] == "warning":
warn_num += 1
elif alert["labels"]["severity"] == "critical":
critical_num +=1
message = message + alert["labels"]["severity"] + ": " + alert["annotations"]["description"] + "\n"

if warn_num > 0:
title = " 发现普通告警" if warn == 0 else " 发现普通告警,播放声音"
if critical_num > 0:
title = " 发现严重告警,播放声音"

print("==========================================")
print(strftime("%Y-%m-%d %H:%M:%S", localtime()) + title)
print(message)

if critical_num > 0 or (warn == 1 and warn_num > 0):
winsound.PlaySound('alert', winsound.SND_ASYNC)
count_down(sleep)

if __name__ == '__main__':
while True:
main()

其他

Prometheus的告警规则里,需要定义告警级别标签。

如下系统负载超标定义为普通警告(severity: warning),根分区使用率大于90%为严重警告(severity: critical)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- name: system_load.rules
rules:
- alert: 系统负载超标
expr: node_load1/count without (cpu, mode) (node_cpu_seconds_total{mode="system"})>1.1
for: 2m
labels:
severity: warning
annotations:
summary: 系统负载超标
description: '{{$labels.instance}} 当前负载超标率 {{printf "%.2f" $value}}'

- name: partion_used.rules
rules:
- alert: 分区使用率大于90%
expr: ceil(100 - ((node_filesystem_avail_bytes{fstype != "rootfs"} * 100) / node_filesystem_size_bytes{fstype != "rootfs"}))>90
for: 1m
labels:
severity: critical
annotations:
summary: "{{$labels.mountpoint}} 分区空间紧张"
description: "{{$labels.instance}} {{$labels.mountpoint}}分区空间使用率 {{$value}}%"