ELK的监控工具Elastalert的报警功能扩展

Nginx请求日志输出到ELK,同时通过Elastalert监控ELK日志中的关键信息(如http状态500+错误,耗时较长的请求数达到阈值等等),这几乎是中小型互联网公司的标配。

Elastalert自带的报警方式虽然多种多样,但是不能实现根据报警信息分组发送,如研发人员也很关心这些指标,需要接受本项目的报警,运维需要接受所有项目的报警,报警方式要支持电话语音、短信、邮件、钉钉群。要实现这些,只能自己撸脚本了。

1.首先从yaml配置文件开始

yunwei:
  member:
    zhangshan:
      phone: 15895820001
      mail: [email protected]
    lisi:
      phone: 15895820002
      mail: [email protected]
  dingtoken:
    e802cb4b5791bb08e1bc79cfd62c0a6bae4b77e8758b4b52522d5119478f1234
project1:
  member:
    zhouwu:
      phone: 15895820003
      mail: [email protected]
    wangliu:
      phone: 15895820004
      mail: [email protected]
  dingtoken:
    0a30c27cbb9bb17e5dbcb721578b7a6a490810c2fc237e1af5a1289557d31234
project2:
  member:
    liudehua:
      phone: 15895820005
      mail: [email protected]

说明:

  • yunwei代表运维组;project1\porject2代表各个研发组,研发组名称必须与elastalert中的一级域名一致(这个跟各公司的具体情况有关,我们公司有n个平台,每个平台有1个或多个1级域名)
  • 每个组下的member可以有1-n个user;
  • 每个组有一个钉钉群;
  • phone\mail\dingtoken都不是必须的,如project2没有钉钉群,则不发钉钉通知;
  • 对于warning级别的报警,通过phone发送短信通知,对于disaster级别的通知,通过phone发送电话语音通知,所有级别的报警都会通过mail\dingtoken发送。

2.Elastalert的规则配置

以监控500状态为例说明配置

es_host: 10.10.10.1
es_port: 9200
name: freq-status-500
type: frequency
index: nginx-*
num_events: 30
timeframe:
  minutes: 1
filter:
- bool:
    must:
    - terms: 
        status: ["500","501","502","503","504"]
use_terms_query: true
doc_type: doc
terms_size: 10
query_key:
- domain
- status
realert:
  minutes: 60
alert:
- command
new_style_string_format: true
command: ["/root/elastalert-0.1.38/myalert/elastalert-alarm/alarm.py","--level=warning","--domain={domain,status}","--rulename=freq-status-500","--type=frequency","--num_events=30","--timeframe=1min"]

说明:

  • 官方说可以支持多个query_key,但测试过程中发现对于frequency类型的rule,多query_key死活不成功,后来发现frequency类型下并不支持多key,需要改造(见下一章节)
  • 实现按组报警,与普通Elastalert报警的主要区别在于,command要输出很多自定义参数,脚本通过这些参数决定发送的组合发送的内容,具体含义见alarm.py脚本
parser.add_argument('--level',dest='level',help='warning, distater')
parser.add_argument('--domain',dest='domain',help='for instance: sina_www, if rule_name start with freq-500,then sina_www-500')
parser.add_argument('--rulename', dest='rulename', help='rulename')
parser.add_argument('--type', dest='type', help='frequence, flatline')
parser.add_argument('--num_events', dest='num_events', help='num_events')
parser.add_argument('--timeframe', dest='timeframe', help='timeframe')
parser.add_argument('--reqtime_gt', dest='reqtime_gt', help='request time greater than')

3.frequency类型的规则支持多字段query_key

多query_key是非常实用的,如上文中,我要监控每个域名每种HTTP 500状态的请求数,一个rule就能实现了。可惜作者没支持好,需要稍微改造下。

配置举例(use_terms_query必须配置):

use_terms_query: true
query_key:
- domain
- status

修改elastalert.py中的方法get_terms_query:

修改前:
else:
    aggs_query = query
    aggs_query['aggs'] = {'counts': {'terms': {'field': field, 'size': size}}}
return aggs_query
修改后(暂且只支持2个字段):
else:
    aggs_query = query
    field_list = field.split(",")
    if  len(field_list) == 1:
        aggs_query['aggs'] = {'counts': {'terms': {'field': field, 'size': size}}}
    elif  len(field_list) == 2:
        source= "doc['" + field_list[0] + "'].value + '-' + doc['" + field_list[1] + "'].value"
        aggs_query['aggs'] = {'counts': {'terms': {'script': {'source': source}, 'size': size}}}
    else:
        elastalert_logger.inof("Not support more than 2 fields in query_key")
return aggs_query

alert中获取具体domain和status方式如下:

command: ["/tmp/alert_log.sh", "warning - freq 500 exceed, domain: {domain,status}"]

4.具体代码

文件说明:

alarm.py                --程序入口,参数解析
alert_channel.py        --报警发送通道(短信、语音、邮件、钉钉群)
alert.py                --构造发送对象和消息内容
aliyunsdk_SingleCallByTtsRequest.py   --阿里电话语音第三方库
config-contact.yaml     --报警对象配置文件
config.py               --加载配置文件
requirements.txt        --依赖
util.py                 --工具方法

代码地址:https://github.com/meishd/elastalert-alarm

5.效果

如域名www.sina.com的502请求数每分钟超过30个,则报警内容如下:

注:我们ELK中将domain改成“ 一级域名_二级域名 ”的格式入库

warning: sina_www status of 502 exceed 30 per 1min
发布了24 篇原创文章 · 获赞 25 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/sdmei/article/details/89928964
今日推荐