ELK运维之路(异常日志告警)
结合elastalert对ELK中的异常日志进行监控,并进行告警。这个告警对日志的可控性要求还是比较高的,不然容易被消息轰炸!
1. 部署Elastalert2告警
1.1前期准备
root@dockerprojectserv-13:~# mkdir -p Elastalert2/rules
root@dockerprojectserv-13:~# cd Elastalert2
1.2准备配置文件
# 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)
# 规则名
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: 8timestamp_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.namealert:- "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需要集成第三方告警模块)
# 规则名
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: 8timestamp_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.namealert:- "dingtalk" # 告警类型,支持多种告警可以看官网
dingtalk_access_token: "xxxxxx"
dingtalk_msgtype: "text"
1.4 准备Docker-compose
root@ubuntu2204-98:~/Elastalert2# cat docker-compose.yml
version: '3'
services:elastalert:#image: harbor.xxx.top/private-hub/elastalert2:latestimage: jertel/elastalert2:latestrestart: alwaysvolumes:- /root/Elastalert2/config.yaml:/opt/elastalert/config.yaml- /root/Elastalert2/rules:/opt/elastalert/rulescommand: --verbose
告警过滤及参数示例讲解
# 时间单位有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:
- boolshould:- term:status: "404"- term:status: "500"- term:status: "502"
