对于站点流量监控或日志状态的监控,之前通过elk+python+zabbix结合微信报警来实现,但是这种方式对于流量的阈值及监控间隔不太好确定,而且通过elk的dsl语句查询,实现起来比较麻烦。
因此我们希望借助grafana的多数据源特性,结合elk+alertmanager实现微信报警,并且能够报警到不同部门或不同告警人。
alertmanager
alertmanager是prometheus一个单独的报警模块,具有分组、抑制、静默等功能。在此我们借助alertmanager直接与grafana进行结合实现告警。
1.配置
cd /usr/local/alertmanager
vim grafana.yml
global:
resolve_timeout: 5m
templates:
- '/usr/local/alertmanager/wechat.tmpl'
route:
group_by: ['alertname']
group_wait: 5s
#同一组内警报,等待group_interval时间后,再继续等待repeat_interval时间
group_interval: 1m
#当group_interval时间到后,再等待repeat_interval时间后,才进行报警
repeat_interval: 10m
receiver: 'wechat'
receivers:
- name: 'wechat'
wechat_configs:
- corp_id: 'wwbba7dxe372e'
agent_id: '1000005'
api_secret: '-CJ9QLEFxsdfwvxLzx7wPgoK9Dt-NWYOLuy-RuX3I'
to_user: 'test1'
send_resolved: true
alertmanager默认情况下告警接收人为wechat,也就是默认对test1用户发送微信告警。
其中:
- corp_id、agent_id、api_secret为微信企业号的配置;
- to_user为企业号通讯录人员;
- 报警再次发送时间为group_interval+repeat_interval,也就是先等待group_interval,再等待repeat_interval。
注意:企业号新建应用的须设置相应的可见范围及人员,否则无法发送信息。
2.报警模板
cd /usr/local/alertmanager
vim wechat.tmpl
{{ define "grafana.default.message" }}{{ range .Alerts }}
{{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
{{ range .Annotations.SortedPairs }}{{ .Name }} = {{ .Value }}
{{ end }}{{ end }}{{ end }}
{{ define "wechat.default.message" }}
{{ if eq .Status "firing"}}[Warning]:{{ template "grafana.default.message" . }}{{ end }}
{{ if eq .Status "resolved" }}[Resolved]:{{ template "grafana.default.message" . }}{{ end }}
{{ end }}
其中:
- Status 只有两个状态firing、resolved,通过这个参数是否发送warning和resolved报警信息。
- 模板的语法还需查官网进行深入学习。
注意:prometheus 默认时区为UTC且无法改变时区,因此我们的报警时间应该+8:00,因此需要在模板中重新调整时区。
3.设置启动服务
vim /lib/systemd/system/alertmanager.service
[Unit]
Description=Alertmanager for Prometheus
After=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/alertmanager/alertmanager --config.file=/usr/local/alertmanager/grafana.yml --storage.path=/usr/local/alertmanager/data/ --log.level=debug
Restart=on-failur
ExecStop=/bin/kill -9 $MAINPID
[Install]
WantedBy=multi-user.targe
启动后,可通过http://ip:9093 访问alertmanager界面。
grafana
1.添加报警渠道
注意:Disable Resolve Message 没有勾选,不发送报警取消信息;我是在alertmanager 模板中判断若Status没有firing(则为resolved),则发送报警解决信息。
2.设置Alert
Alert需要在相应的dashboard中进行设置
其中监控策略为每分钟计算一次,持续5分钟;当query A 在5分钟时间内的中位数 > 1500 时,报警会发送给alertmanager;alertmanager 会根据group_wait、group_interval、repeat_interval对报警进行分组合并、抑制,从而避免告警泛滥。
3.微信告警
从[Warning]告警得知,alertmanager将两条告警信息合并为一条后发送给报警人,从而避免发送多条告警通知,引起告警泛滥。
告警通知
上面只是实现了对test1用户微信告警通知,但是在生产环境中告警需要按照级别、业务发送给不同部门、负责人,此时我们就需要进行优化。
例如:我们对elk的index按业务分组并发给不同部门的接收人,如:web、api,怎么实现?
接下来我们继续分析。
1.alertmanager告警信息
alertname='xxx流量告警'
description='xxx每分钟访问量超过1500'
summary='xxx流量告警'
metric='Count'
通过访问alertmanager的web页面http://192.168.3.44:9093确认:
- alertmanager中,对alertname进行分组;
- description和summary是具体报警内容;
- metric是标签,即label;
要想实现分组,alertmanager需要根据label进行设置子路由,通过匹配label发送给不同的接收人。
2.设置子路由
通过routes设置子路由,子路由中设置不同的接收人。
vim grafana.yml
global:
resolve_timeout: 5m
templates:
- '/usr/local/alertmanager/wechat.tmpl'
route:
group_by: ['alertname']
group_wait: 5m
#group_wait: 1m
#同一组内警报,等待group_interval时间后,再继续等待repeat_interval时间
group_interval: 10m
#group_interval: 1m
#当group_interval时间到后,再等待repeat_interval时间后,才进行报警
repeat_interval: 1h
#repeat_interval: 1m
receiver: 'wechat'
#子路由
routes:
- receiver: 'wechat_web'
match_re:
department: 'web'
- receiver: 'wechat_api'
match_re:
department: 'api'
receivers:
- name: 'wechat'
wechat_configs:
- corp_id: 'wwbba179b20d372e'
agent_id: '1000005'
api_secret: '-CJ9QLEFxLzxt-NWYOLuy-RuX3I'
to_user: 'test1'
send_resolved: true
- name: 'wechat_web'
wechat_configs:
- corp_id: 'wwbba179b20d372e'
agent_id: '1000005'
api_secret: '-CJ9QLEFxLzxt-NWYOLuy-RuX3I'
to_user: 'test2'
send_resolved: true
- name: 'wechat_api'
wechat_configs:
- corp_id: 'wwbba179b20d372e'
agent_id: '1000005'
api_secret: '-CJ9QLEFxLzxt-NWYOLuy-RuX3I'
to_user: 'test3'
send_resolved: true
我们将告警接受人按标签department分为wechat_web、wechat_api、wechat三组
3.amtool 调试
#触发web报警
./amtool --alertmanager.url=http://192.168.3.44:9093 alert add department=web alertname="xxx流量告警" --annotation=description='xxx每分钟访问量超过1500' --annotation=summary = "xxx流量告警"
#触发api报警
./amtool --alertmanager.url=http://192.168.3.44:9093 alert add department=api alertname="xxx流量告警" --annotation=description='xxx每分钟访问量超过1500' --annotation=summary = "xxx流量告警"
通过这种方式,我们可以在排除grafana的情况下,模拟测试alertmanager触发报警。
4.grafana匹配label
由于我们使用的是grafana5.4 ,查看官方文档进行确认。
从上图看出报警通道为prometheus+alertmanager 是支持发送图片和报警标签(对应alertmanager中的label),但是是从6.3+开始。
也就是说grafana5.4 是不支持报警标签,因此无法设置label;因此我们需要将grafana升级到6.3以上,升级过程需要测试,以免丢失数据。
两个版本的对比如下:
(1)grafana-5.4 告警信息配置:
(2)grafana-6.5 告警信息配置:
通过上图区别,可明显看出6.5 比 5.4 的多出了一个alert tag的功能,即对应alertmanger的label。如下:
使用grafana-5.4 默认展示一个label:metric
使用grafana-6.5 可以展示两个label:department和metric:
- metric用于elk的相关指标的统计量;
- department用于区分发送给不同部门和报警人
alertmanger正是通过这个手动添加的label来匹配不同的子路由,发给不同的报警人,我们只需要在grafana中通过department来指定不同的部门或业务负责人即可。
总结
grafana可以非常直观展示业务的近实时流量状态,因此可以很方便的设置指标的监控阈值,结合alertmanage对告警进行分组、合并、抑制,避免告警泛滥,可以准确的让运维定位问题。但是grafana指标发生告警时的实际值无法在告警通知时展示,这可能是一个比较遗憾的地方。