CentOS下ELK基于ElastAlert实现日志的微信报警_writeback_index

167 阅读2分钟

一、ElastAlert介绍

在日志管理上我们使用Elasticsearch,Logstash和Kibana技术栈来管理不断增长的数据和日志,但是对于错误日志的监控ELK架构并没有提供,所以我们需要使用到第三方工具ElastAlert,来帮助我们及时发现业务中存在的问题。

ElastAlert通过定期查询Elasticsearch,并将数据传递到规则类型,该规则类型确定何时找到匹配项。发生匹配时,将为该警报提供一个或多个警报,这些警报将根据匹配采取行动。

这是由一组规则配置的,每个规则定义一个查询,一个规则类型和一组警报。
在这里插入图片描述
ElastAlert支持以下方式报警

Command (可调用短信接口)
Email
JIRA
OpsGenie
SNS
HipChat
Slack
Telegram
Debug
Stomp

除了这种基本用法外,还有许多其他功能使警报更加有用:

警报链接到Kibana仪表板
任意字段的合计计数
将警报合并为定期报告
通过使用唯一键字段来分隔警报
拦截并增强比赛数据

二、部署ElastAlert

1. 部署所需环境

ELK 环境部署

EFK6.3+kafka+logstash日志分析平台集群

安装依赖包

$ yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel

部署python3.6

$ mkdir -p /usr/local/python3

$ cd /usr/local/python3

$ wget https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz

$ tar xf Python-3.6.9.tgz

$ cd Python-3.6.9

$ ./configure --prefix=/usr/local/python3

$ make && make install

配置环境变量

# 将python2.7 软链删除,换成python3.6

$ rm /usr/bin/python

$ ln -s /usr/local/python3/bin/python3.6 /usr/bin/python

$ rm /usr/bin/pip

$ ln -s /usr/local/python3/bin/pip3 /usr/bin/pip

验证版本

$ python
Python 3.6.9 (default, Jun  2 2020, 12:12:43) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-18)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
$ pip -V
pip 18.1 from /usr/local/python3/lib/python3.6/site-packages/pip (python 3.6)

2. 部署ElastAlert

$ cd /app

$ git clone https://github.com/Yelp/elastalert.git

安装模块:

$ pip install "setuptools>=11.3"
$ python setup.py install

根据Elasticsearch的版本,您可能需要手动安装正确版本的elasticsearch-py。

Elasticsearch 5.0+:

$ pip install "elasticsearch>=5.0.0"

Elasticsearch 2.X:

$ pip install "elasticsearch<3.0.0"

3. 配置ElastAlert

配置config.yaml 文件

$ cp config.yaml.example  config.yaml
$ cat config.yaml
rules_folder: example_rules
run_every:
  seconds: 10
buffer_time:
  minutes: 15
es_host: 10.1.144.208
es_port: 9201
#es\_username: elastic
#es\_password: 123456
writeback_index: elastalert_status
alert_time_limit:
  days: 2

rules_folder:ElastAlert从中加载规则配置文件的位置。它将尝试加载文件夹中的每个.yaml文件。没有任何有效规则,ElastAlert将无法启动。
run_every: ElastAlert多久查询一次Elasticsearch的时间。
buffer_time:查询窗口的大小,从运行每个查询的时间开始向后延伸。对于其中use_count_query或use_terms_query设置为true的规则,将忽略此值。
es_host:是Elasticsearch群集的地址,ElastAlert将在其中存储有关其状态,查询运行,警报和错误的数据。
es_port:es对应的端口。
es_username: 可选的; 用于连接的basic-auth用户名es_host。
es_password: 可选的; 用于连接的basic-auth密码es_host。
es_send_get_body_as: 可选的; 方法查询Elasticsearch - GET,POST或source。默认是GET
writeback_index:ElastAlert将在其中存储数据的索引的名称。我们稍后将创建此索引。
alert_time_limit: 失败警报的重试窗口。

创建elastalert-create-index索引

$ elastalert-create-index
New index name (Default elastalert_status)
Name of existing index to copy (Default None)
New index elastalert_status created
Done!

三、使用微信报警

由于ElastAlert没有内置企业微信的报警方式,我们还需要使用一个开源插件elastalert-wechat-plugin来实现微信的报警,Github项目地址

1. 下载项目文件

$ cd elastalert

$ wget -P ~/elastalert/elastalert_modules/ wget https://raw.githubusercontent.com/anjia0532/elastalert-wechat-plugin/master/elastalert_modules/wechat_qiye_alert.py

$ touch ~/elastalert/elastalert_modules/__init__.py

2. 修改插件源码

由于这个插件是基于python2.x版本开发的,而ElastAlert的最新版本使用的是python3.6版本开发,所以需要改一些代码,以便正常运行,另外还添添加了转中文字符功能。
wechat_qiye_alert.py修改后如下:

#! /usr/bin/env python
# -\*- coding: utf-8 -\*-

import json
import datetime
from elastalert.alerts import Alerter, BasicMatchString
from requests.exceptions import RequestException
from elastalert.util import elastalert_logger,EAException #[感谢minminmsn分享]( )
import requests
from elastalert_modules.MyEncoder import MyEncoder

'''
#################################################################
# 微信企业号推送消息                                              #
#                                                               #
# 作者: AnJia <anjia0532@gmail.com>                              #
# 作者博客: https://anjia.ml/                                    #
# Github: https://github.com/anjia0532/elastalert-wechat-plugin #
#                                                               #
#################################################################
'''
class WeChatAlerter(Alerter):

    #企业号id,secret,应用id必填

    required_options = frozenset(['corp\_id','secret','agent\_id'])

    def \_\_init\_\_(self, \*args):
        super(WeChatAlerter, self).\_\_init\_\_(\*args)
        self.corp_id = self.rule.get('corp\_id', '')     #企业号id
        self.secret = self.rule.get('secret', '')       #secret
        self.agent_id = self.rule.get('agent\_id', '')   #应用id

        self.party_id = self.rule.get('party\_id')       #部门id
        self.user_id = self.rule.get('user\_id', '')     #用户id,多人用 | 分割,全部用 @all
        self.tag_id = self.rule.get('tag\_id', '')       #标签id
        self.access_token = ''                          #微信身份令牌
        self.expires_in=datetime.datetime.now() - datetime.timedelta(seconds=60)

    def create\_default\_title(self, matches):
        subject = 'ElastAlert: %s' % (self.rule['name'])
        return subject

    def alert(self, matches):

        if not self.party_id and not self.user_id and not self.tag_id:
            elastalert_logger.warn("All touser & toparty & totag invalid")

        # 参考elastalert的写法
        # https://github.com/Yelp/elastalert/blob/master/elastalert/alerts.py#L236-L243
        body = self.create\_alert\_body(matches)

        #matches 是json格式
        #self.create\_alert\_body(matches)是String格式,详见 [create\_alert\_body 函数]( )

        # 微信企业号获取Token文档
        # http://qydev.weixin.qq.com/wiki/index.php?title=AccessToken
        self.get\_token()

        self.senddata(body)

        elastalert_logger.info("send message to %s" % (self.corp_id))

    def get\_token(self):

        #获取token是有次数限制的,本想本地缓存过期时间和token,但是elastalert每次调用都是一次性的,不能全局缓存
        if self.expires_in >= datetime.datetime.now() and self.access_token:
            return self.access_token