prometheus+alertmanager+webhook实现自定义监控报警系统
文章目录
1.概述
上一篇文章prometheus+grafana+mtail+node_exporter实现机器负载及业务监控介绍了使用mtail和node_exporter实现的prometheus无埋点监控机器负载和业务的监控系统,本文是在其基础上实现自定义报警功能。
Prometheus+Alertmanager 的警报分为两个部分:
-
Prometheus负责中配置警报规则,将警报发送到Alertmanager
。 -
Alertmanager 负责管理这些警报,包括沉默,抑制,合并和发送通知
。
Alertmanager 发送通知有多种方式,其内部集成了邮箱、Slack、企业微信等三种方式,也提供了webhook的方式来扩展报警通知方式,网上也有大量例子实现对第三方软件的集成,如钉钉等。本文介绍邮件报警方式和通过使用java来搭建webhook自定义通知报警的方式。
本文内容主要分为四块:
- prometheus报警规则配置
- alertmanager配置及部署
- 关联prometheus和alertmanager
- 配置报警通知方式
2.prometheus配置报警规则
prometheus.yml属性配置
属性 | 描述 |
---|---|
scrape_interval | 样本采集周期,默认为1分钟采集一次 |
evaluation_interval | 告警规则计算周期,默认为1分钟计算一次 |
rule_files | 指定告警规则的文件 |
scrape_configs | job的配置项,里面可配多组job任务 |
job_name | 任务名称,需要唯一性 |
static_configs |
job_name 的配置选项,一般使用file_sd_configs 热加载配置 |
file_sd_configs |
job_name 的动态配置选项,使用此配置可以实现配置文件的热加载
|
files: |
file_sd_configs 配置的服务发现的文件路径列表,支持.json,.yml或.yaml,路径最后一层支持通配符* |
refresh_interval |
file_sd_configs 中的files 重新加载的周期,默认5分钟 |
此处我们使用rule_files
属性来设置告警文件
# my global config
global:
scrape_interval: 15s # 采样周期
evaluation_interval: 15s # 告警规则计算周期
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
# 报警规则文件可以指定多个,并且可以使用通配符*
rule_files:
- "rules/*_rules.yml"
# - "second_rules.yml"
# 采集job配置
scrape_configs:
- job_name: 'prometheus'
#使用file_sd_configs热加载配置文件
file_sd_configs:
#指定1分钟加载一次配置
- refresh_interval: 1m
files:
- config_prometheus.json
- job_name: 'linux_base'
file_sd_configs:
- refresh_interval: 1m
files:
- config_exporter.json
- job_name: 'service_base'
file_sd_configs:
- refresh_interval: 1m
files:
- config_mtail.json
- job_name: 'grafana'
file_sd_configs:
- refresh_interval: 1m
files:
- config_grafana.json
设置报警规则,rules/host_rules.yml
groups:
# 报警组组名称
- name: hostStatsAlert
#报警组规则
rules:
#告警名称,需唯一
- alert: hostCpuUsageAlert
#promQL表达式
expr: sum(avg without (cpu)(irate(node_cpu_seconds_total{mode!='idle'}[5m]))) by (instance) > 0.85
#满足此表达式持续时间超过for规定的时间才会触发此报警
for: 1m
labels:
#严重级别
severity: page
annotations:
#发出的告警标题
summary: "实例 {{ $labels.instance }} CPU 使用率过高"
#发出的告警内容
description: "实例{{ $labels.instance }} CPU 使用率超过 85% (当前值为: {{ $value }})"
- alert: hostMemUsageAlert
expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes)/node_memory_MemTotal_bytes > 0.85
for: 1m
labels:
severity: page
annotations:
summary: "实例 {{ $labels.instance }} 内存使用率过高"
description: "实例 {{ $labels.instance }} 内存使用率 85% (当前值为: {{ $value }})"
采集任务job配置config_exporter.json配置如下(其他job配置文件类似):
[
{
"targets": [ "192.168.113.13:9100"],
"labels": {
"env": "prod"
}
},
{
"targets": [ "10.12.141.150:9100"],
"labels": {
"env": "local"
}
},
{
"targets": [ "10.12.141.151:9100"],
"labels": {
"env": "local2"
}
}
]
配置完报警规则重启prometheus,访问http://ip:9090/,点击alerts就能看到配置的报警信息了,如下:
3.alertmanager配置及部署
3.1.alertmanager配置
alertmanager会定义一个基于标签匹配规则的路由树,用以接收到报警后根据不同的标签匹配不同的路由,来将报警发送给不同的receiver。如果定义一个路由route则需要接收并处理所有的报警,如果需要区分不同的报警发送给不同的receiver,则需要配置多个子级route来处理不同的报警,而根route此时必须能够接收处理所有的报警。
#根路由
route:
#*路由配置的接收者(匹配不到子级路由,会使用根路由发送报警)
receiver: 'default-receiver'
#设置等待时间,在此等待时间内如果接收到多个报警,则会合并成一个通知发送给receiver
group_wait: 30s
#两次报警通知的时间间隔,如:5m,表示发送报警通知后,如果5分钟内再次接收到报警则不会发送通知
group_interval: 5m
#发送相同告警的时间间隔,如:4h,表示4小时内不会发送相同的报警
repeat_interval: 4h
#分组规则,如果满足group_by中包含的标签,则这些报警会合并为一个通知发给receiver
group_by: [cluster, alertname]
routes:
#子路由的接收者
- receiver: 'database-pager'
group_wait: 10s
#默认为false。false:配置到满足条件的子节点点后直接返回,true:匹配到子节点后还会继续遍历后续子节点
continue:false
#正则匹配,验证当前标签service的值是否满足当前正则的条件
match_re:
service: mysql|cassandra
#子路由的接收者
- receiver: 'frontend-pager'
group_by: [product, environment]
#字符串匹配,匹配当前标签team的值为frontend的报警
match:
team: frontend
#定义所有接收者
receivers:
#接收者名称
- name: 'default-receiver'
#接收者为webhook类型
webhook_configs:
#webhook的接收地址
- url: 'http://127.0.0.1:5001/'
- name: 'database-pager'
webhook_configs:
- url: 'http://127.0.0.1:5002/'
- name: 'frontend-pager'
webhook_configs:
- url: 'http://127.0.0.1:5003/'
3.2.alertmanager部署
建议下载最新版本,最新版下载地址请戳此处(可能需要*),我使用的版本为alertmanager-0.20.0.linux-amd64.tar.gz,我的版本csdn下载地址请戳。
将其解压到/usr/local后,进入目录/usr/local/alertmanager-0.20.0.linux-amd64,会有个默认配置文件:alertmanager.yml,内容如下:
global:
resolve_timeout: 5m
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
receiver: 'web.hook'
receivers:
- name: 'web.hook'
webhook_configs:
- url: 'http://127.0.0.1:5001/'
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
使用默认配置在后台启动:
nohup ./alertmanager > alertmanager.out 2>&1 &
- 1
查看是否启动成功:
ps -ef | grep alertmanager
- 1
启动后访问http://ip:9093/查看是否启动成功,点击status查看alertmanager及其配置,访问如下(我的配置有改动,请以自己页面展示为准):
4.prometheus关联alertmanager
prometheus.yml中的alerting标签下配置上alertmanager的地址即可,配置如下:
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets: ['192.168.199.23:9093']
添加后重启prometheus即可。
5.配置报警通知方式
5.1.alertmanager邮箱报警demo
global:
#超时时间
resolve_timeout: 5m
#smtp地址需要加端口
smtp_smarthost: 'smtp.126.com:25'
smtp_from: 'aaa@qq.com'
#发件人邮箱账号
smtp_auth_username: 'aaa@qq.com'
#账号对应的授权码(不是密码),阿里云个人版邮箱目前好像没有授权码,126邮箱授权码可以在“设置”里面找到
smtp_auth_password: '1qaz2wsx'
smtp_require_tls: false
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 1m
repeat_interval: 4h
receiver: 'mail'
receivers:
- name: 'mail'
email_configs:
- to: 'aaa@qq.com'
设置后如果有通知,即可收到邮件如下:
5.2.alertmanager使用webhook(java)报警demo
global:
resolve_timeout: 5m
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 1m
repeat_interval: 4h
receiver: 'webhook'
receivers:
- name: 'webhook'
webhook_configs:
- url: 'http://192.168.199.152/demo'
使用webhook方式,alertmanager会给配置的webhook地址发送一个http类型的post请求,参数为json字符串(字符串类型),如下(此处格式化为json了):
{
"receiver":"webhook",
"status":"resolved",
"alerts":[
{
"status":"resolved",
"labels":{
"alertname":"hostCpuUsageAlert",
"instance":"192.168.199.24:9100",
"severity":"page"
},
"annotations":{
"description":"192.168.199.24:9100 CPU 使用率超过 85% (当前值为: 0.9973333333333395)",
"summary":"机器 192.168.199.24:9100 CPU 使用率过高"
},
"startsAt":"2020-02-29T19:45:21.799548092+08:00",
"endsAt":"2020-02-29T19:49:21.799548092+08:00",
"generatorURL":"http://localhost.localdomain:9090/graph?g0.expr=sum+by%28instance%29+%28avg+without%28cpu%29+%28irate%28node_cpu_seconds_total%7Bmode%21%3D%22idle%22%7D%5B5m%5D%29%29%29+%3E+0.85&g0.tab=1",
"fingerprint":"368e9616d542ab48"
}
],
"groupLabels":{
"alertname":"hostCpuUsageAlert"
},
"commonLabels":{
"alertname":"hostCpuUsageAlert",
"instance":"192.168.199.24:9100",
"severity":"page"
},
"commonAnnotations":{
"description":"192.168.199.24:9100 CPU 使用率超过 85% (当前值为: 0.9973333333333395)",
"summary":"机器 192.168.199.24:9100 CPU 使用率过高"
},
"externalURL":"http://localhost.localdomain:9093",
"version":"4",
"groupKey":"{}:{alertname="hostCpuUsageAlert"}"
}
此时需要使用java(其他任何语言都可以,反正只要能处理http的请求就行)搭建个http的请求处理器来处理报警通知,如下:
public class AlertController { @RequestMapping(value = "/demo", produces = "application/json;charset=UTF-8")@ResponseBody
public String pstn(@RequestBody String json) {
log.debug("alert notify params: {}", json);
Map<String, Object> result = new HashMap<>();
result.put("msg", "报警失败");
result.put("code", 0);
if(StringUtils.isBlank(json)){
return JSON.toJSONString(result);
}
JSONObject jo = JSON.parseObject(json);
JSONObject commonAnnotations=jo.getJSONObject("commonAnnotations");
String status = jo.getString("status");if (commonAnnotations == null) {
return JSON.toJSONString(result);} String subject = commonAnnotations.getString("summary");
String content = commonAnnotations.getString("description");
List<String> emailusers = new ArrayList<>();
emailusers.add("aaa@qq.com");
List<String> users = new ArrayList<>();
users.add("158*****5043");
try {
boolean success = Util.email(subject, content, emailusers);
if (success) {
result.put("msg", "报警成功");
result.put("code", 1);
}
} catch (Exception e) {
log.error("=alert email notify error. json={}", json, e);
}
try {
boolean success = Util.sms(subject, content, users);
if (success) {
result.put("msg", "报警成功");
result.put("code", 1);
}
} catch (Exception e) {
log.error("=alert sms notify error. json={}", json, e);
}
return JSON.toJSONString(result);
}
}
6.总结
alertmanager配置功能确认很强大,完全能够按照自己的目标定义灵活的通知和报警方式,尤其是对webhook的支持,简直不能更灵活了。而且alertmanager还支持定义template来更清晰的彰显要通知的内容。但是本人还没有发现alertmanager该怎么进行配置的热加载,后面还要再研究下怎么优化通知,避免告警轰炸和提高告警的准确性。
推荐阅读
-
prometheus+alertmanager+webhook实现自定义监控报警系统
-
使用simple_flow实现实时系统的监控 博客分类: simple_flowc++ c++系统监控simple_flow流式计算
-
win7及以上系统C++实现Hook explorer文件级监控复制、剪切和删除操作
-
python实现内存监控系统
-
python实现服务器监控报警消息用微信发送(附代码)
-
Android编程实现自定义系统菜单背景的方法
-
Android编程实现自定义系统菜单背景的方法
-
C#实现读取注册表监控当前操作系统已安装软件变化的方法
-
C#实现自定义windows系统日志的方法
-
用shell+sendmail实现服务器监控报警小脚本