Elastalert的报警功能拓展:分组报警

一 背景

  基于ELK日志的报警时互联网公司标配,大一点公司都会自研组件,报警信息更加准确、规则多样化。(以前的五八到家就是自研的)咱们采用了Elastalert报警。html

 官网的地址:https://github.com/Yelp/elastalertpython

Elastalert自带的报警方式虽然多种多样,以下所示,可是不能实现根据报警信息分组发送。并且,不太符合国情:nginx

咱们须要的是:邮件+短信+钉钉+微信+电话这种常见的组合。git

Currently, we have built-in support for the following alert types:github

  • Email
  • JIRA
  • OpsGenie
  • Commands
  • HipChat
  • MS Teams
  • Slack
  • Telegram
  • GoogleChat
  • AWS SNS
  • VictorOps
  • PagerDuty
  • PagerTree
  • Exotel
  • Twilio
  • Gitter
  • Line Notify
  • Zabbix

Additional rule types and alerts can be easily imported or written.微信

不能分组这就很蛋疼,要么就是全体收,要么就是制定几我的收。报警太多我自身的感觉就是跟“狼来了”差很少,一天几百个报警,时间一长没几天你就忽略了,真的报警也报淹没了。因此分组报警必要性性就体现出来了。主要目的是为了响应项目的报警发给对应的组内。app

   网上关于Elastalert 文章不少,可是实际上实用有份量的较少,我本身分析下:dom

方案 1: 报警方式实用post,python2.7

优势:便于拓展,工具

缺点:新开发一套报警相关的工程,工做量不是一两天的事

方案2: 基于Commands自定义报警组件:

优缺点:对于我来讲,主要是Python语法上的挑战。不懂啊,只是硬着头皮看点介绍。

这里我要重点介绍下一位大神:https://blog.csdn.net/sdmei/article/details/89928964

要没有他的文章,我就采用方案1了,由于对于不懂Python外行来讲,仍是有必定的技术门槛的。

关于elastalert的安装:mac:ElastAlert 安装

二 拓展改造

注意:Recent changes: As of Elastalert 0.2.0, you must use Python 3.6. Python 2 will not longer be supported.

这里首选说明下,要是使用对应的Python版本,

python
Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

我为了测试,就把mac自带的python2.7的升级到3.6.0版本,mac如何升级Python不展开,网上有不少文章。

2.1 告警数据怎么来获取?

这里关注下如何针对大神的文章去改造参数适配:

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"]

上面原做者的监控nginx 500的错误配置。咱们业务就是简单的监控ES错误日志:filter 哪里:query error

对应实际来讲:监控规则是不用变的,原来发邮件前怎么监控仍是继续。主要是方式:就是alert:从 email 变成command。

并且业务所须要的参数:command要输出不少自定义参数,脚本经过这些参数决定发送的组合发送的内容如IP,es对应的index,tradeid,message,appname等具体报警参数须要传入到command。对应的py脚本:alarm.py。

2.2 报警人员如何获取?

  这里要先看下配置:我改动较少,沿用原来的yaml配置。

project1:
  member:
    zhouwu:
      mail: zhouwu@sina.com
    wangliu:
      mail: wangliu@sina.com

主要仍是以项目XXpeoject为主,获取对应的报警人信息。有一点麻烦就是工程比较多的状况下须要收集下不一样部门不一样项目的报警人邮件,逐一配置。毕竟是Python啊,若是换成Java,仍是会好处理不少。可是维护组织结构与对应的负责项目这种 映射关系是不可缺乏的。

2.3  报警内容组装

原始版本的内容:

def make_msg(self):
        """
        get msg by rulename
        freq-status-*, warning: sina_www status of 500 exceed 30 per 2min
        freq-reqtime-*, warning: sina_www request time greater than 5sec exceed 30 per 2min
        """
        if re.match("freq-status-", self.rulename):
            self.msg = "%s: %s status of %s exceed %s per %s" % \
                       (self.level, self.domain, self.status, self.num_events, self.timeframe)
        elif re.match("freq-reqtime-", self.rulename):
            self.msg = "%s: %s request time greater than %s exceed %s per %s" % \
                       (self.level, self.domain, self.reqtime_gt, self.num_events, self.timeframe)
        else:
            self.msg = ''

这里能够自定义报警内容去替换,我不须要钉钉跟短信,只保留邮件,因此作了调整。

相关代码说明:

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

 

效果展现:

再测试环境肯定对应的ES起来了。而后模拟使用postman给es推送error触发报警。

本地起来了elastalert项目:

python -m elastalert.elastalert --config ./config.yaml --verbose --rule example_rules/my_rule.yaml

以邮件为例:

1 rules loaded
INFO:elastalert:Starting up
INFO:elastalert:Disabled rules are: []
INFO:elastalert:Sleeping for 59.99993 seconds
INFO:elastalert:Queried rule Example frequency rule from 2020-01-05 16:49 CST to 2020-01-05 16:59 CST: 1 / 1 hits
INFO:elastalert:New aggregation for Example frequency rule, aggregation_key: None. next alert at 2020-01-05 09:00:00+00:00.
INFO:elastalert:Ran Example frequency rule from 2020-01-05 16:49 CST to 2020-01-05 16:59 CST: 1 query hits (0 already seen), 1 matches, 0 alerts sent
INFO:elastalert:Disabled rules are: []
INFO:elastalert:Sleeping for 59.999657 seconds
INFO:elastalert:Background configuration change check run at 2020-01-05 17:00 CST
INFO:elastalert:Background alerts thread 1 pending alerts sent at 2020-01-05 17:00 CST
2020-01-05 17:00:12,556:alarm:INFO:mail -> bohu83@163.com,msg ->

elastalert索引中,hits表示规则命中条数;matches表示规则命中条数,而且匹配规则触发告警数量。 

邮件效果:

 数据都是造的,只是为了验证下效果。

没有加html 格式化。初步达到目的。

先后大概花了1天半的时间,开始半天被mac安装python折磨,后面1天主要是改动Python的时候语法错误。

另外,调试的时候遇到的一个坑是es的时间,一开始忽略了.

举个例子:  "@timestamp": "2020-01-05T08:58:11.092Z",

这个时间其实是1月5日16:58产生的,有个8小时时差。

剩下就是调整报警参数及邮件格式了。不得不认可,不懂Python语法调起来很费劲,全靠请教大师+百度。

期间我还咨询了小米的一个大神,大神说也没用过这个报警组件啊,不知道怎么改。其实看看核心代码不是很长大概200多行吧,熟悉的人半天就搞定了吧,可是对于不熟悉的改造加调试的确须要花时间。你得找机器去安装es.我自测试使用的就是线上版本6.7.  elastalert是0.2 ,Python是3.6.0. 一步一个坑。最大收获就是磨练了本身的耐心。

  最后再次感谢大神:他的地址:https://me.csdn.net/sdmei ,没有他的文章我不会尝试修改Python。也不会有本文。