结合elastalert对ELK中的异常日志进行监控,并进行告警。这个告警对日志的可控性要求还是比较高的,不然容易被消息轰炸!
1. 部署Elastalert2告警
1.1前期准备
ruby
root@dockerprojectserv-13:~# mkdir -p Elastalert2/rules
root@dockerprojectserv-13:~# cd Elastalert2
1.2准备配置文件
yaml
# Elastalert2 配置文件
root@dockerprojectserv-13:~/Elastalert2# vi config.yaml
---
#指定告警文件存放目录
rules_folder: /opt/elastalert/rules
#ElastAlert查询Elasticsearch的频率,这个单位可以是几周到几秒不等
run_every:
minutes: 1
#ElastAlert将缓冲最近的一段时间的结果,以防某些日志源不是实时的
buffer_time:
minutes: 1
#Elasticsearch主机
es_host: 192.168.1.99
#Elasticsearch端口
es_port: 9201
# es账号密码设置
es_username: 'eastic'
es_password: '123456'
#es_host上的索引,用于元数据存储。这可以是一个未映射的索引,但建议你运行。设置一个映射
writeback_index: elastalert_status
# 如果一个警报因某种原因而失败,ElastAlert将重试,直到这个时间段过后
alert_time_limit:
days: 2
1.3 准备规则文件
1.3.1 钉钉报警java模版1(text)
vbnet
# 规则名
name: "java_error_rule"
#规则类型为频率,表示要检测的事件是在一定时间范围内出现的次数,有多种类型,不同的类型配置项有不同
# https://elastalert2.readthedocs.io/en/latest/ruletypes.html#rule-types 类型参考
type: "frequency"
# 需要监控的索引 ,多个索引用 逗号分割
index: "filebeat-javalog-mutli-*"
is_enabled: true
# 出现几次就告警
num_events: 1
# 1分钟 出现了 num_events次 匹配记录,就告警
timeframe:
minutes: 1
#同一规则的两次警报之间的最短时间。在此时间内发生的任何警报都将被丢弃。默认值为一分钟。
realert:
minutes: 1
# 指数级扩大 realert 时间,中间如果有报警,
# 则按照 5 -> 10 -> 20 -> 40 -> 60 不断增大报警时间到制定的最大时间,
# 如果之后报警减少,则会慢慢恢复原始 realert 时间
exponential_realert:
hours: 8
timestamp_field: "@timestamp"
timestamp_type: "iso"
# 如果使用inclde这个选项要为true
#use_strftime_index: true
# 这里是es索引中的字段,下边报警模板会使用
#include: ["@timestamp","_index", "module", "level", "msg"]
filter:
- query:
query_string:
#错误级别是ERROR并且msg字段包含java开头Exception结尾的内容就匹配成功,elastalert就会推送报警
#query: "level.keyword : ERROR AND msg : java*Exception"
#匹配的是索引中的关键字可以使用一些连接符来进行过滤
#query: "message:("ERROR" OR "WARNING" OR "exception")"
query: "message:("ERROR" OR "WARNING" OR "exception")"
# 仅使用自定义模板告警
alert_text_type: alert_text_only
#标题
alert_subject: "生产环境日志告警通知"
# 下面是告警模板
alert_text: |
日志告警
索引名称: {0}
时间: {1}
文件: {2}
触发次数: {3}
匹配次数: {4}
日志信息: {5}
告警节点: {6}
alert_text_args: # 告警模板中用到的参数
- "_index"
- "@timestamp"
- log.file.path
- num_hits
- num_matches
- message
- host.name
alert:
- "dingtalk" # 告警类型,支持多种告警可以看官网
dingtalk_access_token: "xxxxx"
dingtalk_msgtype: "text"
dingtalk_single_title: "Kibana"
dingtalk_single_url: "http://192.168.1.99:5600"

1.3.2 钉钉报警java模版2(html需要集成第三方告警模块)
vbnet
# 规则名
name: "java_error_rule"
#规则类型为频率,表示要检测的事件是在一定时间范围内出现的次数,有多种类型,不同的类型配置项有不同
# https://elastalert2.readthedocs.io/en/latest/ruletypes.html#rule-types 类型参考
type: "frequency"
# 需要监控的索引 ,多个索引用 逗号分割
index: "java-log-*"
is_enabled: true
# 出现几次就告警
num_events: 1
# 1分钟 出现了 num_events次 匹配记录,就告警
timeframe:
minutes: 5
#同一规则的两次警报之间的最短时间。在此时间内发生的任何警报都将被丢弃。默认值为一分钟。
realert:
minutes: 30
# 指数级扩大 realert 时间,中间如果有报警,
# 则按照 5 -> 10 -> 20 -> 40 -> 60 不断增大报警时间到制定的最大时间,
# 如果之后报警减少,则会慢慢恢复原始 realert 时间
exponential_realert:
hours: 8
timestamp_field: "@timestamp"
timestamp_type: "iso"
# 如果使用inclde这个选项要为true
#use_strftime_index: true
# 这里是es索引中的字段,下边报警模板会使用
#include: ["@timestamp","_index", "module", "level", "msg"]
filter:
- query:
query_string:
#错误级别是ERROR并且msg字段包含java开头Exception结尾的内容就匹配成功,elastalert就会推送报警
#query: "level.keyword : ERROR AND msg : java*Exception"
#匹配的是索引中的关键字可以使用一些连接符来进行过滤
#query: "message:("ERROR" OR "WARNING" OR "exception")"
query: "message:("ERROR" OR "WARNING" OR "exception")"
alert_text_type: alert_text_only
#标题
alert_subject: "生产环境日志告警通知"
# 下面是告警模板
alert_text: |
日志告警
索引名称: {0}
时间: {1}
文件: {2}
触发次数: {3}
匹配次数: {4}
日志信息: {5}
告警节点: {6}
alert_text_args: # 告警模板中用到的参数
- "_index"
- "@timestamp"
- log.file.path
- num_hits
- num_matches
- message
- host.name
alert:
- "dingtalk" # 告警类型,支持多种告警可以看官网
dingtalk_access_token: "xxxxxx"
dingtalk_msgtype: "text"
1.4 准备Docker-compose
css
root@ubuntu2204-98:~/Elastalert2# cat docker-compose.yml
version: '3'
services:
elastalert:
#image: harbor.xxx.top/private-hub/elastalert2:latest
image: jertel/elastalert2:latest
restart: always
volumes:
- /root/Elastalert2/config.yaml:/opt/elastalert/config.yaml
- /root/Elastalert2/rules:/opt/elastalert/rules
command: --verbose
告警过滤及参数示例讲解
python
# 时间单位有hours,minutes,seconds
# 告警关键字匹配
# 单词匹配可以写为 query: ERROR 或者 query: "message: ERROR"
# 多告警关键字匹配
# query: "message:{"ERROR" OR "WARING" OR "\exception"}" 也可以使用AND连接 query: "message:{"ERROR" AND "WARING" AND "\exception"}"
#---------- 过滤规则示例1 ----------
filter:
- query:
query_string:
query: "error OR ERROR OR 404 OR 500" # 检测的查询语句,包含其中一个
- bool:
must_not:
query_string:
query: ""ERROR 1111"" # 过滤信息,包含ERROR 1111进行过滤 不告警
#---------- 过滤规则示例2 ----------
filter:
- query:
query_string:
query: "error OR ERROR OR 404 OR 500" # 匹配包含 error、ERROR、404 或 500 的日志
- bool:
must_not:
- query_string:
query: ""ERROR 1111"" # 排除包含 ERROR 1111 的日志
- query_string:
query: ""ERROR 2222"" # 排除包含 ERROR 2222 的日志
- query_string: # 额外添加的条件,排除包含特定字符串的日志
query: ""discard long time none received connection""
#---------- Nginx常规日志告警过滤规则 ----------
filter:
- query:
query_string:
query: "message: 404" # 或 query: "error OR ERROR OR 404 OR 500"
#---------- NginxJson日志告警过滤规则 以K/V形式----------
# 查找状态码502的日志
filter:
- term:
status: "404"
# 通过bool实现对多个值查找
filter:
- bool
should:
- term:
status: "404"
- term:
status: "500"
- term:
status: "502"