ElastAlert 错误日志告警

文章目录

  • 前言
  • [一、ElastAlert 概览](#一、ElastAlert 概览)
    • [1.1 简介](#1.1 简介)
    • [1.2 ElastAlert 特性](#1.2 ElastAlert 特性)
  • [二、ElastAlert 下载部署](#二、ElastAlert 下载部署)
    • [2.1 安装 Python3 环境](#2.1 安装 Python3 环境)
    • [2.2 下载 ElastAlert](#2.2 下载 ElastAlert)
    • [2.3 部署 ElastAlert](#2.3 部署 ElastAlert)
  • 三、接入平台
    • [3.1 对外接口层](#3.1 对外接口层)
    • [3.2 服务层](#3.2 服务层)

前言

ElastAlert 是 Yelp 公司基于 python 开发的 ELK 日志告警插件,Elastalert 通过查询 Elasticsearch 中的记录与定于的告警规则进行对比,判断是否满足告警条件。发生匹配时将为该告警触发一个或多个告警动作。告警规则由 ElastAlert 的 rules 定义,每个规则定义一个查询。

一、ElastAlert 概览

1.1 简介

ElastAlert 程序的设计是可靠的、高度可定制的、安装方面也是简单的并且可配置的。

它通过将 Elasticsearch 与两个组件,规则类型(rule types)以及警报(alerts)相结合进行实现。Elasticsearch 会定期的被程序查询,得出的数据经由规则类型(rule type)确定何时找到了匹配项。当找到匹配项后,会根据匹配的数据结果给出一个或多个警报。

配置方面是由一组规则(rules)进行管控,每个规则(rules)里面定义了一个查询,一个规则类型以及一组警报。

目前支持以下的报警类型:

  • Command
  • Email
  • JIRA
  • OpsGenie
  • SNS
  • HipChat
  • Slack
  • Telegram
  • Debug
  • Stomp

1.2 ElastAlert 特性

  1. 架构简单,定制灵活
  2. 支持多种匹配规则(频率、阈值、数据变化、黑白名单、变化率等)
  3. 支持多种警报类型(邮件、HTTP POST、自定义脚本等)
  4. 匹配项汇总报警,重复警报抑制,报警失败重试和过期
  5. 可用性强,状态信息保存到Elasticsearch的索引中

二、ElastAlert 下载部署

2.1 安装 Python3 环境

切换到 /data 目录下

bash 复制代码
cd /data

安装 openssl

bash 复制代码
yum -y install wget openssl openssl-devel gcc gcc-c++

下载 Python 安装包

bash 复制代码
wget https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz

解压缩

bash 复制代码
tar -zxvf Python-3.6.9.tgz

cd Python-3.6.9 目录

bash 复制代码
cd Python-3.6.9

安装配置

bash 复制代码
./configure

编译

bash 复制代码
make && make install

建立软连接去除系统自带的 Python2

bash 复制代码
mv /usr/bin/python /usr/bin/python_old
ln -s /usr/local/python/bin/python3 /usr/bin/python
ln -s /usr/local/python/bin/pip3 /usr/bin/pip
pip install --upgrade pip

查看版本

bash 复制代码
[root@boe-dc-38 bin]# python -V
Python 3.6.9
[root@boe-dc-38 bin]# pip -V
pip 21.3.1 from /usr/local/python/lib/python3.6/site-packages/pip (python 3.6)

2.2 下载 ElastAlert

1.克隆 ElastAlert 项目

bash 复制代码
git clone https://github.com/Yelp/elastalert.git

2.安装

bash 复制代码
cd elastalert
pip install elasticsearch>=7.0.0
pip install -r requirements.txt
python setup.py install

3.安装成功后可以看到四个命令

bash 复制代码
[root@boe-dc-38 bin]# ll /usr/local/python/bin/elastalert*
-rwxr-xr-x 1 root root 396 Nov 17 13:40 /usr/local/python/bin/elastalert
-rwxr-xr-x 1 root root 422 Nov 17 13:40 /usr/local/python/bin/elastalert-create-index
-rwxr-xr-x 1 root root 430 Nov 17 13:40 /usr/local/python/bin/elastalert-rule-from-kibana
-rwxr-xr-x 1 root root 416 Nov 17 13:40 /usr/local/python/bin/elastalert-test-rule

4.软连接到 /usr/bin 下,方便使用

bash 复制代码
ln -s /usr/local/python/bin/elastalert* /usr/bin
  • elastalert 报警执行的命令,会根据报警规则执行相应操作。
  • elastalert-create-index 会创建一个索引,ElastAlert 会把执行记录存放到这个索引中,默认情况下,索引名叫 elastalert_status。其中有 4 个 _type,都有自己的 @timestamp 字段,所以同样也可以用 Kibana 来查看这个索引的日志记录情况。
  • elastalert-rule-from-kibana 从 Kibana3 已保存的仪表盘中读取 Filtering 设置,帮助生成config.yaml 里的配置。不过注意它只会读取 filtering,不包括 queries。
  • elastalert-test-rule 测试自定义配置中的 rule 设置。

5.创建 elastalert 索引

bash 复制代码
elastalert-create-index

2.3 部署 ElastAlert

1.主配置文件config.yaml

yaml 复制代码
#加载rule的目录,默认是example_rules
rules_folder: /data/elastalter/example_rules

#设置定时向elasticsearch发送请求,也就是告警频率
run_every:
  minutes: 1

#用来设置请求里时间字段的范围
buffer_time:
  minutes: 15

#elasticsearch的ip地址和端口
es_host: 192.168.136.123
es_port: 9200

#elastalert产生的日志在elasticsearch中的创建的索引
writeback_index: elastalert_status
writeback_alias: elastalert_alerts
:1
#失败重试的时间限制
alert_time_limit:
  days: 2

2.邮件告警配置

bash 复制代码
python -m elastalert.elastalert --verbose --config /data/elastalter/config.yaml --rule /data/elastalter/example_rules/visual-chart.yaml

三、接入平台

3.1 对外接口层

java 复制代码
@Slf4j
@RestController
@RequestMapping("/webhook")
public class WebhookController {

    @Autowired
    WebhookService webhookService;

    /**
     * 接收elastalert告警消息
     *
     * @param request
     * @return
     */
    @RequestMapping("/elastalert")
    public Result elastalert(HttpServletRequest request) throws IOException {
        //设置流的编码
        request.setCharacterEncoding("UTF-8");
        StringBuffer data = new StringBuffer();
        String line = null;
        BufferedReader reader = null;
        reader = request.getReader();
        while (null != (line = reader.readLine())) {
            data.append(line);
        }
        String result = data.toString().replace("@timestamp","timestamp");
        ElastalertAlarmMessageDTOS elastalertAlarmMessageDTOS = JSON.parseObject(result, ElastalertAlarmMessageDTOS.class);
        String jsonFlatten = JsonFlatten.jsonFlatten(elastalertAlarmMessageDTOS.getLog());
        elastalertAlarmMessageDTOS.setLog(jsonFlatten);
        log.info("请求数据===================>" + elastalertAlarmMessageDTOS);
        webhookService.handleElastalert(elastalertAlarmMessageDTOS);
        return Result.success();
    }
}

3.2 服务层

java 复制代码
/**
 * 处理Elastalert消息
 *
 * @param alarmMessages 告警消息
 */
public void handleElastalert(ElastalertAlarmMessageDTOS alarmMessages) {
    String subject = String.format(MailConstants.ELASTALERT_SUBJECT_TEMPLATE, alarmMessages.get_index());
    String content = String.format(MailConstants.ELASTALERT_CONTENT_TEMPLATE_LARD, alarmMessages.get_index(),
            alarmMessages.get_index(), alarmMessages.getTimestamp(), alarmMessages.getLog(),
            alarmMessages.getMessage(), alarmMessages.get_id());
    try {
        msgService.sendLark(subject, content);
    } catch (Exception e) {
        log.error("发送错误日志告警通知异常, 主题:{}, 内容:{}", subject, content);
    }

    String indexName = serviceService.serviceName(alarmMessages.get_index());
    // 获取服务名称
    String serviceName = getServiceName(indexName);
    // 根据服务名获取服务信息
    TService service = serviceService.findByName(serviceName);
    if (service == null) {
        log.warn("处理Elastalert告警信息失败, 原因:未找到对应服务信息, 服务名称:{}", serviceName);
    }

    TElastalertAlarmRecord alarmRecord = new TElastalertAlarmRecord();
    alarmRecord.setAlarmTime(alarmMessages.getTimestamp().toString());
    alarmRecord.setBuId(service.getBuId());
    alarmRecord.setPath(alarmMessages.getLog());
    alarmRecord.setServiceName(serviceName);
    alarmRecord.setAlarmMessage(alarmMessages.getMessage());
    alarmRecordService.save(alarmRecord);

    // 查找该BU关联的用户
    List<TUser> users = userService.findByBuId(service.getBuId());
    users.removeIf(user -> MailConstants.WARN_SKIP_USERS.contains(user.getEmpNo()));
    if (CollectionUtils.isEmpty(users)) {
        log.warn("发送Elastalert告警通知邮件失败, 原因:未找到对应的负责人, 服务名称:{}", serviceName);
    }
    String[] to = users.stream().map(TUser::getEmail).collect(Collectors.toList()).toArray(new String[0]);
    String contentMail = String.format(MailConstants.ELASTALERT_CONTENT_TEMPLATE_LARD_MAIL, alarmMessages.get_index(),
            alarmMessages.get_index(), alarmMessages.getTimestamp(), alarmMessages.getLog(),
            alarmMessages.getMessage(), alarmMessages.get_id());
    try {
        msgService.sendHTMLMail(to, null, subject, contentMail);
    } catch (Exception e) {
        log.error("发送Elastalert告警通知邮件异常, 收件人:{}, 主题:{}, 内容:{}", to, subject, content);
    }
}
相关推荐
Dusk_橙子10 小时前
在elasticsearch中,document数据的写入流程如何?
大数据·elasticsearch·搜索引擎
喝醉酒的小白12 小时前
Elasticsearch 中,分片(Shards)数量上限?副本的数量?
大数据·elasticsearch·jenkins
熟透的蜗牛14 小时前
Elasticsearch 8.17.1 JAVA工具类
elasticsearch
九圣残炎18 小时前
【ElasticSearch】 Java API Client 7.17文档
java·elasticsearch·搜索引擎
risc12345620 小时前
【Elasticsearch】HNSW
elasticsearch
我的棉裤丢了21 小时前
windows安装ES
大数据·elasticsearch·搜索引擎
乙卯年QAQ1 天前
【Elasticsearch】RestClient操作文档
java·大数据·elasticsearch·jenkins
超级阿飞1 天前
利用Kubespray安装生产环境的k8s集群-实施篇
elasticsearch·容器·kubernetes
小诺大人2 天前
Docker 安装 elk(elasticsearch、logstash、kibana)、ES安装ik分词器
elk·elasticsearch·docker
forestsea2 天前
【Elasticsearch 】 聚合分析:桶聚合
大数据·elasticsearch·搜索引擎