ElasticSearch可以使用X-Pack进行报警功能,由于其是收费使用,而当下也仅是使用告警功能。

所以这里寻求的是开源解决方案,elastalert,在GitHub中star数量5K+,已经算是很受欢迎的项目了,可以配合kibana进行使用,适用于所有版本的Elasticsearch,而且官方使用教程还挺详细,可以参考进行使用。

使用elastalert需要预先配置rule.yaml,根据软件介绍,选择适合自身规则的软件告警规则,根据告警规则填充详细的文档。

我们可以定义多个yaml,同时进行多种告警。对于每个rule.yaml,其包含一种告警发生规则,即阈值;包含一些告警方式,即email、jira等。

安装Elastalert

安装之前需要准备好Python的环境,这里已经提前安装完成,Python2.7

拉取最新的elastalert仓库

1
2
3
$ pip install elastalert
或者
$ git clone https://github.com/Yelp/elastalert.git

安装模块:

1
2
$ pip install "setuptools>=11.3"
$ sudo python setup.py install

安装成功后:

1
2
3
~$ ls /usr/local/bin/elastalert*
/usr/local/bin/elastalert /usr/local/bin/elastalert-rule-from-kibana
/usr/local/bin/elastalert-create-index /usr/local/bin/elastalert-test-rule
  • elastalert-create-index ElastAlert将有关其查询及其警报的信息和元数据保存回Elasticsearch。这对于审计,调试很有用,它允许ElastAlert重新启动并从中断的位置恢复。并不实际影响ElastAlert运行,但强烈推荐这么做。
  • elastalert-rule-from-kibana 从 Kibana 已保存的仪表盘中读取 Filtering 设置,帮助生成 config.yaml里的配置。不过注意,它只会读取 filtering,不包括 queries。
  • elastalert-test-rule 测试自定义配置中的 rule 设置。
  • elastalert运行elastalert。

设置Elasticsearch

ElastAlert将有关其查询及其警报的信息和元数据保存回Elasticsearch。这对于审计,调试很有用,它允许ElastAlert重新启动并从中断的位置恢复。并不实际影响ElastAlert运行,但强烈推荐这么做。

会需要输入es host port等参数,其他默认即可。

1
2
3
4
5
$ elastalert-create-index
New index name (Default elastalert_status)
Name of existing index to copy (Default None)
New index elastalert_status created
Done!

设置配置文件config.yaml和规则Rule

配置文件

1
`$ cp ~/elastalert/config.yaml.example ~/elastalert/config.yaml$ vi ~/elastalert/config.yaml`

调试时,我仅配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# This is the folder that contains the rule yaml files
# Any .yaml file will be loaded as a rule
rules_folder: example_rules

# How often ElastAlert will query Elasticsearch
# The unit can be anything from weeks to seconds
run_every:
minutes: 1

# ElastAlert will buffer results from the most recent
# period of time, in case some log sources are not in real time
buffer_time:
minutes: 15

# The Elasticsearch hostname for metadata writeback
# Note that every rule can have its own Elasticsearch host
es_host: 127.0.0.1

# The Elasticsearch port
es_port: 9200

# The index on es_host which is used for metadata storage
# This can be a unmapped index, but it is recommended that you run
# elastalert-create-index to set a mapping
writeback_index: elastalert_status

# If an alert fails for some reason, ElastAlert will retry
# sending the alert until this time period has elapsed
alert_time_limit:
days: 1

配置文件上的参数意义官方都已经注释。

官方文档中同样也有注解

配置规则

特别重要:监控的index中都必须存在@timestamp字段;go语言中使用time格式进行存储。

1
2
3
4
"@timestamp" : {
"type" : "date",
"format" : "dateOptionalTime"
}

基于example_rules/example_percentage_match.yaml 更改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
name: Example Percentage Match
type: percentage_match

es_host: localhost
es_port: 9200

index: pro_record
description: "95% of all http requests should be successful"

filter:
- term:
_type: record

buffer_time:
minutes: 1

#use_terms_query: true
query_key: ["binx.keyword"]
doc_type: record

match_bucket_filter:
- term:
binx.keyword: "xxxxx"

#min_percentage: 1
max_percentage: 1

#bucket_interval:
# minutes: 1

#sync_bucket_interval: true
#allow_buffer_time_overlap: true
#use_run_every_query_size: true

# (Required)
# The alert is use when a match is found
alert:
- "debug"

文件作为演示,数据都已被更改

使用elastalert-test-rule对规则进行测试。

1
`elastalert-test-rule ~/elastalert/example_rules/example_frequency.yaml`

正常出现Successfully loaded Example Percentage Match,然后实际输出也并没报错,那到这里就规则至少文件是没问题的了。

参考:Rule Types and Configuration Options

若是想要监控特定订单下的bin错误,那就需要增加查询条件:

1
2
3
4
5
match_bucket_filter:
- term:
order.keyword: "TDRAM19012"
- term:
bin.keyword: "2142134038"

使用HTTP POST报警

根据官方文档,查看配置参数的含义:

1
2
3
4
5
6
alert: post
http_post_url: "http://example.com/api"
http_post_payload:
ip: clientip
http_post_static_payload:
apikey: abc123

alert: post:指定警报方式;

http_post_url: "http://example.com/api":post地址,route方法同样也为post

http_post_payload:这个参数表示是否需要重定义ElastAlert的键值,例如设置了ip: clientip,那么原来数据中的clientip键,将被替换成ip,也可以填入没有的键值,只不过value是null可以不需要此参数,表示直接返回ES的数据

http_post_static_payload:这个表示每次警报发送固定的信息,也就是每次警报都会带上apikey: abc123

例如在上面基础上去掉了http_post_payload,返回的json数据是:

1
{"num_hits": 1, "@timestamp": "2019-03-28T06:54:51.043483Z", "denominator": 1, "bin.keyword": "2142134038", "num_matches": 1, "percentage": 100.0, "order": "TDRAM19012"}

运行

最后,运行命令:

1
$ python -m elastalert.elastalert --config ./config.yaml

或者单独执行 rules_folder 里的某个 rule:

1
$ python -m elastalert.elastalert --config ./config.yaml --rule ./examele_rules/example_percentage_match.yaml

调试时使用

1
$ python -m elastalert.elastalert --verbose --rule example_rules/example_percentage_match.yaml --config config.yaml --debug

启动后无error错误打印,代表程序运行成功。

测试

向ES index pro_record插入一些数据,因为制定的规则是在一分钟之内,只要有符合匹配规则的数据插入,其百分比超过100%,就将会报错。

若打印出现类似于:

1
2
3
4
5
6
7
8
9
10
11
12
...

Percentage violation, value: 100.0 (min: None max : 1) of 1 items

@timestamp: 2019-03-27T08:04:16.323823Z
bin.keyword: 2142134038
denominator: 1
num_hits: 21
num_matches: 9
percentage: 100.0

....

表示规则已正常运行,且能成功进行匹配。

参考

介绍命令 ElastAlert

官方文档 Writing Filters For Rules

对各项报警进行分析,其是使用post方式告警 基于Elastalert的安全告警剖析

从安装到使用 ElastAlert 基于Elasticsearch的监控告警