elastalert是专门为elastsearch开源的日志关键字监控工具, 支持非常多的告警方式且自定义程度很高, 代码写的也非常清晰, 最近调研了这个开源库进行了二次开发, 用在了业务日志关键字监控上,还是很不错的.这里站在用户使用的角度对邮件告警进行了改造, 期间踩了不少坑.
下次会记录一下常见的监控rule
类型及接入微信告警的方式.
安装
1 | pip3 install elastalert |
启动
物理机
1 | /usr/bin/python -m elastalert.elastalert --rule /etc/elastalert/rules/my_rule.yaml --verbose |
容器
官方给出的docker启动方式, 但比较粗糙, 不建议, 建议直接运行在k8s中.
1 | git clone https://github.com/bitsensor/elastalert.git; cd elastalert |
k8s
这里推荐一个在elastalert的基础上集成restfulapi接口的库, elastalert-server
直接支持最新的python3.8+elastalert2.0.4
, 可通过http 接口进行CURD
创建索引
elastalert在启动时会自动创建相关索引,当然也可事先使用elastalert-create-index
提示创建索引
1 | root@python-debug-5fdd9d9cd5-fkfkh:/usr/local/lib/python3.5# elastalert-create-index |
上述的5个索引主要用于保存elastalert运行期间的相关数据, 会直接写回到es中, 主要用于计算比如聚合,发现日志关键字时的日志现场等,同时也会记录elastalert本身的数据.
配置热更新
elastalert代码中使用apscheduler库定时检查rule文件的hash值,在运行周期到达时会比对rules的hash值是否有变化从而修改apscheduler的modify_job来实现热更新
1 | new_rule_hashes = self.rules_loader.get_hashes(self.conf, self.args.rule) |
因此如果是rule文件是使用的k8s的configmap进行部署, 则可直接修改configmap,不需要重启.
告警方式
elastalert支持非常多的报警方式, 而且官方也支持直接对报警方式进行二次开发,只要实现对应的类即可, 详情alerts, 这里以邮件为例来自定义邮件模板
自定义邮件格式
邮件subject
默认的邮件的subject的格式是ElastAlert: index realty contain is invalid
index realty contain is invalid
为rule文件中定义的名字
1 | alert_subject: "Issue {0} occurred at {1}" |
这里使用的python中的字符串占位替换.类似于"{}, {}".format(xxx, yyy)
邮件内容
官方支持的邮件内容是纯文本的,非常不美观, 好在直接在rule文件中使用alert_text
字段来指定使用的模板,可以使用html格式,同样,使用参数来进行占位替换.
但这存在一个问题是,每一个rule文件都需要写一大坨的html模板,虽然内容相差无几, 但还是需要根据需要展示的参数的个数来修改html模板, 因此,这里使用固定的html模板样式动态地对参数个数进行支持, 使用到jinja2来做, 最终实现的效果是: 使用者不需要关注模板内容, 直接指定alert_text_args的参数即可
1 | alert: |
邮件效果如下:
问题
- 镜像编译时提示以下
invalid syntax
原因: python3.7的版本需要jira2.0以上的版本, 默认requirements.txt中指定的jira版本为1.x的版本, 不相容.
解决: 升级jira的版本.
- 启动时提示
duplicate rule name
原因: 由于elastalert是递归的遍历rules规则,如果rules是使用的kubernetes的configmap挂载进来的,最终在rules目录下生成的文件会是下面的这样
在..2020_05_26_07_37_04.030814278目录下也会存在一个同名的规则文件, 因此会提示rule 重复.
解决: 在elastalert的配置文件中可指定scan_subdirectories: False
即不对rules目录下的子目录进行扫描即可解决.
- 发送邮件时出现以下错误:
1 | ERROR elastalert-server: |
原因: 由于使用了jinja2的语法, 在hmtl模板文件中会使用大括号来占位, 但是html的style有时也会使用大括号, 不知道为何jinja2错误地把style中的大括号当成是占位参数,从而出现以下错误, 类似下面这种
1 | <style> |
我直接把以下内容删掉后就没问题了,这个有点坑,要注意.
1 | { |
调试
如果在日志中出现query hits为0的多半原因是因为转换后的es 查询语句查询出来的结果就是为0
1 | ProcessController: INFO:elastalert:Queried rule index realty find invalid keyword from 2020-05-27 06:55 UTC to 2020-05-27 07:00 UTC: 0 / 0 hits |
可打开es_debug_trace
将es查询记录到指定的文件中, 如下:
1 | curl -H 'Content-Type: application/json' -XGET 'http://localhost:9200/demo.demo-*/_search?pretty&_source_include=%2A%2C%40timestamp&ignore_unavailable=true&scroll=30s&size=10' -d '{ |
在这里要注意的是es的语法中, 使用wildcard
时只能使用小写的字符串, 这是一个坑, 原因可参考zsk-blog
使用关键字参数
除了使用位置参数外,也支持在模板中使用关键字参数, 如下:
1 | type: any |
elastalert-server支持es_debug_trace
默认的elastalert-server对elastalert参够使用的参数不是很多, 目前只支持--verbose
跟--debug
这两个调试参数, 但是elastalert还有一个参数es_debug_trace
在elastalert-server的配置文件中是不支持的,这对于需要debug es的查询语句时很不方便,需要修改源码支持
elastalert-server/src/controllers/process/index.js
1 | if (config.get('es_debug_trace') !== undefined && config.get('es_debug_trace') !== '') { |
elastalert-server/config/config.json
添加` “es_debug_trace”: “/tmp/“即可