ElastAlert2集成ELK钉钉告警

背景:
现在公司用的是ELK日志架构做日志收集和展示分析,所以相对一些日志进行关键字进行告警,比如MQTT、Nginx40X和50X状态请求、后端服务ERROR严重错误日志,通过监控ES日志数据,然后使用Python调用钉钉接口来实现日志告警

5.0版本之后Elastic将一些重要的插件整合成了X-Pack(需要收费)
所以使用开源的ElastAlert,但已经很久没更新了,采用延续的ElastAlert2
1、ElastAlert是Yelp 公司开源的一套用 Python写的报警框架。属于后来 Elastic.co 公司出品的 Watcher 同类产品。ElastAlert2是原始Yelp/elasteralert项目的延续~
官网地址:https://elastalert2.readthedocs.io/
github地址:https://github.com/jertel/elastalert2

2、它支持多种监控模式和告警方式
电子邮件:通过电子邮件发送报警
Slack:将报警发送到Slack通道
Microsoft Teams:将报警发送到Microsoft Teams频道
JIRA:在JIRA上创建问题
寻呼机职责:通过寻呼机
Amazon SNS:将报警发送到 Amazon Simple Notification Service(SNS)主题
Webhook:通过自定义HTTP POST请求发送报警
Telegram:将报警发送到Telegram群组或用户
Google Chat:将报警发送到Google Chat房间
Twilio:通过电话或短信发送报警
Alerta:将报警发送到Alerta API
Datadog:将报警发送到Datadog事件流
Gitter:将报警发送到Gitter聊天室
VictorOps:通过VictorOps触发报警

3、但是并不支持钉钉告警,在github上面有第三方的钉钉Python项目:https://github.com/xuyaoqiang/elastalert-dingtalk-plugin

1、先准备钉钉机器人
在钉钉群创建自定义机器人,最终是这个格式
https://oapi.dingtalk.com/robot/send?access_token=xxx

2、从GitHub上克隆elastalert2项目
git clone https://github.com/jertel/elastalert2.git
cd elastalert2

3、克隆钉钉告警插件项目
git clone https://github.com/xuyaoqiang/elastalert-dingtalk-plugin.git

4、创建一个config.yaml文件在Elastalert2项目的根目录
es_host: 10.10.10.179
es_port: 9200
rules_folder: rules # ElastAlert2的规则文件夹路径
run_every: # ElastAlert2检查新警报的频率
minutes: 1
buffer_time: # 缓冲时间,用于拉取历史数据
minutes: 15
writeback_index: elastalert_status # 存储警报状态的索引名称
alert_time_limit: # 警报的过期时间
days: 2

5、将钉钉告警插件复制到Elastalert2项目的elastalert目录
cp elastalert-dingtalk-plugin/elastalert_modules/dingtalk_alert.py elastalert2/elastalert/

6、在Elastalert2项目根目录下创建rules目录
mkdir rules

7、创建一个名为example_rule.yaml的规则文件,并添加以下内容。请务必替换为您的钉钉webhook地址
index: "network-*"
is_enabled: true
num_events: 1 # 出现几次就告警
timeframe:
minutes: 1 # 1分钟 出现了 num_events次 匹配记录,就告警
realert:
minutes: 1 # 1分钟内忽略重复告警
timestamp_field: "@timestamp"
timestamp_type: "iso"
use_strftime_index: false
alert_text_type: alert_text_only
alert_text: |
> 正式环境 告警信息
> 时间: {0}
> 主机名: {1}
> 触发次数: {2}
> 匹配次数: {3}
> 日志信息: {4}
alert_text_args: # 告警模板中用到的参数,和上面替代符位置一致
- "@timestamp"
- host.name
- num_hits
- num_matches
- message
filter:
- query:
query_string:
query: "message: reject"
alert:
- "elastalert.dingtalk_alert.DingTalkAlerter"
dingtalk_webhook: "https://oapi.dingtalk.com/robot/send?access_token=xxx"
dingtalk_msgtype: "text"

上面的text_args 可以按照如下来编写
alert_text: |
?「prd-service告警信息」
────────────────
时间: 「{0}」
级别: 「高」
服务名称: 「{1}」
索引名称: 「{2}」
采集路径: 「{3}」
触发次数: 「{4}」
日志信息: 「{5}」
详情请登录「kibana」查看: http://10.10.10.171:5000
有疑惑请[联系运维同学]
alert_text_args:
- "@timestamp"
- "fields.source"
- "_index"
- "log.file.path"
- "num_hits"
- "message"

8、修改Dockerfile
FROM python:3-slim-buster as builder
LABEL description="ElastAlert 2 Official Image"
LABEL maintainer="Jason Ertel"
COPY . /tmp/elastalert
RUN mkdir -p /opt/elastalert && \
cd /tmp/elastalert && \
pip install setuptools wheel && \
python setup.py sdist bdist_wheel
FROM python:3-slim-buster
ARG GID=1000
ARG UID=1000
ARG USERNAME=elastalert
COPY --from=builder /tmp/elastalert/dist/*.tar.gz /tmp/
COPY elastalert/dingtalk_alert.py /opt/elastalert/elastalert/
RUN pip install requests -i https://mirrors.aliyun.com/pypi/simple/
COPY requirements.txt /tmp/
RUN pip install --no-cache-dir -r /tmp/requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
RUN apt update && apt -y upgrade && \
apt -y install jq curl gcc libffi-dev && \
rm -rf /var/lib/apt/lists/* && \
pip install /tmp/*.tar.gz && \
rm -rf /tmp/* && \
apt -y remove gcc libffi-dev && \
apt -y autoremove && \
mkdir -p /opt/elastalert && \
echo "#!/bin/sh" >> /opt/elastalert/run.sh && \
echo "set -e" >> /opt/elastalert/run.sh && \
echo "elastalert-create-index --config /opt/elastalert/config.yaml" \
>> /opt/elastalert/run.sh && \
echo "elastalert --config /opt/elastalert/config.yaml \"\$@\"" \
>> /opt/elastalert/run.sh && \
chmod +x /opt/elastalert/run.sh && \
groupadd -g ${GID} ${USERNAME} && \
useradd -u ${UID} -g ${GID} -M -b /opt -s /sbin/nologin \
-c "ElastAlert 2 User" ${USERNAME}
USER ${USERNAME}
ENV TZ "UTC"
WORKDIR /opt/elastalert
ENTRYPOINT ["/opt/elastalert/run.sh"]

9、更换为阿里源(可选,如果没有科学上网)
FROM python:3-slim-buster as builder
LABEL description="ElastAlert 2 Official Image"
LABEL maintainer="Jason Ertel"
COPY . /tmp/elastalert
RUN mkdir -p /opt/elastalert && \
cd /tmp/elastalert && \
pip install setuptools wheel && \
python setup.py sdist bdist_wheel
FROM python:3-slim-buster
ARG GID=1000
ARG UID=1000
ARG USERNAME=elastalert
COPY --from=builder /tmp/elastalert/dist/*.tar.gz /tmp/
COPY elastalert/dingtalk_alert.py /opt/elastalert/elastalert/
RUN pip install requests -i https://mirrors.aliyun.com/pypi/simple/
COPY requirements.txt /tmp/
RUN pip install --no-cache-dir -r /tmp/requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
RUN echo 'deb http://mirrors.aliyun.com/debian/ buster main non-free contrib\n\
deb-src http://mirrors.aliyun.com/debian/ buster main non-free contrib\n\
deb http://mirrors.aliyun.com/debian-security buster/updates main\n\
deb-src http://mirrors.aliyun.com/debian-security buster/updates main\n\
deb http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib\n\
deb-src http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib\n\
deb http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib\n\
deb-src http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib' > /etc/apt/sources.list && \
apt update && apt -y upgrade && \
apt -y install jq curl gcc libffi-dev && \
rm -rf /var/lib/apt/lists/* && \
pip install /tmp/*.tar.gz && \
rm -rf /tmp/* && \
apt -y remove gcc libffi-dev && \
apt -y autoremove && \
mkdir -p /opt/elastalert && \
echo "#!/bin/sh" >> /opt/elastalert/run.sh && \
echo "set -e" >> /opt/elastalert/run.sh && \
echo "elastalert-create-index --config /opt/elastalert/config.yaml" \
>> /opt/elastalert/run.sh && \
echo "elastalert --config /opt/elastalert/config.yaml \"\$@\"" \
>> /opt/elastalert/run.sh && \
chmod +x /opt/elastalert/run.sh && \
groupadd -g ${GID} ${USERNAME} && \
useradd -u ${UID} -g ${GID} -M -b /opt -s /sbin/nologin \
-c "ElastAlert 2 User" ${USERNAME}
USER ${USERNAME}
ENV TZ "UTC"
WORKDIR /opt/elastalert
ENTRYPOINT ["/opt/elastalert/run.sh"]

10、使用Docker构建Elastalert2镜像,对docker版本有要求,低版本的不行
docker build -t elastalert2 .

11、使用Docker运行Elastalert2容器
docker run -d --name elastalert2 --restart=always -v /root/elastalert2/config.yaml:/opt/elastalert/config.yaml -v /root/elastalert2/rules:/opt/elastalert/rules elastalert2

## 号外:修改rules格式
a)、service后端rules
name: "prd-service-360pai"
type: "frequency"
index: "prd-service-*"
is_enabled: true
num_events: 1
timeframe:
minutes: 1
realert:
minutes: 1
timestamp_field: "@timestamp"
timestamp_type: "iso"
use_strftime_index: false
alert_text_type: alert_text_only
alert_text: |
?「prd-service告警信息」
────────────────
时间: 「{0}」
级别: 「高」
服务名称: 「{1}」
索引名称: 「{2}」
采集路径: 「{3}」
触发次数: 「{4}」
日志信息: 「{5}」
详情请登录「kibana」查看: http://10.10.10.171:5000
有疑惑请[联系运维同学]
alert_text_args:
- "@timestamp"
- "fields.source"
- "_index"
- "log.file.path"
- "num_hits"
- "message"
filter:
- query:
query_string:
query: "message: ERROR"
alert:
- "elastalert.dingtalk_alert.DingTalkAlerter"
dingtalk_webhook: "https://oapi.dingtalk.com/robot/send?access_token=***"
dingtalk_msgtype: "text"

b)、web前端rules
name: "prd-web-360pai" # 规则的名称,用于识别和记录
type: "frequency" # 规则类型,这里是 "frequency",表示在给定的时间范围内匹配到的事件数量达到某个阈值时触发告警
index: "prd-web-*" # Elasticsearch 索引的名称模式,表示从哪个索引获取数据
is_enabled: true # 表示规则是否启用
num_events: 1 # 在指定的时间范围内需要匹配的事件数量,以触发告警
timeframe: # 用于计算事件频率的时间范围
minutes: 1
realert: # # 在触发告警后,多长时间内不再触发新的告警
minutes: 1
timestamp_field: "@timestamp" # 在触发告警后,多长时间内不再触发新的告警
timestamp_type: "iso" # 事件时间戳字段的格式类型
use_strftime_index: false # 是否使用strftime格式动态构建索引名称
alert_text_type: alert_text_only # 告警文本的格式类型
alert_text: | # 告警文本模板,其中的占位符将被实际值替换
?「prd-sweb告警信息」
────────────────
时间: 「{0}」
级别: 「高」
服务名称: 「{1}」
索引名称: 「{2}」
采集路径: 「{3}」
触发次数: 「{4}」
请求IP: 「{5}」
请求状态: 「{6}」
请求URL: 「{7}」
日志信息: 「{8}」
详情请登录「kibana」查看: http://10.10.10.171:5000
有疑惑请[联系运维同学]
alert_text_args: # 用于替换告警文本模板中占位符的字段列表 (去kibana找详细信息)
- "@timestamp"
- "fields.source"
- "_index"
- "log.file.path"
- "num_hits"
- "nginx.real_ip"
- "nginx.status"
- "nginx.url"
- "message"
filter: # 查询和筛选匹配的事件
- query:
query_string:
query: "nginx.status: [400 TO 499] OR nginx.status: [500 TO 599]"
alert: # 规定告警类型和处理器,这里使用了一个钉钉机器人
- "elastalert.dingtalk_alert.DingTalkAlerter"
dingtalk_webhook: "https://oapi.dingtalk.com/robot/send?access_token=***" # 钉钉机器人的 webhook URL
dingtalk_msgtype: "text" # 钉钉机器人发送的消息类型

12、测试:
进入docker容器运行下面命令,可以查看命中数
elastalert-test-rule ./examples/rules/exemple_discord_any.yaml --config=./examples/config.yaml

钉钉告警测试,看是否可以发送到钉钉
curl -H "Content-Type: application/json" \
-d '{"msgtype":"text","text":{"content":"EFK alert test"}}' \
https://oapi.dingtalk.com/robot/send?access_token=xxx

13、参考:https://kentxxq.com/posts/%E7%AC%94%E8%AE%B0/elastalert2%E9%92%89%E9%92%89%E5%91%8A%E8%AD%A6/
https://43.143.33.33/2023/03/21/elastalert2-alert/

https://www.cnblogs.com/JIKes/p/18169991


案例,用的时候用大模型格式化

name: "network-hq-sw"
type: "frequency"
index: "heyteahq-sw*"
is_enabled: true
num_events: 1 # 出现几次就告警
timeframe:
minutes: 1 # 1分钟出现了 num_events 次匹配记录,就告警
realert:
minutes: 1 # 1分钟内忽略重复告警
timestamp_field: "@timestamp"
timestamp_type: "iso"
use_strftime_index: false
alert_text_type: alert_text_only
alert_text: |
> 时间: {0}
> 主机名: {1}
> 触发次数: {2}
> 匹配次数: {3}
> 日志信息: {4}
alert_text_args: # 告警模板中用到的参数
- "@timestamp"
- "log.file.path"
- num_hits
- num_matches
- message
filter:
- query:
query_string:
query: "deleted OR discarding OR added OR error OR low OR 冲突 OR limit OR 异常"
- bool:
must_not:
- query_string:
query: "Command"
- query_string:
query: "\"threshold is 8.16dBM\""
- query_string:
query: "\"Optical module in interface GigabitEthernet1/0/49 exception\""
alert:
- "elastalert.dingtalk_alert.DingTalkAlerter"
dingtalk_webhook: "https://oapi.dingtalk.com/robot/send?access_token=7409853303896d650e3078467bb75a55ad9b6c4a395977e25a6a521689030e69"
dingtalk_msgtype: "text"

版权声明:本文内容由互联网用户撰写,该文观点仅代表作者本人。本站爱分享仅提供分享服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请立马联系本站,本站将立刻删除。
THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭