这次着重看一看elastalert的配置及支持的Rule规则. 对于一般的业务需求基本是可以满足的了.
全局配置
1 | es_host: 127.0.0.1 |
全局配置文件比较好理解, 比较重要的是
run_every
: 指定每次查询的周期- buffer_time: 查询es的时间窗口
writeback_index
: 存储所有数据的索引, 参考old_query_limit
: The maximum time between queries for ElastAlert to start at the most recently run query.
When ElastAlert starts, for each rule, it will searchelastalert_metadata
for the most recently run query and start from that time, unless it is older thanold_query_limit
, in which case it will start from the present time. The default is one week.
注意如果需要改动这个配置文件, 需要重启.
rule类型
常用的rule类型有以下几类:
frequency
说明:当给定时间范围内至少有一定数量的事件时,此规则匹配。 这可以按照每个query_key来计数
规则: 5分钟之内如果出现10次匹配到关键字,则触发报警
1 | es_host: 127.0.0.1 |
下面几种rule规则的配置只会贴出与上面配置不一样的地方.官方的说明很详细
any
说明:任何规则都会匹配, 查询返回的每个命中将生成一个警报。
规则:当匹配status字段为anystatus
,触发告警
1 | type: any |
一定要慎用这个规则, 因为每个命中都会生成告警
flatline
说明:当一个时间段内的事件总数低于一个给定的阈值时,匹配规则
规则: 5分钟之内如果关键字的文档数小于给定阈值,则触发报警
1 | timeframe: |
spike
说明:当某个时间段内的事件量比上一个时间段的spike_height时间大或小时,这个规则是匹配的。它使用两个滑动窗口来比较事件的当前和参考频率。 我们将这两个窗口称为“参考”和“当前”。
规则:当前窗口数据量为3,当前窗口超过参考窗口数据量次数1次,触发告警
1 | type: spike |
threshold_cur
:当前窗口初始值spike_height
:当前窗口数据量连续比参考窗口数据量高(/低)的次数spike_type
:高或低
change
说明:此规则将监视某个字段,并在该字段更改时进行匹配,该领域必须相对于最后一个事件发生相同的变化。
规则:当server字段值相同,codec字段值不同时,触发告警
1 | type: change |
compare_key
:与上一条记录做对比的字段- query_key
:与上一条记录相同的字段
ignore_null
:忽略记录不存在compare_key字段的情况
blacklist
说明:黑名单规则将检查黑名单中的某个字段,如果它在黑名单中则匹配。
规则:当字段status匹配到关键字sensefacexxx,触发告警
1 | type: blacklist |
要注意的是最终转换成es的查询语句时会将blacklist的值也加入到查询条件中,如下:
1 | curl -H 'Content-Type: application/json' -XGET 'http://localhost:9200/demo.demo-*/_search?pretty&_source_include=%40timestamp%2C%2A%2Cschema.device_id%2CbackendMod&ignore_unavailable=true&scroll=30s&size=1000 |
writelist
说明:与黑名单类似,此规则将某个字段与白名单进行比较,如果列表中不包含该字词,则匹配
blacklist与writelist都没有rule title.
cardinality
说明:当一个时间范围内的特定字段的唯一值的总数高于或低于阈值时,该规则匹配
规则:1分钟内,level的唯一数量超过2个(不包括2个),触发告警。
1 | type: cardinality |
注意:cardinality类型的因为查询的是唯一值,因此不会返回match_body的内容, 所以任何引用match_body的字段都会返回<MISSING VALUE>
,当然可以使用enhancement.
关于时间格式
首先要说明的是: 默认情况下, elasticsearch存储的日志的@timestamp
为UTC
格式的, 因此所有查询es的时间窗口都会被转换成UTC
而elastalert也很人性化的会根据本地时区对日期进行格式化输出.
1 | # endtime 永远都为当着时间,因此会首先获取utc时间然后根据时区转换为当地时间 |
大多数情况下,查询es默认都是以@timestamp为基准,如果使用其它的field, 需要在rule文件中指定以下三个相应的配置
1 | timestamp_field: datetime |
日志说明
1 | Queried rule index realty find invalid keyword from 2020-05-29 08:49 UTC to 2020-05-29 08:54 UTC: 482 / 482 hits |
elastalert索引中,hits
表示规则命中条数;matches
表示规则命中条数,并且匹配规则触发告警数量。
num_hits表示的是根据filter条件及查询时间段从es返回的记录,而num_matches表示的是预计会产生多少条报警
因此 num_matches = num_hits / num_events, 会四舍五入,所以在告警内容中会发现两者都是这样的关系
elastalert打印的以下日志包含以下几个信息非常有用.
- 时间段: 2020-05-29 08:49 to 2020-05-29 08:54
- 查询的文档数(匹配查询条件返回的记录): 482
- 已处理文档数(already seen): 108
- 报警数: 37
- 发送报警数: 1
如果每次运行的时间(run_every)跟查询窗口时间(buffer_time)有重叠的,则会出现already seen
, 比如run_every为3分钟, buffer_time为5分钟, 则每3分钟查询5分钟的es, 待下次查询时还查5分钟内的文档, 则前2分钟在上一个执行周期内已经查询过了, 因此already seen
就类似于2分钟内有108个文档.
如果在rule配置文件中配置了realert,比如2分钟, 则会在日志中可能看到Ignoring match,这些都是被丢弃的alert, realert的意思是同一类的match产生的报警在2分钟之内不会重复发送,直接被丢弃
如果设置了realert=0,则每个match都会产生alert.这个要注意告警风暴.
match_body
match_body
这个字典是最重要的结构体,当查询到符合报警的文档时,会复制一份到elastalert的索引中, 内容如下:
1 | { |
elastalert索引中,hits
表示规则命中条数;matches
表示规则命中条数,并且匹配规则触发告警数量
在上面的rule配置文件中alert_text_args
与alert_subject_args
指定的参数都可以直接使用match_body结构体中的字段. 嵌套的使用点(.)来引用
num_hits vs num_matches
1 | num_hits is the number of documents returned by elasticsearch for a given query. num_matches is how many times that data matched your rule, each one potentially generating an alert. |
enhancements
如果觉得最终返回的数据不符合要求或者需要添加自定义的字段, 那么可以在发送给告警器之前对match_body进行修改, 这就需要用到enhancements
功能
比如需要对时间格式进行调整, 那么可以这样使用
1 | import arrow |
然后在rule的配置文件中指定:
1 | match_enhancements: # 指定使用增强功能 |
如果出现以下错误failed to parse [match_time]
:
原因: 这是由于enhancements.py中TimeEnhancement中改变了@timestamp
的格式,从而使得match_time
不符合索引中的格式
解决: 修改或者去掉enhancements.py默认的以下内容
1 | match['@timestamp'] = pretty_ts(match['@timestamp'] |
告警内容
对于不同的rule, 生成的告警内容不太一样, 但是都是由汇总信息+自定义内容组成,对于frequency类型来说,内容如下:
1 | Ref Log http://192.168.115.65 |
对于其它类型的告警内容可参考官网
下次跟大家分享下elastalert的源码.
参考文章:
- https://www.cnblogs.com/duanxz/p/11859307.html
- https://www.freebuf.com/sectool/164591.html
- https://www.jianshu.com/p/f82812e0a743
- https://github.com/Yelp/elastalert/issues/2754
- https://segmentfault.com/a/1190000017553282
- https://blog.xizhibei.me/2017/11/19/alerting-with-elastalert/
- https://github.com/Yelp/elastalert/issues/1737
- https://elastalert.readthedocs.io/en/latest/elastalert_status.html#elastalert-status
- https://elastalert.readthedocs.io/en/latest/recipes/adding_enhancements.html#enhancements