分布式监控告警系统有非常多的实现方案,围绕ELK的实现方案则是当下的主流,这里举例几种常见的实现方案:
方案 | 环境要求 | 报警方式 | 评论 |
---|---|---|---|
ElastAlert Docker GitHub Docker Hub |
python2.6+ ElasticSearch 7.0.0以下 |
邮箱 微信 钉钉 | 开源;专注于告警;Kibana插件可以较为方便的进行配置,内置Filter 支持多种匹配规则(ES Lucene语法、正则表达式等),但部署较为复杂。 |
X-Pack | 所有版本 |
邮箱 钉钉 | 商用;提供实施日志监控报警,报表呈现,是ELK报警器的最佳选择,但商用。 |
Sentinl | ElasticSearch 6.6.X以下 |
邮箱 微信 钉钉 | 开源;属于Kibana插件,即插即用;基于ES实现了丰富的图表数据呈现,可视化程度高,但不支持高版本ELK。可用来实现大屏监控。 |
ELK+GPE备用连接 | 无要求 | 自实现 | “GPE只是一种分布式监控预警方案”,作者这样介绍到,并给出了他个人的实现Grafana+Prometheus+Exporter。面向分布式,是更适合用于大型分布式系统的监控告警系统,是“云”大屏监控的实现方案,而在日志监控方面有所欠缺,功能比较驳杂。 |
Zabbix | 无特殊要求 | 邮箱 钉钉 | 开源;基于Agent插桩技术实现,原生直接操作日志文件实现监控告警,提供ES实现方式,亦优亦劣,是脱离ELK不错的日志监控报警方案。 |
以上内容,仅个人见解。如果你的系统使用ELK做日志收集,ElastAlert将会是不错的日志报警器的选择。
ElastAlert是Yelp公司基于Python写的开源报警框架,并且提供与Kibana集成使用的插件,支持多种报警方式(邮箱、微信、钉钉),这里只提供邮箱的实现方式。
分为两部分进行部署,ElastAlert Kibana管理插件部署、ElastAlert部署。
ELK7.3环境安装最新版本ElastAlertv0.2.4 需要 3.6 > Python > 3.7,考虑到源码部署方式会有很多坑,这里选择官方提供ElasticSearch 7.0.0对应的ElastAlert Docker 镜像进行部署。
更多版本可以到这里查看。
创建几个文件夹保存ElastAlert相关配置信息。
mkdir -p /mnt/elastalert/{config,rules,rule_templates}
之后我们定义路径,${ELASTALERT} = / m n t / e l a s t a l e r t = /mnt/elastalert =/mnt/elastalert。
文件(夹) | 用途 |
---|---|
config | 存放所有相关配置文件 |
rules | 存放路由规则 |
rule_templates | (可选)存放规则模板 |
config.yaml | ElastAlert核心配置,配置规则的执行时机、重试、缓存等规则。 |
config.json | 配置Docker ElastAlert的启动参数 |
rule.yaml | 单条规则的详细配置 |
smtp_auth.yaml | 邮箱smtp认证配置 |
创建 ${ELASTALERT}/config/config.yaml用来存储核心配置:
# 路由规则存放的文件路径
rules_folder: rules
# 每间隔run_every时间运行一次
run_every:
# seconds: 30
minutes: 1
# ElastAlert使用ES进行过滤查询的结果将被缓存的时间
buffer_time:
minutes: 15
# 服务连接地址
es_host: 192.168.0.123
# Elasticsearch 端口
es_port: 9200
# Elasticsearch 认证配置
es_username: elastic
es_password: elastic
# ElastAlert默认在ES上创建的索引,由于存放ElastAlert运行日志
writeback_index: elastalert_status
writeback_alias: elastalert_alerts
# 2天内报警失败,进行重试
alert_time_limit:
days: 2
创建 ${ELASTALERT}/config/config.json启动参数配置文件:
{
"appName": "elastalert-server",
"port": 3030,
"wsport": 3333,
"elastalertPath": "/opt/elastalert",
"verbose": true,
"es_debug": false,
"debug": false,
"rulesPath": {
"relative": true,
"path": "/rules"
},
"templatesPath": {
"relative": true,
"path": "/rule_templates"
},
"es_host": "192.168.0.123",
"es_port": 9200,
"writeback_index": "elastalert_status"
}
参数 | 用途 |
---|---|
elastalertPath | 根ElastAlert文件夹的路径。它是包含“ setup.py”脚本的文件夹。 |
verbose | 将增加日志记录的详细程度,使您可以查看有关查询状态的信息。 |
es_debug | ES debug日志。 |
debug | 不能与verbose同时开启,verbose符合规则时进行报警,而debug只打印报警日志。 |
rulesPath | 规则配置文件存放路径。 |
relative | 是否使用相对于“elastalertPath”文件夹的路径。 |
writeback_index | 启动时创建的用于标识ElastAlert状态的索引名。 |
更多启动参数配置 更多启动参数参考
我们编写一条,模糊匹配的规则,规则满足的条件如下:
匹配所有以[XXX-server]2020开头的ES索引;
匹配索引的message字段中包含“ERROR”字符串,不包含“INFO”和“Read timed out”的日志;
每分钟执行一次,5分钟内与规则匹配的日志超过1条,触发邮箱报警;
对5分钟内符合规则的日志进行去重;
聚合5分钟内所有报警信息,5分钟后统一触发报警器。
创建 ${ELASTALERT}/config/xxx_server_rule.yaml用来存储规则配置:
es_host: 192.168.0.123
es_port: 9200
#use_ssl: True
es_username: elastic
es_password: elastic
name: xxx_server_rule
# 规则类型,默认支持的规则:https://github.com/Yelp/elastalert#overview
# frequency:匹配Y时间中至少有X个事件的地方。
type: frequency
# 不进行重复提醒的(ES索引)字段,和realert联合使用,30分钟内这个query_key只告警一次
query_key:
- message
# 聚合2分钟内的结果。设置一个时长,则该时长内,所有的报警(同一个配置文件内的报警)最终合并在一起发送。默认值为警报间隔一分钟。
aggregation:
minutes: 5
# 同一规则的两次警报之间的最短时间。在此时间内发生的任何符合相同规则的警报都将被丢弃。默认值为一分钟(去重)。
# 如果你希望听到不断的“叮咚”声,可以将它配置为 0。
realert:
minutes: 5
# ES索引名称,支持模糊匹配
index: "[XXX-server]202*"
# 与规则匹配的日志出现次数
num_events: 1
#threshold: 1
# 与num_events配合,表示在timeframe时间内出现num_events次与规则匹配的日志,将会触发报警。
timeframe:
minutes: 5
# 以下编写了一条Lucene格式的过滤规则
filter:
- query:
query_string:
query: "message: ERROR"
- query:
query_string:
query: "NOT message: INFO"
- query:
query_string:
query: "NOT message: Read timed out"
# 告警方式
#alert: post
# 告警连接接口,更多信息参考:https://elastalert.readthedocs.io/en/latest/ruletypes.html?highlight=http_post_url#alerta
#http_post_url: "http://localhost:8088/alertapi"
alert:
- "email"
# Email格式
email_format: html
# 如果这个去掉,那么发送alert_text的同时,也会发送默认模板内容
alert_text_type: alert_text_only
#主题模板
alert_text: "紧急!XXX日志报警通知。
立马前往Kibana查看
告警详情
@timestamp: {} @version: {} _id: {} _index: {} _type: {} host: {} message: {} 规则命中条数: {} 匹配触发告警数: {} 日志位置: {}
"
# 邮箱模板参数
alert_text_args:
- "@timestamp"
- "@version"
- _id
- _index
- _type
- host
- message
- num_hits
- num_matches
- path
# 标题
alert_subject: "紧急!XXX日志报警通知。"
# 可配置多个接收方(Team)
email:
- "[email protected]"
- "[email protected]"
# 为了安全起见,最好自建邮箱服务器
smtp_host: "smtp.126.com"
smtp_port: 465
# 邮箱认证配置文件
smtp_auth_file: /opt/elastalert/rules/smtp_auth.yaml
# 设置邮箱Reply-To标头。默认值为收件人地址。
email_reply_to: "[email protected]"
# 作为发送方的系统邮箱地址
from_addr: "[email protected]"
# https 证书
smtp_ssl: true
更多过滤规则配置参考 规则未生效?
创建 ${ELASTALERT}/rules/smtp_auth.yaml用来存储规则配置:
user: "[email protected]"
password: "xxxxxxxxxxxxxxxxxx"
docker pull bitsensor/elastalert:3.0.0-beta.1
docker run -d -p 3030:3030 -p 3333:3333 \
-v /mnt/elastalert/config/config.yaml:/opt/elastalert/config.yaml \
-v /mnt/elastalert/config/config.json:/opt/elastalert-server/config/config.json \
-v /mnt/elastalert/rules:/opt/elastalert/rules \
-v /mnt/elastalert/rule_templates:/opt/elastalert/rule_templates \
-v /etc/localtime:/etc/localtime:ro \
-e TZ=Asia/Shanghai \
--name elastalert bitsensor/elastalert:3.0.0-beta.1
容器运行,文件路径为镜像内路径,挂载后为 / o p t / e l a s t a l e r t /opt/elastalert /opt/elastalert。
docker exec -i elastalert python -m elastalert.elastalert --verbose \
--config /opt/elastalert/config.yaml \
--rule /opt/elastalert/rules/xxx_server_rule.yaml
若无异常,你收到的报警邮箱大概是这样一份聚合后的结果:
规则未生效?
ElastAlert部署过程可能并非这么顺利,大家可以去ElastAlert Docker社区寻找答案。
Kibana 7.3对应的ElastAlert plugin版本为v1.1.0,去发行页查看更多插件版本。
bin/kibana-plugin install https://github.com/bitsensor/elastalert-kibana-plugin/releases/download/1.1.0/elastalert-kibana-plugin-1.1.0-7.3.2.zip
记得切换账户身份。
su elk
bin/kibana -d
ElastAlert Kibana插件使用比较简单,这里就不做演示啦。
编写start_el_rule.sh用以后台运行特定ElastAlert规则:
#!/bin/bash
# author:LM.X
nohup docker exec -i elastalert python -m elastalert.elastalert --verbose --config /opt/elastalert/config.yaml --rule /opt/elastalert/rules/xxx_server_rule.yaml > logs/xxx_server_rule.log 2>&1 &
echo "ps -aux|grep 'docker exec -i elastalert python -m'"
ps -aux|grep "docker exec -i elastalert python -m"
编写stop.sh用以停止所有规则的运行:
#!/bin/bash
# author:LM.X
PIDS=`ps -ef |grep "python -m elastalert.elastalert --verbose --config /opt/elastalert/config.yaml" |grep -v grep | awk '{print $2}'`
kill -15 $PIDS
echo 'Kill %s success.' $PIDS
参考文献
https://elastalert.readthedocs.io/en/latest/running_elastalert.html?highlight=email#
https://github.com/bitsensor/elastalert
https://github.com/bitsensor/yelp-elastalert
https://github.com/bitsensor/elastalert-kibana-plugin